From 5eadb538b0d48d4050694a2c4c22bb19cc740199 Mon Sep 17 00:00:00 2001 From: Jimmy Monin Date: Tue, 27 Dec 2016 18:50:51 +0100 Subject: [PATCH] Download sources (except dependencies) during installation and upgrade to 1.0.35 --- README.markdown | 2 +- conf/config.php | 31 +- scripts/install | 10 +- scripts/upgrade | 10 + sources/.htaccess | 26 - sources/ChangeLog | 637 --- sources/app/.htaccess | 7 - sources/app/Action/Base.php | 297 -- sources/app/Action/CommentCreation.php | 87 - .../Action/CommentCreationMoveTaskColumn.php | 94 - .../app/Action/TaskAssignCategoryColor.php | 95 - .../app/Action/TaskAssignCategoryLabel.php | 91 - sources/app/Action/TaskAssignCategoryLink.php | 101 - .../app/Action/TaskAssignColorCategory.php | 95 - sources/app/Action/TaskAssignColorColumn.php | 96 - sources/app/Action/TaskAssignColorLink.php | 95 - .../app/Action/TaskAssignColorPriority.php | 95 - sources/app/Action/TaskAssignColorUser.php | 96 - sources/app/Action/TaskAssignCurrentUser.php | 95 - .../Action/TaskAssignCurrentUserColumn.php | 98 - sources/app/Action/TaskAssignSpecificUser.php | 96 - sources/app/Action/TaskAssignUser.php | 88 - sources/app/Action/TaskClose.php | 80 - sources/app/Action/TaskCloseColumn.php | 84 - sources/app/Action/TaskCloseNoActivity.php | 95 - sources/app/Action/TaskCreation.php | 88 - .../Action/TaskDuplicateAnotherProject.php | 93 - sources/app/Action/TaskEmail.php | 107 - sources/app/Action/TaskEmailNoActivity.php | 124 - sources/app/Action/TaskMoveAnotherProject.php | 92 - sources/app/Action/TaskMoveColumnAssigned.php | 101 - .../Action/TaskMoveColumnCategoryChange.php | 100 - .../app/Action/TaskMoveColumnUnAssigned.php | 101 - sources/app/Action/TaskOpen.php | 80 - sources/app/Action/TaskUpdateStartDate.php | 94 - .../Analytic/AverageLeadCycleTimeAnalytic.php | 116 - .../AverageTimeSpentColumnAnalytic.php | 154 - .../EstimatedTimeComparisonAnalytic.php | 50 - .../app/Analytic/TaskDistributionAnalytic.php | 48 - .../app/Analytic/UserDistributionAnalytic.php | 56 - .../Api/Authorization/ActionAuthorization.php | 19 - .../Authorization/CategoryAuthorization.php | 19 - .../Api/Authorization/ColumnAuthorization.php | 19 - .../Authorization/CommentAuthorization.php | 19 - .../Authorization/ProcedureAuthorization.php | 32 - .../Authorization/ProjectAuthorization.php | 35 - .../Authorization/SubtaskAuthorization.php | 19 - .../Api/Authorization/TaskAuthorization.php | 19 - .../Authorization/TaskFileAuthorization.php | 19 - .../Authorization/TaskLinkAuthorization.php | 19 - .../Api/Authorization/UserAuthorization.php | 22 - .../Middleware/AuthenticationMiddleware.php | 82 - sources/app/Api/Procedure/ActionProcedure.php | 91 - sources/app/Api/Procedure/AppProcedure.php | 47 - sources/app/Api/Procedure/BaseProcedure.php | 85 - sources/app/Api/Procedure/BoardProcedure.php | 25 - .../app/Api/Procedure/CategoryProcedure.php | 59 - sources/app/Api/Procedure/ColumnProcedure.php | 51 - .../app/Api/Procedure/CommentProcedure.php | 62 - .../Api/Procedure/GroupMemberProcedure.php | 37 - sources/app/Api/Procedure/GroupProcedure.php | 49 - sources/app/Api/Procedure/LinkProcedure.php | 111 - sources/app/Api/Procedure/MeProcedure.php | 72 - .../Api/Procedure/ProjectFileProcedure.php | 68 - .../Procedure/ProjectPermissionProcedure.php | 69 - .../app/Api/Procedure/ProjectProcedure.php | 113 - .../app/Api/Procedure/SubtaskProcedure.php | 74 - .../SubtaskTimeTrackingProcedure.php | 39 - .../app/Api/Procedure/SwimlaneProcedure.php | 91 - .../Procedure/TaskExternalLinkProcedure.php | 106 - .../app/Api/Procedure/TaskFileProcedure.php | 70 - .../app/Api/Procedure/TaskLinkProcedure.php | 85 - sources/app/Api/Procedure/TaskProcedure.php | 167 - sources/app/Api/Procedure/UserProcedure.php | 131 - sources/app/Auth/DatabaseAuth.php | 126 - sources/app/Auth/LdapAuth.php | 176 - sources/app/Auth/RememberMeAuth.php | 79 - sources/app/Auth/ReverseProxyAuth.php | 77 - sources/app/Auth/TotpAuth.php | 144 - sources/app/Console/BaseCommand.php | 67 - sources/app/Console/CronjobCommand.php | 32 - .../app/Console/LocaleComparatorCommand.php | 81 - sources/app/Console/LocaleSyncCommand.php | 53 - sources/app/Console/PluginInstallCommand.php | 36 - .../app/Console/PluginUninstallCommand.php | 36 - sources/app/Console/PluginUpgradeCommand.php | 55 - .../ProjectDailyColumnStatsExportCommand.php | 34 - .../ProjectDailyStatsCalculationCommand.php | 28 - sources/app/Console/ResetPasswordCommand.php | 79 - sources/app/Console/ResetTwoFactorCommand.php | 38 - sources/app/Console/SubtaskExportCommand.php | 34 - sources/app/Console/TaskExportCommand.php | 34 - .../TaskOverdueNotificationCommand.php | 191 - sources/app/Console/TaskTriggerCommand.php | 51 - .../app/Console/TransitionExportCommand.php | 34 - sources/app/Console/WorkerCommand.php | 28 - sources/app/Controller/ActionController.php | 77 - .../Controller/ActionCreationController.php | 122 - sources/app/Controller/ActivityController.php | 45 - sources/app/Controller/AnalyticController.php | 178 - sources/app/Controller/AppController.php | 46 - sources/app/Controller/AuthController.php | 83 - .../app/Controller/AvatarFileController.php | 94 - sources/app/Controller/BaseController.php | 158 - .../app/Controller/BoardAjaxController.php | 140 - .../app/Controller/BoardPopoverController.php | 47 - .../app/Controller/BoardTooltipController.php | 127 - .../app/Controller/BoardViewController.php | 69 - sources/app/Controller/CalendarController.php | 107 - sources/app/Controller/CaptchaController.php | 29 - sources/app/Controller/CategoryController.php | 159 - sources/app/Controller/ColumnController.php | 178 - sources/app/Controller/CommentController.php | 191 - sources/app/Controller/ConfigController.php | 219 - sources/app/Controller/CurrencyController.php | 71 - .../app/Controller/CustomFilterController.php | 172 - .../app/Controller/DashboardController.php | 183 - .../Controller/DocumentationController.php | 136 - sources/app/Controller/ExportController.php | 92 - sources/app/Controller/FeedController.php | 55 - .../app/Controller/FileViewerController.php | 136 - .../app/Controller/GroupAjaxController.php | 26 - .../Controller/GroupCreationController.php | 49 - .../app/Controller/GroupListController.php | 173 - .../GroupModificationController.php | 53 - .../app/Controller/ICalendarController.php | 101 - sources/app/Controller/LinkController.php | 150 - sources/app/Controller/OAuthController.php | 130 - .../Controller/PasswordResetController.php | 132 - sources/app/Controller/PluginController.php | 126 - .../ProjectActionDuplicationController.php | 38 - .../Controller/ProjectCreationController.php | 129 - .../app/Controller/ProjectEditController.php | 133 - .../app/Controller/ProjectFileController.php | 79 - .../app/Controller/ProjectGanttController.php | 57 - .../app/Controller/ProjectListController.php | 41 - .../Controller/ProjectOverviewController.php | 32 - .../ProjectPermissionController.php | 198 - .../Controller/ProjectStatusController.php | 102 - .../app/Controller/ProjectTagController.php | 134 - .../ProjectUserOverviewController.php | 130 - .../app/Controller/ProjectViewController.php | 162 - sources/app/Controller/SearchController.php | 67 - sources/app/Controller/SubtaskController.php | 177 - .../Controller/SubtaskConverterController.php | 39 - .../SubtaskRestrictionController.php | 61 - .../Controller/SubtaskStatusController.php | 71 - sources/app/Controller/SwimlaneController.php | 314 -- sources/app/Controller/TagController.php | 121 - sources/app/Controller/TaskAjaxController.php | 49 - sources/app/Controller/TaskBulkController.php | 89 - .../app/Controller/TaskCreationController.php | 86 - .../Controller/TaskDuplicationController.php | 141 - .../Controller/TaskExternalLinkController.php | 178 - sources/app/Controller/TaskFileController.php | 98 - .../app/Controller/TaskGanttController.php | 62 - .../TaskGanttCreationController.php | 70 - .../app/Controller/TaskImportController.php | 74 - .../Controller/TaskInternalLinkController.php | 167 - sources/app/Controller/TaskListController.php | 45 - .../Controller/TaskModificationController.php | 78 - .../app/Controller/TaskPopoverController.php | 26 - .../Controller/TaskRecurrenceController.php | 65 - .../app/Controller/TaskStatusController.php | 62 - .../Controller/TaskSuppressionController.php | 53 - sources/app/Controller/TaskViewController.php | 147 - .../app/Controller/TwoFactorController.php | 202 - sources/app/Controller/UserAjaxController.php | 52 - .../app/Controller/UserCreationController.php | 83 - .../Controller/UserCredentialController.php | 109 - .../app/Controller/UserImportController.php | 77 - sources/app/Controller/UserListController.php | 32 - .../Controller/UserModificationController.php | 69 - .../app/Controller/UserStatusController.php | 111 - sources/app/Controller/UserViewController.php | 217 - .../Controller/WebNotificationController.php | 79 - sources/app/Core/Action/ActionManager.php | 142 - sources/app/Core/Base.php | 205 - sources/app/Core/Cache/Base.php | 38 - sources/app/Core/Cache/CacheInterface.php | 45 - sources/app/Core/Cache/MemoryCache.php | 65 - .../Controller/AccessForbiddenException.php | 14 - sources/app/Core/Controller/BaseException.php | 52 - .../app/Core/Controller/BaseMiddleware.php | 58 - .../Core/Controller/PageNotFoundException.php | 14 - sources/app/Core/Controller/Runner.php | 105 - sources/app/Core/Csv.php | 216 - sources/app/Core/DateParser.php | 336 -- sources/app/Core/Event/EventManager.php | 63 - .../ExternalLink/ExternalLinkInterface.php | 36 - .../Core/ExternalLink/ExternalLinkManager.php | 197 - .../ExternalLinkProviderInterface.php | 71 - .../ExternalLinkProviderNotFound.php | 15 - sources/app/Core/Filter/CriteriaInterface.php | 40 - sources/app/Core/Filter/FilterInterface.php | 56 - .../app/Core/Filter/FormatterInterface.php | 31 - sources/app/Core/Filter/Lexer.php | 155 - sources/app/Core/Filter/LexerBuilder.php | 151 - sources/app/Core/Filter/OrCriteria.php | 68 - sources/app/Core/Filter/QueryBuilder.php | 103 - .../Group/GroupBackendProviderInterface.php | 21 - sources/app/Core/Group/GroupManager.php | 71 - .../app/Core/Group/GroupProviderInterface.php | 40 - sources/app/Core/Helper.php | 104 - sources/app/Core/Http/Client.php | 224 - sources/app/Core/Http/OAuth2.php | 150 - sources/app/Core/Http/RememberMeCookie.php | 120 - sources/app/Core/Http/Request.php | 346 -- sources/app/Core/Http/Response.php | 385 -- sources/app/Core/Http/Route.php | 187 - sources/app/Core/Http/Router.php | 131 - sources/app/Core/Ldap/Client.php | 212 - sources/app/Core/Ldap/ClientException.php | 15 - sources/app/Core/Ldap/Entries.php | 63 - sources/app/Core/Ldap/Entry.php | 91 - sources/app/Core/Ldap/Group.php | 130 - sources/app/Core/Ldap/Query.php | 97 - sources/app/Core/Ldap/User.php | 344 -- sources/app/Core/Mail/Client.php | 117 - sources/app/Core/Mail/ClientInterface.php | 24 - sources/app/Core/Mail/Transport/Mail.php | 55 - sources/app/Core/Mail/Transport/Sendmail.php | 25 - sources/app/Core/Mail/Transport/Smtp.php | 30 - sources/app/Core/Markdown.php | 141 - .../Notification/NotificationInterface.php | 32 - .../app/Core/ObjectStorage/FileStorage.php | 154 - .../ObjectStorage/ObjectStorageException.php | 9 - .../ObjectStorage/ObjectStorageInterface.php | 67 - sources/app/Core/Paginator.php | 459 -- sources/app/Core/Plugin/Base.php | 134 - sources/app/Core/Plugin/Directory.php | 56 - sources/app/Core/Plugin/Hook.php | 99 - sources/app/Core/Plugin/Installer.php | 162 - sources/app/Core/Plugin/Loader.php | 113 - .../Core/Plugin/PluginInstallerException.php | 15 - sources/app/Core/Plugin/SchemaHandler.php | 122 - sources/app/Core/Queue/JobHandler.php | 70 - sources/app/Core/Queue/QueueManager.php | 71 - sources/app/Core/Security/AccessMap.php | 175 - .../Core/Security/AuthenticationManager.php | 187 - .../AuthenticationProviderInterface.php | 28 - sources/app/Core/Security/Authorization.php | 46 - .../OAuthAuthenticationProviderInterface.php | 46 - ...asswordAuthenticationProviderInterface.php | 36 - .../PostAuthenticationProviderInterface.php | 69 - .../PreAuthenticationProviderInterface.php | 20 - sources/app/Core/Security/Role.php | 64 - .../SessionCheckProviderInterface.php | 20 - sources/app/Core/Security/Token.php | 61 - sources/app/Core/Session/FlashMessage.php | 71 - sources/app/Core/Session/SessionManager.php | 110 - sources/app/Core/Session/SessionStorage.php | 91 - sources/app/Core/Template.php | 124 - sources/app/Core/Thumbnail.php | 172 - sources/app/Core/Tool.php | 58 - sources/app/Core/Translator.php | 193 - .../app/Core/User/Avatar/AvatarManager.php | 93 - .../User/Avatar/AvatarProviderInterface.php | 30 - sources/app/Core/User/GroupSync.php | 68 - sources/app/Core/User/UserProfile.php | 66 - sources/app/Core/User/UserProperty.php | 74 - .../app/Core/User/UserProviderInterface.php | 103 - sources/app/Core/User/UserSession.php | 228 - sources/app/Core/User/UserSync.php | 76 - sources/app/Event/AuthFailureEvent.php | 44 - sources/app/Event/AuthSuccessEvent.php | 43 - sources/app/Event/CommentEvent.php | 7 - sources/app/Event/FileEvent.php | 7 - sources/app/Event/GenericEvent.php | 45 - sources/app/Event/SubtaskEvent.php | 7 - sources/app/Event/TaskEvent.php | 7 - sources/app/Event/TaskLinkEvent.php | 7 - sources/app/Event/TaskListEvent.php | 11 - sources/app/Event/UserProfileSyncEvent.php | 64 - sources/app/Export/SubtaskExport.php | 124 - sources/app/Export/TaskExport.php | 148 - sources/app/Export/TransitionExport.php | 76 - sources/app/ExternalLink/AttachmentLink.php | 26 - .../ExternalLink/AttachmentLinkProvider.php | 117 - sources/app/ExternalLink/BaseLink.php | 44 - sources/app/ExternalLink/BaseLinkProvider.php | 33 - sources/app/ExternalLink/FileLink.php | 26 - sources/app/ExternalLink/FileLinkProvider.php | 74 - sources/app/ExternalLink/WebLink.php | 37 - sources/app/ExternalLink/WebLinkProvider.php | 77 - sources/app/Filter/BaseDateFilter.php | 103 - sources/app/Filter/BaseFilter.php | 74 - .../ProjectActivityCreationDateFilter.php | 38 - .../Filter/ProjectActivityCreatorFilter.php | 65 - .../Filter/ProjectActivityProjectIdFilter.php | 38 - .../ProjectActivityProjectIdsFilter.php | 43 - .../ProjectActivityProjectNameFilter.php | 38 - .../Filter/ProjectActivityTaskIdFilter.php | 38 - .../ProjectActivityTaskStatusFilter.php | 43 - .../Filter/ProjectActivityTaskTitleFilter.php | 25 - .../Filter/ProjectGroupRoleProjectFilter.php | 38 - .../Filter/ProjectGroupRoleUsernameFilter.php | 44 - sources/app/Filter/ProjectIdsFilter.php | 43 - sources/app/Filter/ProjectStatusFilter.php | 45 - sources/app/Filter/ProjectTypeFilter.php | 45 - .../Filter/ProjectUserRoleProjectFilter.php | 38 - .../Filter/ProjectUserRoleUsernameFilter.php | 41 - sources/app/Filter/TaskAssigneeFilter.php | 75 - sources/app/Filter/TaskCategoryFilter.php | 46 - sources/app/Filter/TaskColorFilter.php | 60 - sources/app/Filter/TaskColumnFilter.php | 44 - sources/app/Filter/TaskCommentFilter.php | 41 - .../app/Filter/TaskCompletionDateFilter.php | 38 - sources/app/Filter/TaskCreationDateFilter.php | 38 - sources/app/Filter/TaskCreatorFilter.php | 74 - sources/app/Filter/TaskDescriptionFilter.php | 38 - sources/app/Filter/TaskDueDateFilter.php | 41 - sources/app/Filter/TaskDueDateRangeFilter.php | 39 - sources/app/Filter/TaskIdExclusionFilter.php | 38 - sources/app/Filter/TaskIdFilter.php | 38 - sources/app/Filter/TaskLinkFilter.php | 85 - .../app/Filter/TaskModificationDateFilter.php | 38 - sources/app/Filter/TaskProjectFilter.php | 44 - sources/app/Filter/TaskProjectsFilter.php | 43 - sources/app/Filter/TaskReferenceFilter.php | 38 - sources/app/Filter/TaskStartDateFilter.php | 38 - sources/app/Filter/TaskStatusFilter.php | 43 - .../app/Filter/TaskSubtaskAssigneeFilter.php | 140 - sources/app/Filter/TaskSwimlaneFilter.php | 50 - sources/app/Filter/TaskTagFilter.php | 74 - sources/app/Filter/TaskTitleFilter.php | 46 - sources/app/Filter/UserNameFilter.php | 35 - sources/app/Formatter/BaseFormatter.php | 50 - .../Formatter/BaseTaskCalendarFormatter.php | 45 - .../app/Formatter/BoardColumnFormatter.php | 94 - sources/app/Formatter/BoardFormatter.php | 66 - .../app/Formatter/BoardSwimlaneFormatter.php | 120 - sources/app/Formatter/BoardTaskFormatter.php | 96 - .../Formatter/GroupAutoCompleteFormatter.php | 69 - .../ProjectActivityEventFormatter.php | 61 - .../app/Formatter/ProjectGanttFormatter.php | 57 - .../SubtaskTimeTrackingCalendarFormatter.php | 38 - .../Formatter/TaskAutoCompleteFormatter.php | 33 - .../app/Formatter/TaskCalendarFormatter.php | 74 - sources/app/Formatter/TaskGanttFormatter.php | 78 - sources/app/Formatter/TaskICalFormatter.php | 143 - .../Formatter/UserAutoCompleteFormatter.php | 38 - .../Group/DatabaseBackendGroupProvider.php | 34 - sources/app/Group/DatabaseGroupProvider.php | 66 - .../app/Group/LdapBackendGroupProvider.php | 54 - sources/app/Group/LdapGroupProvider.php | 76 - sources/app/Helper/AppHelper.php | 161 - sources/app/Helper/AssetHelper.php | 65 - sources/app/Helper/AvatarHelper.php | 68 - sources/app/Helper/BoardHelper.php | 26 - sources/app/Helper/CalendarHelper.php | 112 - sources/app/Helper/DateHelper.php | 157 - sources/app/Helper/FileHelper.php | 109 - sources/app/Helper/FormHelper.php | 363 -- sources/app/Helper/HookHelper.php | 66 - sources/app/Helper/ICalHelper.php | 38 - sources/app/Helper/LayoutHelper.php | 202 - sources/app/Helper/MailHelper.php | 82 - sources/app/Helper/ModelHelper.php | 94 - sources/app/Helper/ProjectActivityHelper.php | 105 - sources/app/Helper/ProjectHeaderHelper.php | 80 - sources/app/Helper/SubtaskHelper.php | 95 - sources/app/Helper/TaskHelper.php | 246 - sources/app/Helper/TextHelper.php | 119 - sources/app/Helper/UrlHelper.php | 191 - sources/app/Helper/UserHelper.php | 192 - sources/app/Import/TaskImport.php | 157 - sources/app/Import/UserImport.php | 120 - sources/app/Job/BaseJob.php | 33 - sources/app/Job/EmailJob.php | 55 - sources/app/Job/HttpAsyncJob.php | 43 - sources/app/Job/NotificationJob.php | 85 - sources/app/Job/ProjectMetricJob.php | 40 - sources/app/Library/password.php | 226 - sources/app/Locale/bs_BA/translations.php | 1219 ----- sources/app/Locale/cs_CZ/translations.php | 1219 ----- sources/app/Locale/da_DK/translations.php | 1219 ----- sources/app/Locale/de_DE/translations.php | 1219 ----- sources/app/Locale/el_GR/translations.php | 1219 ----- sources/app/Locale/es_ES/translations.php | 1219 ----- sources/app/Locale/fi_FI/translations.php | 1219 ----- sources/app/Locale/fr_FR/translations.php | 1220 ----- sources/app/Locale/hu_HU/translations.php | 1219 ----- sources/app/Locale/id_ID/translations.php | 1219 ----- sources/app/Locale/it_IT/translations.php | 1219 ----- sources/app/Locale/ja_JP/translations.php | 1219 ----- sources/app/Locale/ko_KR/translations.php | 1219 ----- sources/app/Locale/my_MY/translations.php | 1219 ----- sources/app/Locale/nb_NO/translations.php | 1219 ----- sources/app/Locale/nl_NL/translations.php | 1219 ----- sources/app/Locale/pl_PL/translations.php | 1219 ----- sources/app/Locale/pt_BR/translations.php | 1219 ----- sources/app/Locale/pt_PT/translations.php | 1219 ----- sources/app/Locale/ru_RU/translations.php | 1219 ----- .../app/Locale/sr_Latn_RS/translations.php | 1219 ----- sources/app/Locale/sv_SE/translations.php | 1219 ----- sources/app/Locale/th_TH/translations.php | 1219 ----- sources/app/Locale/tr_TR/translations.php | 1219 ----- sources/app/Locale/zh_CN/translations.php | 1219 ----- .../ApplicationAuthorizationMiddleware.php | 27 - .../Middleware/AuthenticationMiddleware.php | 56 - .../app/Middleware/BootstrapMiddleware.php | 44 - .../PostAuthenticationMiddleware.php | 36 - .../ProjectAuthorizationMiddleware.php | 34 - sources/app/Model/ActionModel.php | 202 - sources/app/Model/ActionParameterModel.php | 164 - sources/app/Model/AvatarFileModel.php | 139 - sources/app/Model/BoardModel.php | 115 - sources/app/Model/CategoryModel.php | 230 - sources/app/Model/ColorModel.php | 228 - sources/app/Model/ColumnModel.php | 223 - sources/app/Model/CommentModel.php | 173 - sources/app/Model/ConfigModel.php | 89 - sources/app/Model/CurrencyModel.php | 111 - sources/app/Model/CustomFilterModel.php | 104 - sources/app/Model/FileModel.php | 378 -- sources/app/Model/GroupMemberModel.php | 130 - sources/app/Model/GroupModel.php | 119 - sources/app/Model/LanguageModel.php | 179 - sources/app/Model/LastLoginModel.php | 92 - sources/app/Model/LinkModel.php | 178 - sources/app/Model/MetadataModel.php | 139 - sources/app/Model/NotificationModel.php | 173 - sources/app/Model/NotificationTypeModel.php | 128 - sources/app/Model/PasswordResetModel.php | 95 - sources/app/Model/ProjectActivityModel.php | 94 - .../Model/ProjectDailyColumnStatsModel.php | 254 - sources/app/Model/ProjectDailyStatsModel.php | 76 - sources/app/Model/ProjectDuplicationModel.php | 181 - sources/app/Model/ProjectFileModel.php | 74 - sources/app/Model/ProjectGroupRoleModel.php | 191 - sources/app/Model/ProjectMetadataModel.php | 54 - sources/app/Model/ProjectModel.php | 515 -- .../app/Model/ProjectNotificationModel.php | 67 - .../Model/ProjectNotificationTypeModel.php | 57 - sources/app/Model/ProjectPermissionModel.php | 166 - .../app/Model/ProjectTaskDuplicationModel.php | 35 - .../app/Model/ProjectTaskPriorityModel.php | 74 - sources/app/Model/ProjectUserRoleModel.php | 282 -- sources/app/Model/RememberMeSessionModel.php | 152 - sources/app/Model/SettingModel.php | 113 - sources/app/Model/SubtaskModel.php | 444 -- .../app/Model/SubtaskTimeTrackingModel.php | 298 -- sources/app/Model/SwimlaneModel.php | 508 -- sources/app/Model/TagDuplicationModel.php | 87 - sources/app/Model/TagModel.php | 180 - sources/app/Model/TaskAnalyticModel.php | 72 - sources/app/Model/TaskCreationModel.php | 109 - sources/app/Model/TaskDuplicationModel.php | 145 - sources/app/Model/TaskExternalLinkModel.php | 101 - sources/app/Model/TaskFileModel.php | 104 - sources/app/Model/TaskFinderModel.php | 459 -- sources/app/Model/TaskLinkModel.php | 281 -- sources/app/Model/TaskMetadataModel.php | 35 - sources/app/Model/TaskModel.php | 146 - sources/app/Model/TaskModificationModel.php | 113 - sources/app/Model/TaskPositionModel.php | 239 - .../app/Model/TaskProjectDuplicationModel.php | 60 - sources/app/Model/TaskProjectMoveModel.php | 68 - sources/app/Model/TaskRecurrenceModel.php | 147 - sources/app/Model/TaskStatusModel.php | 146 - sources/app/Model/TaskTagModel.php | 184 - sources/app/Model/TimezoneModel.php | 58 - sources/app/Model/TransitionModel.php | 130 - sources/app/Model/UserLockingModel.php | 105 - sources/app/Model/UserMentionModel.php | 62 - sources/app/Model/UserMetadataModel.php | 35 - sources/app/Model/UserModel.php | 390 -- .../app/Model/UserNotificationFilterModel.php | 206 - sources/app/Model/UserNotificationModel.php | 204 - .../app/Model/UserNotificationTypeModel.php | 52 - .../app/Model/UserUnreadNotificationModel.php | 117 - .../ActivityStreamNotification.php | 48 - sources/app/Notification/MailNotification.php | 151 - sources/app/Notification/WebNotification.php | 47 - .../app/Notification/WebhookNotification.php | 56 - sources/app/Schema/Mysql.php | 1350 ------ sources/app/Schema/Postgres.php | 1237 ----- sources/app/Schema/Sql/mysql.sql | 702 --- sources/app/Schema/Sql/postgres.sql | 2315 --------- sources/app/Schema/Sqlite.php | 1290 ----- .../app/ServiceProvider/ActionProvider.php | 84 - sources/app/ServiceProvider/ApiProvider.php | 81 - .../AuthenticationProvider.php | 213 - .../app/ServiceProvider/AvatarProvider.php | 35 - sources/app/ServiceProvider/ClassProvider.php | 180 - .../app/ServiceProvider/CommandProvider.php | 62 - .../app/ServiceProvider/DatabaseProvider.php | 129 - .../EventDispatcherProvider.php | 44 - .../ServiceProvider/ExternalLinkProvider.php | 36 - .../app/ServiceProvider/FilterProvider.php | 178 - sources/app/ServiceProvider/GroupProvider.php | 40 - .../app/ServiceProvider/HelperProvider.php | 46 - .../app/ServiceProvider/LoggingProvider.php | 53 - sources/app/ServiceProvider/MailProvider.php | 34 - .../ServiceProvider/NotificationProvider.php | 45 - .../app/ServiceProvider/PluginProvider.php | 31 - sources/app/ServiceProvider/QueueProvider.php | 27 - sources/app/ServiceProvider/RouteProvider.php | 199 - .../app/ServiceProvider/SessionProvider.php | 42 - sources/app/Subscriber/AuthSubscriber.php | 107 - sources/app/Subscriber/BaseSubscriber.php | 39 - .../app/Subscriber/BootstrapSubscriber.php | 42 - .../Subscriber/LdapUserPhotoSubscriber.php | 49 - .../app/Subscriber/NotificationSubscriber.php | 46 - .../ProjectDailySummarySubscriber.php | 30 - .../ProjectModificationDateSubscriber.php | 32 - .../Subscriber/RecurringTaskSubscriber.php | 40 - .../SubtaskTimeTrackingSubscriber.php | 48 - .../app/Subscriber/TransitionSubscriber.php | 28 - sources/app/Template/action/index.php | 71 - sources/app/Template/action/remove.php | 15 - .../app/Template/action_creation/create.php | 16 - .../app/Template/action_creation/event.php | 27 - .../app/Template/action_creation/params.php | 55 - .../app/Template/activity/filter_dropdown.php | 14 - sources/app/Template/activity/project.php | 14 - sources/app/Template/activity/task.php | 9 - .../Template/analytic/avg_time_columns.php | 29 - sources/app/Template/analytic/burndown.php | 34 - sources/app/Template/analytic/cfd.php | 32 - .../app/Template/analytic/compare_hours.php | 62 - sources/app/Template/analytic/layout.php | 10 - .../app/Template/analytic/lead_cycle_time.php | 42 - sources/app/Template/analytic/sidebar.php | 29 - sources/app/Template/analytic/tasks.php | 34 - sources/app/Template/analytic/users.php | 34 - sources/app/Template/app/filters_helper.php | 20 - sources/app/Template/app/forbidden.php | 5 - sources/app/Template/app/notfound.php | 5 - sources/app/Template/auth/index.php | 42 - sources/app/Template/avatar_file/show.php | 23 - sources/app/Template/board/table_column.php | 80 - .../app/Template/board/table_container.php | 58 - sources/app/Template/board/table_swimlane.php | 26 - sources/app/Template/board/table_tasks.php | 31 - sources/app/Template/board/task_avatar.php | 20 - sources/app/Template/board/task_footer.php | 108 - sources/app/Template/board/task_private.php | 62 - sources/app/Template/board/task_public.php | 24 - .../app/Template/board/tooltip_comments.php | 9 - .../Template/board/tooltip_description.php | 5 - .../Template/board/tooltip_external_links.php | 22 - sources/app/Template/board/tooltip_files.php | 20 - .../app/Template/board/tooltip_subtasks.php | 22 - .../app/Template/board/tooltip_tasklinks.php | 34 - sources/app/Template/board/view_private.php | 12 - sources/app/Template/board/view_public.php | 11 - .../board_popover/close_all_tasks_column.php | 18 - sources/app/Template/calendar/show.php | 9 - sources/app/Template/category/edit.php | 23 - sources/app/Template/category/index.php | 45 - sources/app/Template/category/remove.php | 17 - sources/app/Template/column/create.php | 24 - sources/app/Template/column/edit.php | 26 - sources/app/Template/column/index.php | 56 - sources/app/Template/column/remove.php | 15 - sources/app/Template/comment/create.php | 29 - sources/app/Template/comment/edit.php | 27 - sources/app/Template/comment/remove.php | 21 - sources/app/Template/comment/show.php | 39 - sources/app/Template/comments/create.php | 24 - sources/app/Template/comments/show.php | 33 - sources/app/Template/config/about.php | 86 - sources/app/Template/config/api.php | 18 - sources/app/Template/config/application.php | 38 - sources/app/Template/config/board.php | 23 - sources/app/Template/config/calendar.php | 34 - sources/app/Template/config/email.php | 18 - sources/app/Template/config/integrations.php | 17 - .../Template/config/keyboard_shortcuts.php | 35 - sources/app/Template/config/layout.php | 9 - sources/app/Template/config/project.php | 27 - sources/app/Template/config/sidebar.php | 42 - sources/app/Template/config/webhook.php | 31 - sources/app/Template/currency/index.php | 54 - sources/app/Template/custom_filter/add.php | 24 - sources/app/Template/custom_filter/edit.php | 32 - sources/app/Template/custom_filter/index.php | 51 - sources/app/Template/custom_filter/remove.php | 17 - sources/app/Template/dashboard/activity.php | 4 - sources/app/Template/dashboard/calendar.php | 5 - sources/app/Template/dashboard/layout.php | 32 - .../app/Template/dashboard/notifications.php | 55 - sources/app/Template/dashboard/projects.php | 55 - sources/app/Template/dashboard/show.php | 12 - sources/app/Template/dashboard/sidebar.php | 27 - sources/app/Template/dashboard/subtasks.php | 43 - sources/app/Template/dashboard/tasks.php | 53 - sources/app/Template/doc/show.php | 13 - sources/app/Template/event/comment_create.php | 11 - sources/app/Template/event/comment_update.php | 10 - sources/app/Template/event/events.php | 20 - sources/app/Template/event/subtask_create.php | 23 - sources/app/Template/event/subtask_update.php | 23 - .../Template/event/task_assignee_change.php | 17 - sources/app/Template/event/task_close.php | 10 - sources/app/Template/event/task_create.php | 10 - .../app/Template/event/task_file_create.php | 10 - .../app/Template/event/task_move_column.php | 11 - .../app/Template/event/task_move_position.php | 12 - .../app/Template/event/task_move_swimlane.php | 18 - sources/app/Template/event/task_open.php | 10 - sources/app/Template/event/task_update.php | 15 - sources/app/Template/export/sidebar.php | 18 - sources/app/Template/export/subtasks.php | 24 - sources/app/Template/export/summary.php | 24 - sources/app/Template/export/tasks.php | 24 - sources/app/Template/export/transitions.php | 24 - sources/app/Template/feed/project.php | 27 - sources/app/Template/feed/user.php | 27 - sources/app/Template/file_viewer/show.php | 14 - sources/app/Template/group/associate.php | 20 - sources/app/Template/group/dissociate.php | 12 - sources/app/Template/group/index.php | 46 - sources/app/Template/group/remove.php | 12 - sources/app/Template/group/users.php | 43 - sources/app/Template/group_creation/show.php | 15 - .../app/Template/group_modification/show.php | 18 - sources/app/Template/header.php | 118 - sources/app/Template/layout.php | 73 - sources/app/Template/link/create.php | 18 - sources/app/Template/link/edit.php | 21 - sources/app/Template/link/index.php | 33 - sources/app/Template/link/remove.php | 15 - .../Template/notification/comment_create.php | 11 - .../Template/notification/comment_update.php | 7 - .../notification/comment_user_mention.php | 7 - sources/app/Template/notification/footer.php | 7 - .../Template/notification/subtask_create.php | 17 - .../Template/notification/subtask_update.php | 21 - .../notification/task_assignee_change.php | 20 - .../app/Template/notification/task_close.php | 5 - .../app/Template/notification/task_create.php | 43 - .../notification/task_file_create.php | 5 - .../notification/task_move_column.php | 11 - .../notification/task_move_position.php | 11 - .../notification/task_move_swimlane.php | 19 - .../app/Template/notification/task_open.php | 5 - .../Template/notification/task_overdue.php | 31 - .../app/Template/notification/task_update.php | 4 - .../notification/task_user_mention.php | 7 - .../app/Template/password_reset/change.php | 16 - .../app/Template/password_reset/create.php | 17 - sources/app/Template/password_reset/email.php | 6 - sources/app/Template/plugin/directory.php | 55 - sources/app/Template/plugin/layout.php | 9 - sources/app/Template/plugin/remove.php | 13 - sources/app/Template/plugin/show.php | 41 - sources/app/Template/plugin/sidebar.php | 11 - sources/app/Template/project/dropdown.php | 44 - sources/app/Template/project/layout.php | 11 - sources/app/Template/project/sidebar.php | 66 - .../project_action_duplication/show.php | 19 - .../app/Template/project_creation/create.php | 43 - sources/app/Template/project_edit/dates.php | 26 - .../app/Template/project_edit/description.php | 19 - sources/app/Template/project_edit/general.php | 36 - .../Template/project_edit/task_priority.php | 29 - sources/app/Template/project_file/create.php | 33 - sources/app/Template/project_file/remove.php | 15 - sources/app/Template/project_gantt/show.php | 30 - .../app/Template/project_header/dropdown.php | 94 - .../app/Template/project_header/header.php | 15 - .../app/Template/project_header/search.php | 45 - sources/app/Template/project_header/views.php | 24 - sources/app/Template/project_list/show.php | 85 - .../Template/project_overview/activity.php | 8 - .../Template/project_overview/attachments.php | 15 - .../app/Template/project_overview/columns.php | 8 - .../Template/project_overview/description.php | 15 - .../app/Template/project_overview/files.php | 47 - .../app/Template/project_overview/images.php | 35 - .../Template/project_overview/information.php | 39 - .../app/Template/project_overview/show.php | 8 - .../app/Template/project_permission/index.php | 141 - .../app/Template/project_status/disable.php | 14 - .../app/Template/project_status/enable.php | 14 - .../app/Template/project_status/remove.php | 14 - sources/app/Template/project_tag/create.php | 16 - sources/app/Template/project_tag/edit.php | 17 - sources/app/Template/project_tag/index.php | 31 - sources/app/Template/project_tag/remove.php | 15 - .../Template/project_user_overview/layout.php | 27 - .../Template/project_user_overview/roles.php | 33 - .../project_user_overview/sidebar.php | 30 - .../Template/project_user_overview/tasks.php | 46 - .../project_user_overview/tooltip_users.php | 16 - .../app/Template/project_view/duplicate.php | 29 - .../Template/project_view/integrations.php | 15 - .../Template/project_view/notifications.php | 20 - sources/app/Template/project_view/share.php | 18 - sources/app/Template/project_view/show.php | 85 - sources/app/Template/search/activity.php | 39 - sources/app/Template/search/index.php | 43 - sources/app/Template/search/results.php | 54 - sources/app/Template/subtask/create.php | 20 - sources/app/Template/subtask/edit.php | 20 - sources/app/Template/subtask/menu.php | 17 - sources/app/Template/subtask/remove.php | 20 - sources/app/Template/subtask/show.php | 12 - sources/app/Template/subtask/table.php | 69 - .../app/Template/subtask_converter/show.php | 20 - .../app/Template/subtask_restriction/show.php | 17 - sources/app/Template/swimlane/create.php | 20 - sources/app/Template/swimlane/edit.php | 23 - .../app/Template/swimlane/edit_default.php | 18 - sources/app/Template/swimlane/index.php | 28 - sources/app/Template/swimlane/remove.php | 17 - sources/app/Template/swimlane/table.php | 76 - sources/app/Template/tag/create.php | 16 - sources/app/Template/tag/edit.php | 17 - sources/app/Template/tag/index.php | 31 - sources/app/Template/tag/remove.php | 15 - sources/app/Template/task/analytics.php | 36 - sources/app/Template/task/changes.php | 74 - sources/app/Template/task/description.php | 10 - sources/app/Template/task/details.php | 167 - sources/app/Template/task/dropdown.php | 66 - sources/app/Template/task/layout.php | 17 - sources/app/Template/task/public.php | 36 - sources/app/Template/task/show.php | 53 - sources/app/Template/task/sidebar.php | 96 - .../Template/task/time_tracking_details.php | 31 - .../Template/task/time_tracking_summary.php | 13 - sources/app/Template/task/transitions.php | 30 - sources/app/Template/task_bulk/show.php | 24 - sources/app/Template/task_creation/show.php | 49 - .../app/Template/task_duplication/copy.php | 48 - .../Template/task_duplication/duplicate.php | 15 - .../app/Template/task_duplication/move.php | 48 - .../Template/task_external_link/create.php | 13 - .../app/Template/task_external_link/edit.php | 13 - .../app/Template/task_external_link/find.php | 28 - .../app/Template/task_external_link/form.php | 13 - .../Template/task_external_link/remove.php | 15 - .../app/Template/task_external_link/show.php | 12 - .../app/Template/task_external_link/table.php | 44 - sources/app/Template/task_file/create.php | 33 - sources/app/Template/task_file/files.php | 47 - sources/app/Template/task_file/images.php | 34 - sources/app/Template/task_file/remove.php | 15 - sources/app/Template/task_file/screenshot.php | 19 - sources/app/Template/task_file/show.php | 9 - sources/app/Template/task_gantt/show.php | 34 - .../app/Template/task_gantt_creation/show.php | 46 - sources/app/Template/task_import/show.php | 34 - sources/app/Template/task_import/sidebar.php | 9 - .../Template/task_internal_link/create.php | 33 - .../app/Template/task_internal_link/edit.php | 34 - .../Template/task_internal_link/remove.php | 15 - .../app/Template/task_internal_link/show.php | 14 - .../app/Template/task_internal_link/table.php | 85 - sources/app/Template/task_list/show.php | 62 - .../app/Template/task_modification/show.php | 44 - sources/app/Template/task_recurrence/edit.php | 47 - sources/app/Template/task_recurrence/info.php | 37 - sources/app/Template/task_status/close.php | 15 - sources/app/Template/task_status/open.php | 15 - .../app/Template/task_suppression/remove.php | 15 - sources/app/Template/twofactor/check.php | 10 - sources/app/Template/twofactor/disable.php | 14 - sources/app/Template/twofactor/index.php | 15 - sources/app/Template/twofactor/show.php | 31 - sources/app/Template/user_creation/local.php | 47 - sources/app/Template/user_creation/remote.php | 51 - .../user_credential/authentication.php | 27 - .../app/Template/user_credential/password.php | 23 - sources/app/Template/user_import/show.php | 41 - sources/app/Template/user_list/dropdown.php | 27 - sources/app/Template/user_list/show.php | 66 - .../app/Template/user_modification/show.php | 35 - sources/app/Template/user_status/disable.php | 13 - sources/app/Template/user_status/enable.php | 13 - sources/app/Template/user_status/remove.php | 13 - sources/app/Template/user_view/external.php | 11 - .../app/Template/user_view/integrations.php | 13 - sources/app/Template/user_view/last.php | 24 - sources/app/Template/user_view/layout.php | 19 - .../app/Template/user_view/notifications.php | 26 - .../app/Template/user_view/password_reset.php | 26 - sources/app/Template/user_view/profile.php | 9 - sources/app/Template/user_view/sessions.php | 26 - sources/app/Template/user_view/share.php | 15 - sources/app/Template/user_view/show.php | 44 - sources/app/Template/user_view/sidebar.php | 83 - sources/app/Template/user_view/timesheet.php | 29 - .../app/User/Avatar/AvatarFileProvider.php | 42 - sources/app/User/Avatar/GravatarProvider.php | 42 - .../app/User/Avatar/LetterAvatarProvider.php | 170 - sources/app/User/DatabaseUserProvider.php | 143 - sources/app/User/LdapUserProvider.php | 242 - sources/app/User/OAuthUserProvider.php | 140 - sources/app/User/ReverseProxyUserProvider.php | 164 - sources/app/Validator/ActionValidator.php | 38 - sources/app/Validator/AuthValidator.php | 119 - sources/app/Validator/BaseValidator.php | 55 - sources/app/Validator/CategoryValidator.php | 74 - sources/app/Validator/ColumnValidator.php | 75 - sources/app/Validator/CommentValidator.php | 74 - sources/app/Validator/CurrencyValidator.php | 36 - .../app/Validator/CustomFilterValidator.php | 74 - .../app/Validator/ExternalLinkValidator.php | 76 - sources/app/Validator/GroupValidator.php | 71 - sources/app/Validator/LinkValidator.php | 59 - .../app/Validator/PasswordResetValidator.php | 92 - sources/app/Validator/ProjectValidator.php | 90 - sources/app/Validator/SubtaskValidator.php | 101 - sources/app/Validator/SwimlaneValidator.php | 96 - sources/app/Validator/TagValidator.php | 76 - sources/app/Validator/TaskLinkValidator.php | 71 - sources/app/Validator/TaskValidator.php | 226 - sources/app/Validator/UserValidator.php | 128 - sources/app/check_setup.php | 45 - sources/app/common.php | 52 - sources/app/constants.php | 136 - sources/app/functions.php | 136 - sources/assets/css/app.min.css | 1 - sources/assets/css/chosen-sprite.png | Bin 538 -> 0 bytes sources/assets/css/chosen-sprite@2x.png | Bin 738 -> 0 bytes .../css/images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 180 -> 0 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 178 -> 0 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 120 -> 0 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 105 -> 0 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 111 -> 0 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 110 -> 0 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 119 -> 0 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 101 -> 0 bytes .../css/images/ui-icons_222222_256x240.png | Bin 4369 -> 0 bytes .../css/images/ui-icons_2e83ff_256x240.png | Bin 4369 -> 0 bytes .../css/images/ui-icons_444444_256x240.png | Bin 6992 -> 0 bytes .../css/images/ui-icons_454545_256x240.png | Bin 4369 -> 0 bytes .../css/images/ui-icons_555555_256x240.png | Bin 6988 -> 0 bytes .../css/images/ui-icons_777620_256x240.png | Bin 4549 -> 0 bytes .../css/images/ui-icons_777777_256x240.png | Bin 6999 -> 0 bytes .../css/images/ui-icons_888888_256x240.png | Bin 4369 -> 0 bytes .../css/images/ui-icons_cc0000_256x240.png | Bin 4549 -> 0 bytes .../css/images/ui-icons_cd0a0a_256x240.png | Bin 4369 -> 0 bytes .../css/images/ui-icons_ffffff_256x240.png | Bin 6299 -> 0 bytes sources/assets/css/print.min.css | 1 - sources/assets/css/src/accordion.css | 40 - sources/assets/css/src/activity.css | 41 - sources/assets/css/src/alert.css | 59 - sources/assets/css/src/avatar.css | 40 - sources/assets/css/src/base.css | 71 - sources/assets/css/src/board.css | 159 - sources/assets/css/src/button.css | 61 - sources/assets/css/src/comment.css | 70 - sources/assets/css/src/confirm.css | 5 - sources/assets/css/src/dashboard.css | 21 - sources/assets/css/src/dropdown.css | 93 - sources/assets/css/src/files.css | 56 - sources/assets/css/src/filters.css | 70 - sources/assets/css/src/form.css | 200 - sources/assets/css/src/gantt.css | 143 - sources/assets/css/src/header.css | 122 - sources/assets/css/src/links.css | 17 - sources/assets/css/src/listing.css | 21 - sources/assets/css/src/markdown.css | 121 - sources/assets/css/src/pagination.css | 12 - sources/assets/css/src/popover.css | 22 - sources/assets/css/src/print.css | 6 - sources/assets/css/src/project.css | 45 - sources/assets/css/src/responsive.css | 58 - sources/assets/css/src/sidebar.css | 93 - sources/assets/css/src/subtask.css | 8 - sources/assets/css/src/table.css | 165 - sources/assets/css/src/task.css | 288 -- sources/assets/css/src/tasklink.css | 12 - sources/assets/css/src/title.css | 15 - sources/assets/css/src/tooltip.css | 78 - sources/assets/css/src/upload.css | 39 - sources/assets/css/src/views.css | 46 - sources/assets/css/vendor.min.css | 481 -- sources/assets/fonts/FontAwesome.otf | Bin 124988 -> 0 bytes sources/assets/fonts/fontawesome-webfont.eot | Bin 76518 -> 0 bytes sources/assets/fonts/fontawesome-webfont.svg | 685 --- sources/assets/fonts/fontawesome-webfont.ttf | Bin 152796 -> 0 bytes sources/assets/fonts/fontawesome-webfont.woff | Bin 90412 -> 0 bytes .../assets/fonts/fontawesome-webfont.woff2 | Bin 71896 -> 0 bytes sources/assets/img/favicon.png | Bin 2051 -> 0 bytes sources/assets/img/gravatar-icon.png | Bin 517 -> 0 bytes sources/assets/img/icon.svg | 84 - sources/assets/img/touch-icon-ipad-retina.png | Bin 4157 -> 0 bytes sources/assets/img/touch-icon-ipad.png | Bin 2311 -> 0 bytes .../assets/img/touch-icon-iphone-retina.png | Bin 3454 -> 0 bytes sources/assets/img/touch-icon-iphone.png | Bin 1855 -> 0 bytes sources/assets/js/app.min.js | 2 - sources/assets/js/src/Accordion.js | 18 - sources/assets/js/src/App.js | 211 - sources/assets/js/src/AvgTimeColumnChart.js | 47 - sources/assets/js/src/BoardCollapsedMode.js | 27 - sources/assets/js/src/BoardColumnScrolling.js | 85 - sources/assets/js/src/BoardColumnView.js | 79 - sources/assets/js/src/BoardDragAndDrop.js | 103 - .../assets/js/src/BoardHorizontalScrolling.js | 55 - sources/assets/js/src/BoardPolling.js | 33 - sources/assets/js/src/BoardTask.js | 29 - sources/assets/js/src/Bootstrap.js | 4 - sources/assets/js/src/BurndownChart.js | 56 - sources/assets/js/src/Calendar.js | 55 - sources/assets/js/src/Column.js | 59 - .../assets/js/src/CompareHoursColumnChart.js | 46 - .../assets/js/src/CumulativeFlowDiagram.js | 55 - sources/assets/js/src/Dropdown.js | 58 - sources/assets/js/src/FileUpload.js | 125 - sources/assets/js/src/Gantt.js | 482 -- sources/assets/js/src/LeadCycleTimeChart.js | 53 - sources/assets/js/src/Markdown.js | 59 - sources/assets/js/src/Namespace.js | 3 - sources/assets/js/src/Notification.js | 9 - sources/assets/js/src/Popover.js | 151 - sources/assets/js/src/ProjectCreation.js | 15 - sources/assets/js/src/ProjectPermission.js | 19 - sources/assets/js/src/Screenshot.js | 134 - sources/assets/js/src/Search.js | 97 - sources/assets/js/src/Session.js | 21 - sources/assets/js/src/Subtask.js | 93 - sources/assets/js/src/Swimlane.js | 128 - sources/assets/js/src/Task.js | 85 - sources/assets/js/src/TaskRepartitionChart.js | 25 - sources/assets/js/src/TaskTimeColumnChart.js | 47 - sources/assets/js/src/Tooltip.js | 75 - sources/assets/js/src/UserRepartitionChart.js | 25 - sources/assets/js/vendor.min.js | 4244 ----------------- sources/config.default.php | 213 - sources/data/.htaccess | 7 - sources/data/web.config | 6 - sources/doc/2fa.markdown | 33 - sources/doc/analytics-tasks.markdown | 24 - sources/doc/analytics.markdown | 65 - sources/doc/api-action-procedures.markdown | 245 - .../doc/api-application-procedures.markdown | 291 -- sources/doc/api-authentication.markdown | 55 - sources/doc/api-board-procedures.markdown | 158 - sources/doc/api-category-procedures.markdown | 172 - sources/doc/api-column-procedures.markdown | 229 - sources/doc/api-comment-procedures.markdown | 182 - sources/doc/api-examples.markdown | 152 - ...api-external-task-link-procedures.markdown | 221 - .../doc/api-group-member-procedures.markdown | 188 - sources/doc/api-group-procedures.markdown | 174 - ...api-internal-task-link-procedures.markdown | 187 - sources/doc/api-json-rpc.markdown | 71 - sources/doc/api-link-procedures.markdown | 285 -- sources/doc/api-me-procedures.markdown | 385 -- .../doc/api-project-file-procedures.markdown | 221 - ...api-project-permission-procedures.markdown | 307 -- sources/doc/api-project-procedures.markdown | 464 -- sources/doc/api-subtask-procedures.markdown | 194 - ...-subtask-time-tracking-procedures.markdown | 102 - sources/doc/api-swimlane-procedures.markdown | 438 -- sources/doc/api-task-file-procedures.markdown | 217 - sources/doc/api-task-procedures.markdown | 697 --- sources/doc/api-user-procedures.markdown | 357 -- .../doc/application-configuration.markdown | 41 - sources/doc/assets.markdown | 49 - sources/doc/automatic-actions.markdown | 108 - sources/doc/board-collapsed-expanded.markdown | 18 - sources/doc/board-configuration.markdown | 24 - ...zontal-scrolling-and-compact-view.markdown | 10 - sources/doc/board-show-hide-columns.markdown | 12 - sources/doc/bruteforce-protection.markdown | 26 - sources/doc/calendar-configuration.markdown | 42 - sources/doc/calendar.markdown | 20 - sources/doc/centos-installation.markdown | 79 - sources/doc/cli.markdown | 205 - sources/doc/closing-tasks.markdown | 16 - sources/doc/cloudron.markdown | 28 - sources/doc/coding-standards.markdown | 24 - sources/doc/config.markdown | 307 -- sources/doc/contributing.markdown | 70 - sources/doc/create-tasks-by-email.markdown | 45 - sources/doc/creating-projects.markdown | 39 - sources/doc/creating-tasks.markdown | 30 - sources/doc/cronjob.markdown | 32 - sources/doc/currency-rate.markdown | 11 - sources/doc/custom-filters.markdown | 19 - sources/doc/debian-installation.markdown | 65 - sources/doc/docker.markdown | 96 - sources/doc/duplicate-move-tasks.markdown | 58 - sources/doc/editing-projects.markdown | 15 - sources/doc/email-configuration.markdown | 114 - sources/doc/env.markdown | 9 - .../doc/es_ES/calendar-configuration.markdown | 43 - .../doc/es_ES/email-configuration.markdown | 115 - .../es_ES/kanban-vs-todo-and-scrum.markdown | 38 - sources/doc/faq.markdown | 131 - sources/doc/fr_FR/2fa.markdown | 33 - sources/doc/fr_FR/analytics-tasks.markdown | 24 - sources/doc/fr_FR/analytics.markdown | 70 - .../fr_FR/application-configuration.markdown | 41 - .../fr_FR/application-configuration.markup | 41 - sources/doc/fr_FR/automatic-actions.markdown | 133 - .../fr_FR/board-collapsed-expanded.markdown | 18 - .../doc/fr_FR/board-configuration.markdown | 24 - ...zontal-scrolling-and-compact-view.markdown | 11 - .../fr_FR/board-show-hide-columns.markdown | 12 - .../doc/fr_FR/calendar-configuration.markdown | 43 - sources/doc/fr_FR/calendar.markdown | 20 - sources/doc/fr_FR/closing-tasks.markdown | 16 - .../doc/fr_FR/create-tasks-by-email.markdown | 45 - sources/doc/fr_FR/creating-projects.markdown | 39 - sources/doc/fr_FR/creating-tasks.markdown | 35 - sources/doc/fr_FR/currency-rate.markdown | 11 - .../doc/fr_FR/duplicate-move-tasks.markdown | 58 - sources/doc/fr_FR/editing-projects.markdown | 15 - .../doc/fr_FR/gantt-chart-projects.markdown | 17 - sources/doc/fr_FR/gantt-chart-tasks.markdown | 20 - sources/doc/fr_FR/index.markdown | 64 - .../fr_FR/kanban-vs-todo-and-scrum.markdown | 36 - sources/doc/fr_FR/keyboard-shortcuts.markdown | 37 - sources/doc/fr_FR/link-labels.markdown | 13 - sources/doc/fr_FR/notifications.markdown | 45 - .../doc/fr_FR/project-configuration.markdown | 42 - .../doc/fr_FR/project-permissions.markdown | 22 - sources/doc/fr_FR/project-types.markdown | 14 - sources/doc/fr_FR/project-views.markdown | 61 - sources/doc/fr_FR/recurring-tasks.markdown | 24 - sources/doc/fr_FR/removing-projects.markdown | 10 - sources/doc/fr_FR/roles.markdown | 24 - sources/doc/fr_FR/screenshots.markdown | 26 - .../screenshots/automatic-action-creation.png | Bin 19900 -> 0 bytes .../screenshots/board-collapsed-mode.png | Bin 7074 -> 0 bytes .../fr_FR/screenshots/board-compact-mode.png | Bin 12765 -> 0 bytes .../fr_FR/screenshots/board-expanded-mode.png | Bin 11783 -> 0 bytes .../fr_FR/screenshots/board-task-limit.png | Bin 16848 -> 0 bytes sources/doc/fr_FR/screenshots/board-view.png | Bin 24371 -> 0 bytes .../doc/fr_FR/screenshots/calendar-view.png | Bin 21691 -> 0 bytes sources/doc/fr_FR/screenshots/gantt-view.png | Bin 29367 -> 0 bytes sources/doc/fr_FR/screenshots/hide-column.png | Bin 9642 -> 0 bytes sources/doc/fr_FR/screenshots/list-view.png | Bin 23457 -> 0 bytes sources/doc/fr_FR/screenshots/new-project.png | Bin 20818 -> 0 bytes sources/doc/fr_FR/screenshots/new-user.png | Bin 26286 -> 0 bytes .../screenshots/project-disable-sharing.png | Bin 17706 -> 0 bytes .../doc/fr_FR/screenshots/project-edition.png | Bin 40230 -> 0 bytes .../screenshots/project-enable-sharing.png | Bin 14297 -> 0 bytes .../fr_FR/screenshots/project-permissions.png | Bin 32926 -> 0 bytes .../doc/fr_FR/screenshots/project-view.png | Bin 40868 -> 0 bytes sources/doc/fr_FR/screenshots/show-column.png | Bin 17940 -> 0 bytes .../screenshots/swimlane-configuration.png | Bin 14226 -> 0 bytes sources/doc/fr_FR/screenshots/swimlanes.png | Bin 25290 -> 0 bytes .../fr_FR/screenshots/task-creation-board.png | Bin 3915 -> 0 bytes .../fr_FR/screenshots/task-creation-form.png | Bin 42123 -> 0 bytes sources/doc/fr_FR/sharing-projects.markdown | 35 - sources/doc/fr_FR/subtasks.markdown | 43 - sources/doc/fr_FR/swimlanes.markdown | 29 - sources/doc/fr_FR/task-links.markdown | 22 - sources/doc/fr_FR/time-tracking.markdown | 44 - sources/doc/fr_FR/transitions.markdown | 20 - sources/doc/fr_FR/usage-examples.markdown | 69 - sources/doc/fr_FR/user-management.markdown | 35 - sources/doc/fr_FR/what-is-kanban.markdown | 34 - sources/doc/freebsd-installation.markdown | 128 - sources/doc/gantt-chart-projects.markdown | 17 - sources/doc/gantt-chart-tasks.markdown | 20 - sources/doc/groups.markdown | 17 - sources/doc/heroku.markdown | 39 - sources/doc/ical.markdown | 78 - sources/doc/index.markdown | 143 - sources/doc/installation.markdown | 66 - sources/doc/kanban-vs-todo-and-scrum.markdown | 37 - sources/doc/keyboard-shortcuts.markdown | 38 - sources/doc/ldap-authentication.markdown | 184 - .../doc/ldap-configuration-examples.markdown | 221 - sources/doc/ldap-group-sync.markdown | 78 - sources/doc/ldap-parameters.markdown | 36 - sources/doc/ldap-profile-picture.markdown | 27 - sources/doc/link-labels.markdown | 11 - sources/doc/mysql-configuration.markdown | 72 - sources/doc/nice-urls.markdown | 128 - sources/doc/nitrous.markdown | 10 - sources/doc/notifications.markdown | 46 - sources/doc/performances.markdown | 39 - ...lugin-authentication-architecture.markdown | 99 - sources/doc/plugin-authentication.markdown | 40 - ...plugin-authorization-architecture.markdown | 39 - sources/doc/plugin-automatic-actions.markdown | 60 - sources/doc/plugin-avatar-provider.markdown | 32 - sources/doc/plugin-directory.markdown | 15 - sources/doc/plugin-events.markdown | 27 - sources/doc/plugin-external-link.markdown | 78 - sources/doc/plugin-group-provider.markdown | 55 - sources/doc/plugin-helpers.markdown | 40 - sources/doc/plugin-hooks.markdown | 204 - sources/doc/plugin-ldap-client.markdown | 99 - sources/doc/plugin-mail-transports.markdown | 50 - sources/doc/plugin-metadata.markdown | 42 - sources/doc/plugin-notifications.markdown | 60 - sources/doc/plugin-overrides.markdown | 42 - sources/doc/plugin-registration.markdown | 161 - sources/doc/plugin-routes.markdown | 85 - sources/doc/plugin-schema-migrations.markdown | 39 - sources/doc/plugins.markdown | 46 - sources/doc/postgresql-configuration.markdown | 52 - sources/doc/project-configuration.markdown | 42 - sources/doc/project-permissions.markdown | 23 - sources/doc/project-types.markdown | 14 - sources/doc/project-views.markdown | 58 - sources/doc/recurring-tasks.markdown | 24 - sources/doc/removing-projects.markdown | 10 - sources/doc/requirements.markdown | 110 - .../doc/reverse-proxy-authentication.markdown | 64 - sources/doc/roles.markdown | 24 - sources/doc/rss.markdown | 23 - sources/doc/screenshots.markdown | 25 - .../screenshots/automatic-action-creation.png | Bin 16241 -> 0 bytes .../doc/screenshots/board-collapsed-mode.png | Bin 6296 -> 0 bytes .../doc/screenshots/board-compact-mode.png | Bin 13501 -> 0 bytes .../doc/screenshots/board-expanded-mode.png | Bin 10680 -> 0 bytes sources/doc/screenshots/board-task-limit.png | Bin 22642 -> 0 bytes sources/doc/screenshots/board-view.png | Bin 24460 -> 0 bytes sources/doc/screenshots/calendar-view.png | Bin 20973 -> 0 bytes sources/doc/screenshots/gantt-view.png | Bin 27793 -> 0 bytes sources/doc/screenshots/groups-management.png | Bin 17922 -> 0 bytes sources/doc/screenshots/hide-column.png | Bin 8553 -> 0 bytes sources/doc/screenshots/list-view.png | Bin 22769 -> 0 bytes .../doc/screenshots/mention-autocomplete.png | Bin 3066 -> 0 bytes sources/doc/screenshots/new-project.png | Bin 20808 -> 0 bytes sources/doc/screenshots/new-user.png | Bin 22387 -> 0 bytes .../screenshots/project-disable-sharing.png | Bin 15375 -> 0 bytes sources/doc/screenshots/project-edition.png | Bin 36345 -> 0 bytes .../screenshots/project-enable-sharing.png | Bin 12251 -> 0 bytes .../doc/screenshots/project-permissions.png | Bin 41833 -> 0 bytes sources/doc/screenshots/project-remove.png | Bin 4330 -> 0 bytes sources/doc/screenshots/project-view.png | Bin 37215 -> 0 bytes sources/doc/screenshots/show-column.png | Bin 13581 -> 0 bytes .../screenshots/swimlane-configuration.png | Bin 13069 -> 0 bytes sources/doc/screenshots/swimlanes.png | Bin 25733 -> 0 bytes sources/doc/screenshots/tags-board.png | Bin 7405 -> 0 bytes sources/doc/screenshots/tags-global.png | Bin 9617 -> 0 bytes sources/doc/screenshots/tags-projects.png | Bin 13718 -> 0 bytes sources/doc/screenshots/tags-search.png | Bin 3904 -> 0 bytes sources/doc/screenshots/tags-task.png | Bin 4766 -> 0 bytes .../doc/screenshots/task-creation-board.png | Bin 10242 -> 0 bytes .../doc/screenshots/task-creation-form.png | Bin 34726 -> 0 bytes sources/doc/search.markdown | 185 - sources/doc/sharing-projects.markdown | 35 - sources/doc/sqlite-database.markdown | 50 - sources/doc/subtasks.markdown | 44 - sources/doc/suse-installation.markdown | 14 - sources/doc/swimlanes.markdown | 32 - sources/doc/syntax-guide.markdown | 139 - sources/doc/tags.markdown | 28 - sources/doc/task-links.markdown | 22 - sources/doc/tests.markdown | 154 - sources/doc/time-tracking.markdown | 43 - sources/doc/transitions.markdown | 20 - sources/doc/translations.markdown | 68 - sources/doc/ubuntu-installation.markdown | 65 - sources/doc/update.markdown | 34 - sources/doc/usage-examples.markdown | 67 - sources/doc/user-management.markdown | 35 - sources/doc/user-mentions.markdown | 17 - sources/doc/user-types.markdown | 14 - sources/doc/vagrant.markdown | 10 - sources/doc/webhooks.markdown | 271 -- sources/doc/what-is-kanban.markdown | 32 - .../doc/windows-apache-installation.markdown | 130 - sources/doc/windows-iis-installation.markdown | 67 - sources/doc/worker.markdown | 35 - sources/favicon.ico | Bin 13094 -> 0 bytes sources/index.php | 12 - sources/jsonrpc.php | 5 - sources/kanboard | 13 - sources/robots.txt | 2 - sources/vendor/autoload.php | 4 +- sources/vendor/bin/picofeed | 1 + .../vendor/christian-riesen/base32/.gitignore | 3 + .../christian-riesen/base32/.travis.yml | 19 + .../vendor/christian-riesen/base32/README.md | 60 + .../christian-riesen/base32/composer.json | 33 + .../base32/tests/Base32Test.php | 51 + .../base32/tests/bootstrap.php | 5 + .../vendor/christian-riesen/otp/.gitignore | 5 + .../vendor/christian-riesen/otp/.travis.yml | 11 + sources/vendor/christian-riesen/otp/README.md | 105 + .../vendor/christian-riesen/otp/composer.json | 28 + .../otp/tests/Otp/GoogleAuthenticatorTest.php | 88 + .../otp/tests/Otp/OtpTest.php | 124 + sources/vendor/composer/ClassLoader.php | 48 +- sources/vendor/composer/autoload_classmap.php | 153 +- .../vendor/composer/autoload_namespaces.php | 2 + sources/vendor/composer/autoload_real.php | 16 +- sources/vendor/composer/autoload_static.php | 174 +- sources/vendor/composer/installed.json | 143 +- sources/vendor/eluceo/ical/.gitignore | 3 + sources/vendor/eluceo/ical/.travis.yml | 19 + sources/vendor/eluceo/ical/README.md | 158 + sources/vendor/eluceo/ical/composer.json | 43 + .../Component/CalendarIntegrationTest.php | 64 + .../ical/tests/Eluceo/iCal/ComponentTest.php | 45 + .../tests/Eluceo/iCal/ParameterBagTest.php | 35 + .../Eluceo/iCal/Property/ArrayValueTest.php | 26 + .../iCal/Property/Event/DescriptionTest.php | 17 + .../iCal/Property/Event/OrganizerTest.php | 63 + .../Property/Event/RecurrenceRuleTest.php | 21 + .../Eluceo/iCal/Property/StringValueTest.php | 63 + .../tests/Eluceo/iCal/PropertyBagTest.php | 18 + .../ical/tests/Eluceo/iCal/PropertyTest.php | 42 + sources/vendor/erusev/parsedown/.travis.yml | 16 + sources/vendor/erusev/parsedown/README.md | 57 + sources/vendor/erusev/parsedown/composer.json | 18 + .../erusev/parsedown/test/CommonMarkTest.php | 74 + .../erusev/parsedown/test/ParsedownTest.php | 159 + .../erusev/parsedown/test/TestParsedown.php | 5 + .../erusev/parsedown/test/bootstrap.php | 3 + .../parsedown/test/data/aesthetic_table.html | 18 + .../parsedown/test/data/aesthetic_table.md | 4 + .../parsedown/test/data/aligned_table.html | 21 + .../parsedown/test/data/aligned_table.md | 4 + .../parsedown/test/data/atx_heading.html | 9 + .../erusev/parsedown/test/data/atx_heading.md | 17 + .../parsedown/test/data/automatic_link.html | 1 + .../parsedown/test/data/automatic_link.md | 1 + .../parsedown/test/data/block-level_html.html | 12 + .../parsedown/test/data/block-level_html.md | 16 + .../parsedown/test/data/code_block.html | 8 + .../erusev/parsedown/test/data/code_block.md | 10 + .../erusev/parsedown/test/data/code_span.html | 6 + .../erusev/parsedown/test/data/code_span.md | 11 + .../test/data/compound_blockquote.html | 9 + .../test/data/compound_blockquote.md | 10 + .../test/data/compound_emphasis.html | 2 + .../parsedown/test/data/compound_emphasis.md | 4 + .../parsedown/test/data/compound_list.html | 12 + .../parsedown/test/data/compound_list.md | 7 + .../test/data/deeply_nested_list.html | 12 + .../parsedown/test/data/deeply_nested_list.md | 6 + .../erusev/parsedown/test/data/em_strong.html | 8 + .../erusev/parsedown/test/data/em_strong.md | 15 + .../erusev/parsedown/test/data/email.html | 1 + .../erusev/parsedown/test/data/email.md | 1 + .../erusev/parsedown/test/data/emphasis.html | 8 + .../erusev/parsedown/test/data/emphasis.md | 13 + .../erusev/parsedown/test/data/escaping.html | 6 + .../erusev/parsedown/test/data/escaping.md | 11 + .../test/data/fenced_code_block.html | 6 + .../parsedown/test/data/fenced_code_block.md | 14 + .../parsedown/test/data/horizontal_rule.html | 5 + .../parsedown/test/data/horizontal_rule.md | 9 + .../parsedown/test/data/html_comment.html | 5 + .../parsedown/test/data/html_comment.md | 8 + .../parsedown/test/data/html_entity.html | 1 + .../erusev/parsedown/test/data/html_entity.md | 1 + .../parsedown/test/data/image_reference.html | 2 + .../parsedown/test/data/image_reference.md | 5 + .../parsedown/test/data/image_title.html | 2 + .../erusev/parsedown/test/data/image_title.md | 3 + .../test/data/implicit_reference.html | 4 + .../parsedown/test/data/implicit_reference.md | 13 + .../parsedown/test/data/inline_link.html | 6 + .../erusev/parsedown/test/data/inline_link.md | 11 + .../test/data/inline_link_title.html | 6 + .../parsedown/test/data/inline_link_title.md | 11 + .../parsedown/test/data/inline_title.html | 1 + .../parsedown/test/data/inline_title.md | 1 + .../parsedown/test/data/lazy_blockquote.html | 6 + .../parsedown/test/data/lazy_blockquote.md | 5 + .../erusev/parsedown/test/data/lazy_list.html | 4 + .../erusev/parsedown/test/data/lazy_list.md | 2 + .../parsedown/test/data/line_break.html | 2 + .../erusev/parsedown/test/data/line_break.md | 2 + .../test/data/multiline_list_paragraph.html | 7 + .../test/data/multiline_list_paragraph.md | 4 + .../test/data/nested_block-level_html.html | 10 + .../test/data/nested_block-level_html.md | 11 + .../parsedown/test/data/ordered_list.html | 13 + .../parsedown/test/data/ordered_list.md | 11 + .../parsedown/test/data/paragraph_list.html | 12 + .../parsedown/test/data/paragraph_list.md | 9 + .../parsedown/test/data/reference_title.html | 2 + .../parsedown/test/data/reference_title.md | 6 + .../test/data/self-closing_html.html | 12 + .../parsedown/test/data/self-closing_html.md | 12 + .../test/data/separated_nested_list.html | 9 + .../test/data/separated_nested_list.md | 4 + .../parsedown/test/data/setext_header.html | 5 + .../parsedown/test/data/setext_header.md | 12 + .../test/data/simple_blockquote.html | 11 + .../parsedown/test/data/simple_blockquote.md | 7 + .../parsedown/test/data/simple_table.html | 37 + .../parsedown/test/data/simple_table.md | 11 + .../parsedown/test/data/span-level_html.html | 5 + .../parsedown/test/data/span-level_html.md | 8 + .../test/data/sparse_dense_list.html | 7 + .../parsedown/test/data/sparse_dense_list.md | 4 + .../parsedown/test/data/sparse_html.html | 8 + .../erusev/parsedown/test/data/sparse_html.md | 8 + .../parsedown/test/data/sparse_list.html | 15 + .../erusev/parsedown/test/data/sparse_list.md | 9 + .../test/data/special_characters.html | 6 + .../parsedown/test/data/special_characters.md | 13 + .../parsedown/test/data/strikethrough.html | 3 + .../parsedown/test/data/strikethrough.md | 5 + .../erusev/parsedown/test/data/strong_em.html | 6 + .../erusev/parsedown/test/data/strong_em.md | 11 + .../test/data/tab-indented_code_block.html | 6 + .../test/data/tab-indented_code_block.md | 6 + .../test/data/table_inline_markdown.html | 22 + .../test/data/table_inline_markdown.md | 5 + .../parsedown/test/data/text_reference.html | 8 + .../parsedown/test/data/text_reference.md | 21 + .../parsedown/test/data/unordered_list.html | 10 + .../parsedown/test/data/unordered_list.md | 8 + .../parsedown/test/data/untidy_table.html | 18 + .../parsedown/test/data/untidy_table.md | 4 + .../parsedown/test/data/url_autolinking.html | 3 + .../parsedown/test/data/url_autolinking.md | 5 + .../parsedown/test/data/whitespace.html | 1 + .../erusev/parsedown/test/data/whitespace.md | 5 + .../lib/PicoDb/Builder/ConditionBuilder.php | 32 +- .../lib/PicoDb/Builder/OrConditionBuilder.php | 43 + .../picodb/lib/PicoDb/Driver/Mysql.php | 2 +- .../{ => vendor/fguillot/picofeed}/LICENSE | 2 +- .../fguillot/picofeed/lib/PicoFeed/Base.php | 34 + .../picofeed/lib/PicoFeed/Client/Client.php | 673 +++ .../lib/PicoFeed/Client/ClientException.php | 14 + .../picofeed/lib/PicoFeed/Client/Curl.php | 386 ++ .../PicoFeed/Client/ForbiddenException.php | 10 + .../lib/PicoFeed/Client/HttpHeaders.php | 79 + .../Client/InvalidCertificateException.php | 12 + .../PicoFeed/Client/InvalidUrlException.php | 12 + .../PicoFeed/Client/MaxRedirectException.php | 12 + .../lib/PicoFeed/Client/MaxSizeException.php | 12 + .../picofeed/lib/PicoFeed/Client/Stream.php | 201 + .../lib/PicoFeed/Client/TimeoutException.php | 12 + .../PicoFeed/Client/UnauthorizedException.php | 10 + .../picofeed/lib/PicoFeed/Client/Url.php | 290 ++ .../picofeed/lib/PicoFeed/Config/Config.php | 96 + .../lib/PicoFeed/Encoding/Encoding.php | 33 + .../lib/PicoFeed/Filter/Attribute.php | 699 +++ .../picofeed/lib/PicoFeed/Filter/Filter.php | 155 + .../picofeed/lib/PicoFeed/Filter/Html.php | 243 + .../picofeed/lib/PicoFeed/Filter/Tag.php | 215 + .../Generator/ContentGeneratorInterface.php | 23 + .../Generator/FileContentGenerator.php | 36 + .../Generator/YoutubeContentGenerator.php | 67 + .../picofeed/lib/PicoFeed/Logging/Logger.php | 114 + .../picofeed/lib/PicoFeed/Parser/Atom.php | 368 ++ .../lib/PicoFeed/Parser/DateParser.php | 127 + .../picofeed/lib/PicoFeed/Parser/Feed.php | 315 ++ .../picofeed/lib/PicoFeed/Parser/Item.php | 479 ++ .../PicoFeed/Parser/MalformedXmlException.php | 13 + .../picofeed/lib/PicoFeed/Parser/Parser.php | 400 ++ .../lib/PicoFeed/Parser/ParserException.php | 15 + .../lib/PicoFeed/Parser/ParserInterface.php | 173 + .../picofeed/lib/PicoFeed/Parser/Rss10.php | 293 ++ .../picofeed/lib/PicoFeed/Parser/Rss20.php | 305 ++ .../picofeed/lib/PicoFeed/Parser/Rss91.php | 13 + .../picofeed/lib/PicoFeed/Parser/Rss92.php | 13 + .../PicoFeed/Parser/XmlEntityException.php | 13 + .../lib/PicoFeed/Parser/XmlParser.php | 246 + .../lib/PicoFeed/PicoFeedException.php | 14 + .../Processor/ContentFilterProcessor.php | 37 + .../Processor/ContentGeneratorProcessor.php | 49 + .../PicoFeed/Processor/ItemPostProcessor.php | 96 + .../Processor/ItemProcessorInterface.php | 25 + .../PicoFeed/Processor/ScraperProcessor.php | 96 + .../picofeed/lib/PicoFeed/Reader/Favicon.php | 190 + .../picofeed/lib/PicoFeed/Reader/Reader.php | 190 + .../lib/PicoFeed/Reader/ReaderException.php | 14 + .../Reader/SubscriptionNotFoundException.php | 12 + .../Reader/UnsupportedFeedFormatException.php | 12 + .../lib/PicoFeed/Rules/.blog.lemonde.fr.php | 14 + .../lib/PicoFeed/Rules/.blogs.nytimes.com.php | 15 + .../picofeed/lib/PicoFeed/Rules/.igen.fr.php | 13 + .../lib/PicoFeed/Rules/.nytimes.com.php | 11 + .../lib/PicoFeed/Rules/.over-blog.com.php | 11 + .../lib/PicoFeed/Rules/.phoronix.com.php | 12 + .../lib/PicoFeed/Rules/.slate.com.php | 20 + .../lib/PicoFeed/Rules/.theguardian.com.php | 14 + .../lib/PicoFeed/Rules/.wikipedia.org.php | 29 + .../lib/PicoFeed/Rules/.wired.com.php | 31 + .../picofeed/lib/PicoFeed/Rules/.wsj.com.php | 15 + .../picofeed/lib/PicoFeed/Rules/01net.com.php | 19 + .../lib/PicoFeed/Rules/abstrusegoose.com.php | 9 + .../lib/PicoFeed/Rules/alainonline.net.php | 15 + .../lib/PicoFeed/Rules/aljazeera.com.php | 22 + .../lib/PicoFeed/Rules/allafrica.com.php | 20 + .../PicoFeed/Rules/allgemeine-zeitung.de.php | 24 + .../PicoFeed/Rules/amazingsuperpowers.com.php | 9 + .../lib/PicoFeed/Rules/anythingcomic.com.php | 14 + .../picofeed/lib/PicoFeed/Rules/ap.org.php | 14 + .../lib/PicoFeed/Rules/areadvd.de.php | 11 + .../lib/PicoFeed/Rules/arstechnica.com.php | 23 + .../lib/PicoFeed/Rules/awkwardzombie.com.php | 11 + .../lib/PicoFeed/Rules/bangkokpost.com.php | 21 + .../picofeed/lib/PicoFeed/Rules/bgr.com.php | 16 + .../lib/PicoFeed/Rules/bigfootjustice.com.php | 9 + .../lib/PicoFeed/Rules/bizjournals.com.php | 13 + .../lib/PicoFeed/Rules/blog.fefe.de.php | 14 + .../lib/PicoFeed/Rules/blog.mapillary.com.php | 12 + .../PicoFeed/Rules/buenosairesherald.com.php | 18 + .../lib/PicoFeed/Rules/bunicomic.com.php | 14 + .../lib/PicoFeed/Rules/buttersafe.com.php | 14 + .../lib/PicoFeed/Rules/cad-comic.com.php | 13 + .../Rules/chaoslife.findchaos.com.php | 11 + .../lib/PicoFeed/Rules/cliquerefresh.com.php | 11 + .../picofeed/lib/PicoFeed/Rules/cnet.com.php | 38 + .../lib/PicoFeed/Rules/consomac.fr.php | 14 + .../lib/PicoFeed/Rules/cowbirdsinlove.com.php | 9 + .../lib/PicoFeed/Rules/csmonitor.com.php | 19 + .../lib/PicoFeed/Rules/dailyjs.com.php | 20 + .../lib/PicoFeed/Rules/dailyreporter.com.php | 16 + .../lib/PicoFeed/Rules/dailytech.com.php | 14 + .../lib/PicoFeed/Rules/degroupnews.com.php | 15 + .../lib/PicoFeed/Rules/derstandard.at.php | 15 + .../lib/PicoFeed/Rules/dilbert.com.php | 12 + .../PicoFeed/Rules/discovermagazine.com.php | 18 + .../lib/PicoFeed/Rules/distrowatch.com.php | 14 + .../lib/PicoFeed/Rules/dozodomo.com.php | 16 + .../PicoFeed/Rules/drawingboardcomic.com.php | 16 + .../Rules/encyclopedie.naheulbeuk.com.php | 13 + .../lib/PicoFeed/Rules/endlessorigami.com.php | 9 + .../lib/PicoFeed/Rules/engadget.com.php | 11 + .../PicoFeed/Rules/escapistmagazine.com.php | 46 + .../lib/PicoFeed/Rules/espn.go.com.php | 12 + .../lib/PicoFeed/Rules/exocomics.com.php | 16 + .../lib/PicoFeed/Rules/explosm.net.php | 14 + .../Rules/extrafabulouscomics.com.php | 9 + .../lib/PicoFeed/Rules/fastcodesign.com.php | 14 + .../lib/PicoFeed/Rules/fastcoexist.com.php | 14 + .../lib/PicoFeed/Rules/fastcompany.com.php | 14 + .../lib/PicoFeed/Rules/ffworld.com.php | 14 + .../lib/PicoFeed/Rules/foreignpolicy.com.php | 22 + .../lib/PicoFeed/Rules/fossbytes.com.php | 19 + .../PicoFeed/Rules/fowllanguagecomics.com.php | 11 + .../picofeed/lib/PicoFeed/Rules/geek.com.php | 17 + .../PicoFeed/Rules/gerbilwithajetpack.com.php | 13 + .../lib/PicoFeed/Rules/giantitp.com.php | 13 + .../lib/PicoFeed/Rules/github.com.php | 15 + .../lib/PicoFeed/Rules/gocomics.com.php | 13 + .../picofeed/lib/PicoFeed/Rules/golem.de.php | 13 + .../lib/PicoFeed/Rules/happletea.com.php | 19 + .../picofeed/lib/PicoFeed/Rules/heise.de.php | 13 + .../lib/PicoFeed/Rules/huffingtonpost.com.php | 14 + .../lib/PicoFeed/Rules/imogenquest.net.php | 9 + .../picofeed/lib/PicoFeed/Rules/ing.dk.php | 13 + .../lib/PicoFeed/Rules/invisiblebread.com.php | 9 + .../lib/PicoFeed/Rules/ir.amd.com.php | 11 + .../lib/PicoFeed/Rules/japantimes.co.jp.php | 22 + .../lib/PicoFeed/Rules/japantoday.com.php | 16 + .../lib/PicoFeed/Rules/journaldugeek.com.php | 12 + .../lib/PicoFeed/Rules/jsonline.com.php | 24 + .../picofeed/lib/PicoFeed/Rules/kanpai.fr.php | 14 + .../PicoFeed/Rules/karriere.jobfinder.dk.php | 13 + .../lib/PicoFeed/Rules/koreaherald.com.php | 12 + .../lib/PicoFeed/Rules/koreatimes.php | 16 + .../PicoFeed/Rules/lastplacecomics.com.php | 9 + .../lib/PicoFeed/Rules/lejapon.fr.php | 18 + .../lib/PicoFeed/Rules/lesjoiesducode.fr.php | 14 + .../picofeed/lib/PicoFeed/Rules/lfg.co.php | 13 + .../lib/PicoFeed/Rules/lifehacker.com.php | 19 + .../picofeed/lib/PicoFeed/Rules/linux.org.php | 15 + .../lib/PicoFeed/Rules/linuxinsider.com.php | 21 + .../picofeed/lib/PicoFeed/Rules/lists.php | 14 + .../lib/PicoFeed/Rules/loadingartist.com.php | 9 + .../lib/PicoFeed/Rules/loldwell.com.php | 11 + .../lib/PicoFeed/Rules/lukesurl.com.php | 16 + .../picofeed/lib/PicoFeed/Rules/macg.co.php | 14 + .../picofeed/lib/PicoFeed/Rules/marc.info.php | 14 + .../PicoFeed/Rules/marriedtothesea.com.php | 13 + .../lib/PicoFeed/Rules/marycagle.com.php | 14 + .../Rules/maximumble.thebookofbiff.com.php | 11 + .../lib/PicoFeed/Rules/medium.com.php | 15 + .../lib/PicoFeed/Rules/mercworks.net.php | 18 + .../lib/PicoFeed/Rules/metronieuws.nl.php | 11 + .../lib/PicoFeed/Rules/milwaukeenns.php | 15 + .../picofeed/lib/PicoFeed/Rules/mlb.com.php | 19 + .../Rules/mokepon.smackjeeves.com.php | 11 + .../PicoFeed/Rules/monwindowsphone.com.php | 14 + .../lib/PicoFeed/Rules/mrlovenstein.com.php | 10 + .../lib/PicoFeed/Rules/muckrock.com.php | 17 + .../PicoFeed/Rules/nationaljournal.com.php | 16 + .../lib/PicoFeed/Rules/nature.com.php | 13 + .../picofeed/lib/PicoFeed/Rules/nba.com.php | 16 + .../lib/PicoFeed/Rules/nedroid.com.php | 9 + .../lib/PicoFeed/Rules/networkworld.com.php | 21 + .../lib/PicoFeed/Rules/neustadt-ticker.de.php | 16 + .../lib/PicoFeed/Rules/niceteethcomic.com.php | 11 + .../lib/PicoFeed/Rules/nichtlustig.de.php | 9 + .../picofeed/lib/PicoFeed/Rules/oglaf.com.php | 20 + .../picofeed/lib/PicoFeed/Rules/onhax.net.php | 16 + .../lib/PicoFeed/Rules/onmilwaukee.php | 25 + .../PicoFeed/Rules/openrightsgroup.org.php | 21 + .../lib/PicoFeed/Rules/opensource.com.php | 12 + .../lib/PicoFeed/Rules/optipess.com.php | 9 + .../lib/PicoFeed/Rules/osnews.com.php | 12 + .../lib/PicoFeed/Rules/pastebin.com.php | 14 + .../lib/PicoFeed/Rules/peebleslab.com.php | 10 + .../lib/PicoFeed/Rules/penny-arcade.com.php | 22 + .../lib/PicoFeed/Rules/pixelbeat.org.php | 13 + .../lib/PicoFeed/Rules/plus.google.com.php | 12 + .../lib/PicoFeed/Rules/popstrip.com.php | 9 + .../lib/PicoFeed/Rules/putaindecode.fr.php | 17 + .../lib/PicoFeed/Rules/recode.net.php | 21 + .../PicoFeed/Rules/retractionwatch.com.php | 18 + .../PicoFeed/Rules/rue89.nouvelobs.com.php | 14 + .../lib/PicoFeed/Rules/rugbyrama.fr.php | 20 + .../lib/PicoFeed/Rules/satwcomic.com.php | 14 + .../lib/PicoFeed/Rules/scrumalliance.org.php | 13 + .../lib/PicoFeed/Rules/securityfocus.com.php | 12 + .../PicoFeed/Rules/sentfromthemoon.com.php | 19 + .../lib/PicoFeed/Rules/sitepoint.com.php | 14 + .../lib/PicoFeed/Rules/slashdot.org.php | 12 + .../PicoFeed/Rules/smallhousebliss.com.php | 20 + .../lib/PicoFeed/Rules/smarthomewelt.de.php | 11 + .../PicoFeed/Rules/smashingmagazine.com.php | 11 + .../lib/PicoFeed/Rules/smbc-comics.com.php | 9 + .../lib/PicoFeed/Rules/soundandvision.com.php | 22 + .../lib/PicoFeed/Rules/spiegel.de.php | 12 + .../lib/PicoFeed/Rules/stereophile.com.php | 12 + .../lib/PicoFeed/Rules/stupidfox.net.php | 14 + .../lib/PicoFeed/Rules/subtraction.com.php | 16 + .../picofeed/lib/PicoFeed/Rules/sz.de.php | 11 + .../lib/PicoFeed/Rules/techcrunch.com.php | 16 + .../PicoFeed/Rules/the-ebook-reader.com.php | 12 + .../lib/PicoFeed/Rules/theatlantic.com.php | 23 + .../lib/PicoFeed/Rules/theawkwardyeti.com.php | 9 + .../lib/PicoFeed/Rules/thecodinglove.com.php | 11 + .../PicoFeed/Rules/thedoghousediaries.com.php | 19 + .../lib/PicoFeed/Rules/thegamercat.com.php | 11 + .../lib/PicoFeed/Rules/thehindu.com.php | 20 + .../lib/PicoFeed/Rules/thelocal.se.php | 21 + .../lib/PicoFeed/Rules/themerepublic.net.php | 11 + .../lib/PicoFeed/Rules/themoscowtimes.com.php | 19 + .../lib/PicoFeed/Rules/thenewslens.com.php | 28 + .../lib/PicoFeed/Rules/theodd1sout.com.php | 9 + .../lib/PicoFeed/Rules/theonion.com.php | 13 + .../lib/PicoFeed/Rules/thestandard.com.hk.php | 23 + .../lib/PicoFeed/Rules/threepanelsoul.com.php | 12 + .../Rules/timesofindia.indiatimes.com.php | 15 + .../lib/PicoFeed/Rules/travel-dealz.de.php | 16 + .../lib/PicoFeed/Rules/treehugger.com.php | 15 + .../lib/PicoFeed/Rules/treelobsters.com.php | 9 + .../lib/PicoFeed/Rules/twogag.com.php | 9 + .../PicoFeed/Rules/twokinds.keenspot.com.php | 11 + .../lib/PicoFeed/Rules/undeadly.org.php | 15 + .../picofeed/lib/PicoFeed/Rules/upi.com.php | 16 + .../lib/PicoFeed/Rules/version2.dk.php | 13 + .../lib/PicoFeed/Rules/vgcats.com.php | 16 + .../picofeed/lib/PicoFeed/Rules/vuxml.org.php | 18 + .../lib/PicoFeed/Rules/www.bbc.co.uk.php | 34 + .../lib/PicoFeed/Rules/www.bdgest.com.php | 16 + .../lib/PicoFeed/Rules/www.bgr.in.php | 24 + .../PicoFeed/Rules/www.businessweek.com.php | 16 + .../lib/PicoFeed/Rules/www.cnn.com.php | 25 + .../lib/PicoFeed/Rules/www.developpez.com.php | 22 + .../lib/PicoFeed/Rules/www.egscomics.com.php | 13 + .../Rules/www.fakingnews.firstpost.com.php | 18 + .../lib/PicoFeed/Rules/www.forbes.com.php | 21 + .../PicoFeed/Rules/www.franceculture.fr.php | 14 + .../Rules/www.futura-sciences.com.php | 20 + .../PicoFeed/Rules/www.geekculture.com.php | 13 + .../lib/PicoFeed/Rules/www.howtogeek.com.php | 15 + .../lib/PicoFeed/Rules/www.lepoint.fr.php | 19 + .../PicoFeed/Rules/www.lesnumeriques.com.php | 26 + .../lib/PicoFeed/Rules/www.mac4ever.com.php | 14 + .../lib/PicoFeed/Rules/www.makeuseof.com.php | 19 + .../Rules/www.monsieur-le-chien.fr.php | 11 + .../lib/PicoFeed/Rules/www.npr.org.php | 21 + .../lib/PicoFeed/Rules/www.numerama.com.php | 16 + .../lib/PicoFeed/Rules/www.oneindia.com.php | 15 + .../lib/PicoFeed/Rules/www.pcinpact.com.php | 14 + .../Rules/www.pseudo-sciences.org.php | 17 + .../lib/PicoFeed/Rules/www.sciencemag.org.php | 16 + .../lib/PicoFeed/Rules/www.slate.fr.php | 20 + .../PicoFeed/Rules/www.universfreebox.com.php | 16 + .../lib/PicoFeed/Rules/www.zeit.de.php | 41 + .../picofeed/lib/PicoFeed/Rules/xkcd.com.php | 9 + .../picofeed/lib/PicoFeed/Rules/zdnet.com.php | 24 + .../lib/PicoFeed/Scraper/CandidateParser.php | 273 ++ .../lib/PicoFeed/Scraper/ParserInterface.php | 13 + .../lib/PicoFeed/Scraper/RuleLoader.php | 107 + .../lib/PicoFeed/Scraper/RuleParser.php | 83 + .../picofeed/lib/PicoFeed/Scraper/Scraper.php | 267 ++ .../PicoFeed/Serialization/Subscription.php | 175 + .../Serialization/SubscriptionList.php | 75 + .../Serialization/SubscriptionListBuilder.php | 204 + .../Serialization/SubscriptionListParser.php | 100 + .../Serialization/SubscriptionParser.php | 142 + .../PicoFeed/Syndication/AtomFeedBuilder.php | 65 + .../lib/PicoFeed/Syndication/AtomHelper.php | 139 + .../PicoFeed/Syndication/AtomItemBuilder.php | 63 + .../lib/PicoFeed/Syndication/FeedBuilder.php | 185 + .../lib/PicoFeed/Syndication/ItemBuilder.php | 209 + .../PicoFeed/Syndication/Rss20FeedBuilder.php | 76 + .../lib/PicoFeed/Syndication/Rss20Helper.php | 115 + .../PicoFeed/Syndication/Rss20ItemBuilder.php | 67 + sources/vendor/fguillot/picofeed/picofeed | 125 + sources/vendor/gregwar/captcha/.gitignore | 3 + sources/vendor/gregwar/captcha/.travis.yml | 12 + sources/vendor/gregwar/captcha/README.md | 108 + sources/vendor/gregwar/captcha/composer.json | 28 + .../vendor/paragonie/random_compat/README.md | 176 + .../paragonie/random_compat/composer.json | 35 + sources/vendor/pimple/pimple/.gitignore | 3 + sources/vendor/pimple/pimple/.travis.yml | 32 + sources/vendor/pimple/pimple/composer.json | 25 + .../pimple/pimple/ext/pimple/.gitignore | 30 + .../vendor/pimple/pimple/ext/pimple/README.md | 12 + .../pimple/pimple/ext/pimple/tests/001.phpt | 45 + .../pimple/pimple/ext/pimple/tests/002.phpt | 15 + .../pimple/pimple/ext/pimple/tests/003.phpt | 16 + .../pimple/pimple/ext/pimple/tests/004.phpt | 30 + .../pimple/pimple/ext/pimple/tests/005.phpt | 27 + .../pimple/pimple/ext/pimple/tests/006.phpt | 51 + .../pimple/pimple/ext/pimple/tests/007.phpt | 22 + .../pimple/pimple/ext/pimple/tests/008.phpt | 29 + .../pimple/pimple/ext/pimple/tests/009.phpt | 13 + .../pimple/pimple/ext/pimple/tests/010.phpt | 45 + .../pimple/pimple/ext/pimple/tests/011.phpt | 19 + .../pimple/pimple/ext/pimple/tests/012.phpt | 28 + .../pimple/pimple/ext/pimple/tests/013.phpt | 33 + .../pimple/pimple/ext/pimple/tests/014.phpt | 30 + .../pimple/pimple/ext/pimple/tests/015.phpt | 17 + .../pimple/pimple/ext/pimple/tests/016.phpt | 24 + .../pimple/pimple/ext/pimple/tests/017.phpt | 17 + .../pimple/pimple/ext/pimple/tests/017_1.phpt | 17 + .../pimple/pimple/ext/pimple/tests/018.phpt | 23 + .../pimple/pimple/ext/pimple/tests/019.phpt | 18 + .../pimple/pimple/ext/pimple/tests/bench.phpb | 51 + .../pimple/ext/pimple/tests/bench_shared.phpb | 25 + sources/vendor/psr/log/.gitignore | 1 + sources/vendor/psr/log/README.md | 45 + sources/vendor/psr/log/composer.json | 17 + sources/vendor/ramsey/array_column/.gitignore | 6 + .../vendor/ramsey/array_column/.travis.yml | 26 + sources/vendor/ramsey/array_column/README.md | 91 + .../vendor/ramsey/array_column/composer.json | 27 + .../array_column/tests/ArrayColumnTest.php | 422 ++ .../ramsey/array_column/tests/bootstrap.php | 5 + .../vendor/swiftmailer/swiftmailer/.gitignore | 4 + .../swiftmailer/swiftmailer/.travis.yml | 28 + .../swiftmailer/swiftmailer/composer.json | 36 + .../swiftmailer/swiftmailer/doc/headers.rst | 742 +++ .../swiftmailer/doc/help-resources.rst | 44 + .../swiftmailer/doc/including-the-files.rst | 46 + .../swiftmailer/swiftmailer/doc/index.rst | 16 + .../swiftmailer/doc/installing.rst | 89 + .../swiftmailer/doc/introduction.rst | 135 + .../swiftmailer/swiftmailer/doc/japanese.rst | 22 + .../swiftmailer/swiftmailer/doc/messages.rst | 1057 ++++ .../swiftmailer/swiftmailer/doc/overview.rst | 161 + .../swiftmailer/swiftmailer/doc/plugins.rst | 385 ++ .../swiftmailer/swiftmailer/doc/sending.rst | 607 +++ .../swiftmailer/doc/uml/Encoders.graffle | Bin 0 -> 3503 bytes .../swiftmailer/doc/uml/Mime.graffle | Bin 0 -> 5575 bytes .../swiftmailer/doc/uml/Transports.graffle | Bin 0 -> 3061 bytes .../tests/IdenticalBinaryConstraint.php | 62 + .../swiftmailer/tests/StreamCollector.php | 11 + .../tests/SwiftMailerSmokeTestCase.php | 46 + .../swiftmailer/tests/SwiftMailerTestCase.php | 34 + .../_samples/charsets/iso-2022-jp/one.txt | 11 + .../_samples/charsets/iso-8859-1/one.txt | 19 + .../tests/_samples/charsets/utf-8/one.txt | 22 + .../tests/_samples/charsets/utf-8/three.txt | 45 + .../tests/_samples/charsets/utf-8/two.txt | 3 + .../tests/_samples/dkim/dkim.test.priv | 15 + .../tests/_samples/dkim/dkim.test.pub | 6 + .../swiftmailer/tests/_samples/files/data.txt | 1 + .../tests/_samples/files/swiftmailer.png | Bin 0 -> 3194 bytes .../swiftmailer/tests/_samples/smime/CA.srl | 1 + .../swiftmailer/tests/_samples/smime/ca.crt | 21 + .../swiftmailer/tests/_samples/smime/ca.key | 27 + .../tests/_samples/smime/create-cert.sh | 40 + .../tests/_samples/smime/encrypt.crt | 19 + .../tests/_samples/smime/encrypt.key | 27 + .../tests/_samples/smime/encrypt2.crt | 19 + .../tests/_samples/smime/encrypt2.key | 27 + .../tests/_samples/smime/intermediate.crt | 19 + .../tests/_samples/smime/intermediate.key | 27 + .../swiftmailer/tests/_samples/smime/sign.crt | 19 + .../swiftmailer/tests/_samples/smime/sign.key | 27 + .../tests/_samples/smime/sign2.crt | 19 + .../tests/_samples/smime/sign2.key | 27 + .../tests/acceptance.conf.php.default | 44 + .../Swift/AttachmentAcceptanceTest.php | 12 + .../FileByteStreamAcceptanceTest.php | 174 + ...leCharacterReaderFactoryAcceptanceTest.php | 179 + .../DependencyContainerAcceptanceTest.php | 20 + .../Swift/EmbeddedFileAcceptanceTest.php | 12 + .../Encoder/Base64EncoderAcceptanceTest.php | 45 + .../Swift/Encoder/QpEncoderAcceptanceTest.php | 54 + .../Encoder/Rfc2231EncoderAcceptanceTest.php | 50 + .../Swift/EncodingAcceptanceTest.php | 30 + .../KeyCache/ArrayKeyCacheAcceptanceTest.php | 173 + .../KeyCache/DiskKeyCacheAcceptanceTest.php | 183 + .../Swift/MessageAcceptanceTest.php | 57 + .../Swift/Mime/AttachmentAcceptanceTest.php | 125 + .../Base64ContentEncoderAcceptanceTest.php | 56 + .../NativeQpContentEncoderAcceptanceTest.php | 88 + .../PlainContentEncoderAcceptanceTest.php | 88 + .../QpContentEncoderAcceptanceTest.php | 157 + .../Swift/Mime/EmbeddedFileAcceptanceTest.php | 138 + .../Base64HeaderEncoderAcceptanceTest.php | 32 + .../Swift/Mime/MimePartAcceptanceTest.php | 129 + .../Mime/SimpleMessageAcceptanceTest.php | 1251 +++++ .../Swift/MimePartAcceptanceTest.php | 15 + .../AbstractStreamBufferAcceptanceTest.php | 134 + .../BasicSocketAcceptanceTest.php | 34 + .../StreamBuffer/ProcessAcceptanceTest.php | 27 + .../StreamBuffer/SocketTimeoutTest.php | 67 + .../StreamBuffer/SslSocketAcceptanceTest.php | 41 + .../StreamBuffer/TlsSocketAcceptanceTest.php | 40 + .../swiftmailer/tests/bootstrap.php | 21 + .../tests/bug/Swift/Bug111Test.php | 42 + .../tests/bug/Swift/Bug118Test.php | 20 + .../tests/bug/Swift/Bug206Test.php | 38 + .../tests/bug/Swift/Bug274Test.php | 21 + .../swiftmailer/tests/bug/Swift/Bug34Test.php | 75 + .../swiftmailer/tests/bug/Swift/Bug35Test.php | 73 + .../swiftmailer/tests/bug/Swift/Bug38Test.php | 194 + .../tests/bug/Swift/Bug518Test.php | 38 + .../swiftmailer/tests/bug/Swift/Bug51Test.php | 121 + .../tests/bug/Swift/Bug534Test.php | 38 + .../swiftmailer/tests/bug/Swift/Bug71Test.php | 20 + .../swiftmailer/tests/bug/Swift/Bug76Test.php | 82 + ...FileByteStreamConsecutiveReadCallsTest.php | 19 + .../tests/fixtures/MimeEntityFixture.php | 59 + .../swiftmailer/tests/smoke.conf.php.default | 63 + .../smoke/Swift/Smoke/AttachmentSmokeTest.php | 32 + .../smoke/Swift/Smoke/BasicSmokeTest.php | 23 + .../Smoke/HtmlWithAttachmentSmokeTest.php | 31 + .../Swift/Smoke/InternationalSmokeTest.php | 39 + .../Swift/ByteStream/ArrayByteStreamTest.php | 202 + .../GenericFixedWidthReaderTest.php | 43 + .../CharacterReader/UsAsciiReaderTest.php | 52 + .../Swift/CharacterReader/Utf8ReaderTest.php | 65 + .../ArrayCharacterStreamTest.php | 360 ++ .../unit/Swift/DependencyContainerTest.php | 174 + .../unit/Swift/Encoder/Base64EncoderTest.php | 173 + .../unit/Swift/Encoder/QpEncoderTest.php | 402 ++ .../unit/Swift/Encoder/Rfc2231EncoderTest.php | 141 + .../unit/Swift/Events/CommandEventTest.php | 36 + .../unit/Swift/Events/EventObjectTest.php | 34 + .../unit/Swift/Events/ResponseEventTest.php | 40 + .../tests/unit/Swift/Events/SendEventTest.php | 99 + .../Events/SimpleEventDispatcherTest.php | 135 + .../Swift/Events/TransportChangeEventTest.php | 32 + .../Events/TransportExceptionEventTest.php | 43 + .../unit/Swift/KeyCache/ArrayKeyCacheTest.php | 242 + .../SimpleKeyCacheInputStreamTest.php | 73 + .../Mailer/ArrayRecipientIteratorTest.php | 42 + .../tests/unit/Swift/MailerTest.php | 147 + .../tests/unit/Swift/MessageTest.php | 130 + .../Swift/Mime/AbstractMimeEntityTest.php | 1054 ++++ .../tests/unit/Swift/Mime/AttachmentTest.php | 320 ++ .../Base64ContentEncoderTest.php | 323 ++ .../PlainContentEncoderTest.php | 173 + .../ContentEncoder/QpContentEncoderTest.php | 518 ++ .../unit/Swift/Mime/EmbeddedFileTest.php | 57 + .../HeaderEncoder/Base64HeaderEncoderTest.php | 13 + .../HeaderEncoder/QpHeaderEncoderTest.php | 223 + .../Swift/Mime/Headers/DateHeaderTest.php | 69 + .../Mime/Headers/IdentificationHeaderTest.php | 189 + .../Swift/Mime/Headers/MailboxHeaderTest.php | 327 ++ .../Mime/Headers/ParameterizedHeaderTest.php | 400 ++ .../Swift/Mime/Headers/PathHeaderTest.php | 77 + .../Mime/Headers/UnstructuredHeaderTest.php | 355 ++ .../tests/unit/Swift/Mime/MimePartTest.php | 233 + .../Swift/Mime/SimpleHeaderFactoryTest.php | 168 + .../unit/Swift/Mime/SimpleHeaderSetTest.php | 734 +++ .../unit/Swift/Mime/SimpleMessageTest.php | 829 ++++ .../unit/Swift/Mime/SimpleMimeEntityTest.php | 11 + .../Swift/Plugins/AntiFloodPluginTest.php | 95 + .../Plugins/BandwidthMonitorPluginTest.php | 130 + .../Swift/Plugins/DecoratorPluginTest.php | 269 ++ .../unit/Swift/Plugins/LoggerPluginTest.php | 190 + .../Swift/Plugins/Loggers/ArrayLoggerTest.php | 65 + .../Swift/Plugins/Loggers/EchoLoggerTest.php | 24 + .../Swift/Plugins/PopBeforeSmtpPluginTest.php | 103 + .../Swift/Plugins/RedirectingPluginTest.php | 185 + .../unit/Swift/Plugins/ReporterPluginTest.php | 88 + .../Plugins/Reporters/HitReporterTest.php | 64 + .../Plugins/Reporters/HtmlReporterTest.php | 54 + .../Swift/Plugins/ThrottlerPluginTest.php | 104 + .../unit/Swift/Signers/DKIMSignerTest.php | 227 + .../unit/Swift/Signers/OpenDKIMSignerTest.php | 45 + .../unit/Swift/Signers/SMimeSignerTest.php | 554 +++ .../ByteArrayReplacementFilterTest.php | 131 + .../StringReplacementFilterFactoryTest.php | 38 + .../StringReplacementFilterTest.php | 55 + .../AbstractSmtpEventSupportTest.php | 560 +++ .../unit/Swift/Transport/AbstractSmtpTest.php | 1249 +++++ .../Esmtp/Auth/CramMd5AuthenticatorTest.php | 66 + .../Esmtp/Auth/LoginAuthenticatorTest.php | 66 + .../Esmtp/Auth/NTLMAuthenticatorTest.php | 235 + .../Esmtp/Auth/PlainAuthenticatorTest.php | 69 + .../Swift/Transport/Esmtp/AuthHandlerTest.php | 167 + .../EsmtpTransport/ExtensionSupportTest.php | 528 ++ .../Swift/Transport/EsmtpTransportTest.php | 298 ++ .../Swift/Transport/FailoverTransportTest.php | 520 ++ .../Transport/LoadBalancedTransportTest.php | 751 +++ .../Swift/Transport/MailTransportTest.php | 452 ++ .../Swift/Transport/SendmailTransportTest.php | 152 + .../unit/Swift/Transport/StreamBufferTest.php | 45 + sources/vendor/symfony/console/.gitignore | 3 + sources/vendor/symfony/console/README.md | 20 + sources/vendor/symfony/console/composer.json | 44 + .../symfony/event-dispatcher/.gitignore | 3 + .../vendor/symfony/event-dispatcher/README.md | 15 + .../symfony/event-dispatcher/composer.json | 44 + .../symfony/polyfill-mbstring/README.md | 13 + .../symfony/polyfill-mbstring/composer.json | 34 + .../vendor/zendframework/zendxml/.gitignore | 5 + .../vendor/zendframework/zendxml/.travis.yml | 43 + .../vendor/zendframework/zendxml/CHANGELOG.md | 24 + .../vendor/zendframework/zendxml/LICENSE.md | 12 + .../vendor/zendframework/zendxml/README.md | 50 + .../zendframework/zendxml/composer.json | 40 + .../ZendXml/Exception/ExceptionInterface.php | 14 + .../Exception/InvalidArgumentException.php | 17 + .../ZendXml/Exception/RuntimeException.php | 17 + .../zendxml/library/ZendXml/Security.php | 374 ++ .../zendframework/zendxml/tests/Bootstrap.php | 92 + .../tests/ZendXmlTest/MultibyteTest.php | 125 + .../tests/ZendXmlTest/SecurityTest.php | 135 + .../zendxml/tests/phpunit.xml.dist | 27 + sources/web.config | 22 - 1821 files changed, 43224 insertions(+), 120048 deletions(-) delete mode 100644 sources/.htaccess delete mode 100644 sources/ChangeLog delete mode 100644 sources/app/.htaccess delete mode 100644 sources/app/Action/Base.php delete mode 100644 sources/app/Action/CommentCreation.php delete mode 100644 sources/app/Action/CommentCreationMoveTaskColumn.php delete mode 100644 sources/app/Action/TaskAssignCategoryColor.php delete mode 100644 sources/app/Action/TaskAssignCategoryLabel.php delete mode 100644 sources/app/Action/TaskAssignCategoryLink.php delete mode 100644 sources/app/Action/TaskAssignColorCategory.php delete mode 100644 sources/app/Action/TaskAssignColorColumn.php delete mode 100644 sources/app/Action/TaskAssignColorLink.php delete mode 100644 sources/app/Action/TaskAssignColorPriority.php delete mode 100644 sources/app/Action/TaskAssignColorUser.php delete mode 100644 sources/app/Action/TaskAssignCurrentUser.php delete mode 100644 sources/app/Action/TaskAssignCurrentUserColumn.php delete mode 100644 sources/app/Action/TaskAssignSpecificUser.php delete mode 100644 sources/app/Action/TaskAssignUser.php delete mode 100644 sources/app/Action/TaskClose.php delete mode 100644 sources/app/Action/TaskCloseColumn.php delete mode 100644 sources/app/Action/TaskCloseNoActivity.php delete mode 100644 sources/app/Action/TaskCreation.php delete mode 100644 sources/app/Action/TaskDuplicateAnotherProject.php delete mode 100644 sources/app/Action/TaskEmail.php delete mode 100644 sources/app/Action/TaskEmailNoActivity.php delete mode 100644 sources/app/Action/TaskMoveAnotherProject.php delete mode 100644 sources/app/Action/TaskMoveColumnAssigned.php delete mode 100644 sources/app/Action/TaskMoveColumnCategoryChange.php delete mode 100644 sources/app/Action/TaskMoveColumnUnAssigned.php delete mode 100644 sources/app/Action/TaskOpen.php delete mode 100644 sources/app/Action/TaskUpdateStartDate.php delete mode 100644 sources/app/Analytic/AverageLeadCycleTimeAnalytic.php delete mode 100644 sources/app/Analytic/AverageTimeSpentColumnAnalytic.php delete mode 100644 sources/app/Analytic/EstimatedTimeComparisonAnalytic.php delete mode 100644 sources/app/Analytic/TaskDistributionAnalytic.php delete mode 100644 sources/app/Analytic/UserDistributionAnalytic.php delete mode 100644 sources/app/Api/Authorization/ActionAuthorization.php delete mode 100644 sources/app/Api/Authorization/CategoryAuthorization.php delete mode 100644 sources/app/Api/Authorization/ColumnAuthorization.php delete mode 100644 sources/app/Api/Authorization/CommentAuthorization.php delete mode 100644 sources/app/Api/Authorization/ProcedureAuthorization.php delete mode 100644 sources/app/Api/Authorization/ProjectAuthorization.php delete mode 100644 sources/app/Api/Authorization/SubtaskAuthorization.php delete mode 100644 sources/app/Api/Authorization/TaskAuthorization.php delete mode 100644 sources/app/Api/Authorization/TaskFileAuthorization.php delete mode 100644 sources/app/Api/Authorization/TaskLinkAuthorization.php delete mode 100644 sources/app/Api/Authorization/UserAuthorization.php delete mode 100644 sources/app/Api/Middleware/AuthenticationMiddleware.php delete mode 100644 sources/app/Api/Procedure/ActionProcedure.php delete mode 100644 sources/app/Api/Procedure/AppProcedure.php delete mode 100644 sources/app/Api/Procedure/BaseProcedure.php delete mode 100644 sources/app/Api/Procedure/BoardProcedure.php delete mode 100644 sources/app/Api/Procedure/CategoryProcedure.php delete mode 100644 sources/app/Api/Procedure/ColumnProcedure.php delete mode 100644 sources/app/Api/Procedure/CommentProcedure.php delete mode 100644 sources/app/Api/Procedure/GroupMemberProcedure.php delete mode 100644 sources/app/Api/Procedure/GroupProcedure.php delete mode 100644 sources/app/Api/Procedure/LinkProcedure.php delete mode 100644 sources/app/Api/Procedure/MeProcedure.php delete mode 100644 sources/app/Api/Procedure/ProjectFileProcedure.php delete mode 100644 sources/app/Api/Procedure/ProjectPermissionProcedure.php delete mode 100644 sources/app/Api/Procedure/ProjectProcedure.php delete mode 100644 sources/app/Api/Procedure/SubtaskProcedure.php delete mode 100644 sources/app/Api/Procedure/SubtaskTimeTrackingProcedure.php delete mode 100644 sources/app/Api/Procedure/SwimlaneProcedure.php delete mode 100644 sources/app/Api/Procedure/TaskExternalLinkProcedure.php delete mode 100644 sources/app/Api/Procedure/TaskFileProcedure.php delete mode 100644 sources/app/Api/Procedure/TaskLinkProcedure.php delete mode 100644 sources/app/Api/Procedure/TaskProcedure.php delete mode 100644 sources/app/Api/Procedure/UserProcedure.php delete mode 100644 sources/app/Auth/DatabaseAuth.php delete mode 100644 sources/app/Auth/LdapAuth.php delete mode 100644 sources/app/Auth/RememberMeAuth.php delete mode 100644 sources/app/Auth/ReverseProxyAuth.php delete mode 100644 sources/app/Auth/TotpAuth.php delete mode 100644 sources/app/Console/BaseCommand.php delete mode 100644 sources/app/Console/CronjobCommand.php delete mode 100644 sources/app/Console/LocaleComparatorCommand.php delete mode 100644 sources/app/Console/LocaleSyncCommand.php delete mode 100644 sources/app/Console/PluginInstallCommand.php delete mode 100644 sources/app/Console/PluginUninstallCommand.php delete mode 100644 sources/app/Console/PluginUpgradeCommand.php delete mode 100644 sources/app/Console/ProjectDailyColumnStatsExportCommand.php delete mode 100644 sources/app/Console/ProjectDailyStatsCalculationCommand.php delete mode 100644 sources/app/Console/ResetPasswordCommand.php delete mode 100644 sources/app/Console/ResetTwoFactorCommand.php delete mode 100644 sources/app/Console/SubtaskExportCommand.php delete mode 100644 sources/app/Console/TaskExportCommand.php delete mode 100644 sources/app/Console/TaskOverdueNotificationCommand.php delete mode 100644 sources/app/Console/TaskTriggerCommand.php delete mode 100644 sources/app/Console/TransitionExportCommand.php delete mode 100644 sources/app/Console/WorkerCommand.php delete mode 100644 sources/app/Controller/ActionController.php delete mode 100644 sources/app/Controller/ActionCreationController.php delete mode 100644 sources/app/Controller/ActivityController.php delete mode 100644 sources/app/Controller/AnalyticController.php delete mode 100644 sources/app/Controller/AppController.php delete mode 100644 sources/app/Controller/AuthController.php delete mode 100644 sources/app/Controller/AvatarFileController.php delete mode 100644 sources/app/Controller/BaseController.php delete mode 100644 sources/app/Controller/BoardAjaxController.php delete mode 100644 sources/app/Controller/BoardPopoverController.php delete mode 100644 sources/app/Controller/BoardTooltipController.php delete mode 100644 sources/app/Controller/BoardViewController.php delete mode 100644 sources/app/Controller/CalendarController.php delete mode 100644 sources/app/Controller/CaptchaController.php delete mode 100644 sources/app/Controller/CategoryController.php delete mode 100644 sources/app/Controller/ColumnController.php delete mode 100644 sources/app/Controller/CommentController.php delete mode 100644 sources/app/Controller/ConfigController.php delete mode 100644 sources/app/Controller/CurrencyController.php delete mode 100644 sources/app/Controller/CustomFilterController.php delete mode 100644 sources/app/Controller/DashboardController.php delete mode 100644 sources/app/Controller/DocumentationController.php delete mode 100644 sources/app/Controller/ExportController.php delete mode 100644 sources/app/Controller/FeedController.php delete mode 100644 sources/app/Controller/FileViewerController.php delete mode 100644 sources/app/Controller/GroupAjaxController.php delete mode 100644 sources/app/Controller/GroupCreationController.php delete mode 100644 sources/app/Controller/GroupListController.php delete mode 100644 sources/app/Controller/GroupModificationController.php delete mode 100644 sources/app/Controller/ICalendarController.php delete mode 100644 sources/app/Controller/LinkController.php delete mode 100644 sources/app/Controller/OAuthController.php delete mode 100644 sources/app/Controller/PasswordResetController.php delete mode 100644 sources/app/Controller/PluginController.php delete mode 100644 sources/app/Controller/ProjectActionDuplicationController.php delete mode 100644 sources/app/Controller/ProjectCreationController.php delete mode 100644 sources/app/Controller/ProjectEditController.php delete mode 100644 sources/app/Controller/ProjectFileController.php delete mode 100644 sources/app/Controller/ProjectGanttController.php delete mode 100644 sources/app/Controller/ProjectListController.php delete mode 100644 sources/app/Controller/ProjectOverviewController.php delete mode 100644 sources/app/Controller/ProjectPermissionController.php delete mode 100644 sources/app/Controller/ProjectStatusController.php delete mode 100644 sources/app/Controller/ProjectTagController.php delete mode 100644 sources/app/Controller/ProjectUserOverviewController.php delete mode 100644 sources/app/Controller/ProjectViewController.php delete mode 100644 sources/app/Controller/SearchController.php delete mode 100644 sources/app/Controller/SubtaskController.php delete mode 100644 sources/app/Controller/SubtaskConverterController.php delete mode 100644 sources/app/Controller/SubtaskRestrictionController.php delete mode 100644 sources/app/Controller/SubtaskStatusController.php delete mode 100644 sources/app/Controller/SwimlaneController.php delete mode 100644 sources/app/Controller/TagController.php delete mode 100644 sources/app/Controller/TaskAjaxController.php delete mode 100644 sources/app/Controller/TaskBulkController.php delete mode 100644 sources/app/Controller/TaskCreationController.php delete mode 100644 sources/app/Controller/TaskDuplicationController.php delete mode 100644 sources/app/Controller/TaskExternalLinkController.php delete mode 100644 sources/app/Controller/TaskFileController.php delete mode 100644 sources/app/Controller/TaskGanttController.php delete mode 100644 sources/app/Controller/TaskGanttCreationController.php delete mode 100644 sources/app/Controller/TaskImportController.php delete mode 100644 sources/app/Controller/TaskInternalLinkController.php delete mode 100644 sources/app/Controller/TaskListController.php delete mode 100644 sources/app/Controller/TaskModificationController.php delete mode 100644 sources/app/Controller/TaskPopoverController.php delete mode 100644 sources/app/Controller/TaskRecurrenceController.php delete mode 100644 sources/app/Controller/TaskStatusController.php delete mode 100644 sources/app/Controller/TaskSuppressionController.php delete mode 100644 sources/app/Controller/TaskViewController.php delete mode 100644 sources/app/Controller/TwoFactorController.php delete mode 100644 sources/app/Controller/UserAjaxController.php delete mode 100644 sources/app/Controller/UserCreationController.php delete mode 100644 sources/app/Controller/UserCredentialController.php delete mode 100644 sources/app/Controller/UserImportController.php delete mode 100644 sources/app/Controller/UserListController.php delete mode 100644 sources/app/Controller/UserModificationController.php delete mode 100644 sources/app/Controller/UserStatusController.php delete mode 100644 sources/app/Controller/UserViewController.php delete mode 100644 sources/app/Controller/WebNotificationController.php delete mode 100644 sources/app/Core/Action/ActionManager.php delete mode 100644 sources/app/Core/Base.php delete mode 100644 sources/app/Core/Cache/Base.php delete mode 100644 sources/app/Core/Cache/CacheInterface.php delete mode 100644 sources/app/Core/Cache/MemoryCache.php delete mode 100644 sources/app/Core/Controller/AccessForbiddenException.php delete mode 100644 sources/app/Core/Controller/BaseException.php delete mode 100644 sources/app/Core/Controller/BaseMiddleware.php delete mode 100644 sources/app/Core/Controller/PageNotFoundException.php delete mode 100644 sources/app/Core/Controller/Runner.php delete mode 100644 sources/app/Core/Csv.php delete mode 100644 sources/app/Core/DateParser.php delete mode 100644 sources/app/Core/Event/EventManager.php delete mode 100644 sources/app/Core/ExternalLink/ExternalLinkInterface.php delete mode 100644 sources/app/Core/ExternalLink/ExternalLinkManager.php delete mode 100644 sources/app/Core/ExternalLink/ExternalLinkProviderInterface.php delete mode 100644 sources/app/Core/ExternalLink/ExternalLinkProviderNotFound.php delete mode 100644 sources/app/Core/Filter/CriteriaInterface.php delete mode 100644 sources/app/Core/Filter/FilterInterface.php delete mode 100644 sources/app/Core/Filter/FormatterInterface.php delete mode 100644 sources/app/Core/Filter/Lexer.php delete mode 100644 sources/app/Core/Filter/LexerBuilder.php delete mode 100644 sources/app/Core/Filter/OrCriteria.php delete mode 100644 sources/app/Core/Filter/QueryBuilder.php delete mode 100644 sources/app/Core/Group/GroupBackendProviderInterface.php delete mode 100644 sources/app/Core/Group/GroupManager.php delete mode 100644 sources/app/Core/Group/GroupProviderInterface.php delete mode 100644 sources/app/Core/Helper.php delete mode 100644 sources/app/Core/Http/Client.php delete mode 100644 sources/app/Core/Http/OAuth2.php delete mode 100644 sources/app/Core/Http/RememberMeCookie.php delete mode 100644 sources/app/Core/Http/Request.php delete mode 100644 sources/app/Core/Http/Response.php delete mode 100644 sources/app/Core/Http/Route.php delete mode 100644 sources/app/Core/Http/Router.php delete mode 100644 sources/app/Core/Ldap/Client.php delete mode 100644 sources/app/Core/Ldap/ClientException.php delete mode 100644 sources/app/Core/Ldap/Entries.php delete mode 100644 sources/app/Core/Ldap/Entry.php delete mode 100644 sources/app/Core/Ldap/Group.php delete mode 100644 sources/app/Core/Ldap/Query.php delete mode 100644 sources/app/Core/Ldap/User.php delete mode 100644 sources/app/Core/Mail/Client.php delete mode 100644 sources/app/Core/Mail/ClientInterface.php delete mode 100644 sources/app/Core/Mail/Transport/Mail.php delete mode 100644 sources/app/Core/Mail/Transport/Sendmail.php delete mode 100644 sources/app/Core/Mail/Transport/Smtp.php delete mode 100644 sources/app/Core/Markdown.php delete mode 100644 sources/app/Core/Notification/NotificationInterface.php delete mode 100644 sources/app/Core/ObjectStorage/FileStorage.php delete mode 100644 sources/app/Core/ObjectStorage/ObjectStorageException.php delete mode 100644 sources/app/Core/ObjectStorage/ObjectStorageInterface.php delete mode 100644 sources/app/Core/Paginator.php delete mode 100644 sources/app/Core/Plugin/Base.php delete mode 100644 sources/app/Core/Plugin/Directory.php delete mode 100644 sources/app/Core/Plugin/Hook.php delete mode 100644 sources/app/Core/Plugin/Installer.php delete mode 100644 sources/app/Core/Plugin/Loader.php delete mode 100644 sources/app/Core/Plugin/PluginInstallerException.php delete mode 100644 sources/app/Core/Plugin/SchemaHandler.php delete mode 100644 sources/app/Core/Queue/JobHandler.php delete mode 100644 sources/app/Core/Queue/QueueManager.php delete mode 100644 sources/app/Core/Security/AccessMap.php delete mode 100644 sources/app/Core/Security/AuthenticationManager.php delete mode 100644 sources/app/Core/Security/AuthenticationProviderInterface.php delete mode 100644 sources/app/Core/Security/Authorization.php delete mode 100644 sources/app/Core/Security/OAuthAuthenticationProviderInterface.php delete mode 100644 sources/app/Core/Security/PasswordAuthenticationProviderInterface.php delete mode 100644 sources/app/Core/Security/PostAuthenticationProviderInterface.php delete mode 100644 sources/app/Core/Security/PreAuthenticationProviderInterface.php delete mode 100644 sources/app/Core/Security/Role.php delete mode 100644 sources/app/Core/Security/SessionCheckProviderInterface.php delete mode 100644 sources/app/Core/Security/Token.php delete mode 100644 sources/app/Core/Session/FlashMessage.php delete mode 100644 sources/app/Core/Session/SessionManager.php delete mode 100644 sources/app/Core/Session/SessionStorage.php delete mode 100644 sources/app/Core/Template.php delete mode 100644 sources/app/Core/Thumbnail.php delete mode 100644 sources/app/Core/Tool.php delete mode 100644 sources/app/Core/Translator.php delete mode 100644 sources/app/Core/User/Avatar/AvatarManager.php delete mode 100644 sources/app/Core/User/Avatar/AvatarProviderInterface.php delete mode 100644 sources/app/Core/User/GroupSync.php delete mode 100644 sources/app/Core/User/UserProfile.php delete mode 100644 sources/app/Core/User/UserProperty.php delete mode 100644 sources/app/Core/User/UserProviderInterface.php delete mode 100644 sources/app/Core/User/UserSession.php delete mode 100644 sources/app/Core/User/UserSync.php delete mode 100644 sources/app/Event/AuthFailureEvent.php delete mode 100644 sources/app/Event/AuthSuccessEvent.php delete mode 100644 sources/app/Event/CommentEvent.php delete mode 100644 sources/app/Event/FileEvent.php delete mode 100644 sources/app/Event/GenericEvent.php delete mode 100644 sources/app/Event/SubtaskEvent.php delete mode 100644 sources/app/Event/TaskEvent.php delete mode 100644 sources/app/Event/TaskLinkEvent.php delete mode 100644 sources/app/Event/TaskListEvent.php delete mode 100644 sources/app/Event/UserProfileSyncEvent.php delete mode 100644 sources/app/Export/SubtaskExport.php delete mode 100644 sources/app/Export/TaskExport.php delete mode 100644 sources/app/Export/TransitionExport.php delete mode 100644 sources/app/ExternalLink/AttachmentLink.php delete mode 100644 sources/app/ExternalLink/AttachmentLinkProvider.php delete mode 100644 sources/app/ExternalLink/BaseLink.php delete mode 100644 sources/app/ExternalLink/BaseLinkProvider.php delete mode 100644 sources/app/ExternalLink/FileLink.php delete mode 100644 sources/app/ExternalLink/FileLinkProvider.php delete mode 100644 sources/app/ExternalLink/WebLink.php delete mode 100644 sources/app/ExternalLink/WebLinkProvider.php delete mode 100644 sources/app/Filter/BaseDateFilter.php delete mode 100644 sources/app/Filter/BaseFilter.php delete mode 100644 sources/app/Filter/ProjectActivityCreationDateFilter.php delete mode 100644 sources/app/Filter/ProjectActivityCreatorFilter.php delete mode 100644 sources/app/Filter/ProjectActivityProjectIdFilter.php delete mode 100644 sources/app/Filter/ProjectActivityProjectIdsFilter.php delete mode 100644 sources/app/Filter/ProjectActivityProjectNameFilter.php delete mode 100644 sources/app/Filter/ProjectActivityTaskIdFilter.php delete mode 100644 sources/app/Filter/ProjectActivityTaskStatusFilter.php delete mode 100644 sources/app/Filter/ProjectActivityTaskTitleFilter.php delete mode 100644 sources/app/Filter/ProjectGroupRoleProjectFilter.php delete mode 100644 sources/app/Filter/ProjectGroupRoleUsernameFilter.php delete mode 100644 sources/app/Filter/ProjectIdsFilter.php delete mode 100644 sources/app/Filter/ProjectStatusFilter.php delete mode 100644 sources/app/Filter/ProjectTypeFilter.php delete mode 100644 sources/app/Filter/ProjectUserRoleProjectFilter.php delete mode 100644 sources/app/Filter/ProjectUserRoleUsernameFilter.php delete mode 100644 sources/app/Filter/TaskAssigneeFilter.php delete mode 100644 sources/app/Filter/TaskCategoryFilter.php delete mode 100644 sources/app/Filter/TaskColorFilter.php delete mode 100644 sources/app/Filter/TaskColumnFilter.php delete mode 100644 sources/app/Filter/TaskCommentFilter.php delete mode 100644 sources/app/Filter/TaskCompletionDateFilter.php delete mode 100644 sources/app/Filter/TaskCreationDateFilter.php delete mode 100644 sources/app/Filter/TaskCreatorFilter.php delete mode 100644 sources/app/Filter/TaskDescriptionFilter.php delete mode 100644 sources/app/Filter/TaskDueDateFilter.php delete mode 100644 sources/app/Filter/TaskDueDateRangeFilter.php delete mode 100644 sources/app/Filter/TaskIdExclusionFilter.php delete mode 100644 sources/app/Filter/TaskIdFilter.php delete mode 100644 sources/app/Filter/TaskLinkFilter.php delete mode 100644 sources/app/Filter/TaskModificationDateFilter.php delete mode 100644 sources/app/Filter/TaskProjectFilter.php delete mode 100644 sources/app/Filter/TaskProjectsFilter.php delete mode 100644 sources/app/Filter/TaskReferenceFilter.php delete mode 100644 sources/app/Filter/TaskStartDateFilter.php delete mode 100644 sources/app/Filter/TaskStatusFilter.php delete mode 100644 sources/app/Filter/TaskSubtaskAssigneeFilter.php delete mode 100644 sources/app/Filter/TaskSwimlaneFilter.php delete mode 100644 sources/app/Filter/TaskTagFilter.php delete mode 100644 sources/app/Filter/TaskTitleFilter.php delete mode 100644 sources/app/Filter/UserNameFilter.php delete mode 100644 sources/app/Formatter/BaseFormatter.php delete mode 100644 sources/app/Formatter/BaseTaskCalendarFormatter.php delete mode 100644 sources/app/Formatter/BoardColumnFormatter.php delete mode 100644 sources/app/Formatter/BoardFormatter.php delete mode 100644 sources/app/Formatter/BoardSwimlaneFormatter.php delete mode 100644 sources/app/Formatter/BoardTaskFormatter.php delete mode 100644 sources/app/Formatter/GroupAutoCompleteFormatter.php delete mode 100644 sources/app/Formatter/ProjectActivityEventFormatter.php delete mode 100644 sources/app/Formatter/ProjectGanttFormatter.php delete mode 100644 sources/app/Formatter/SubtaskTimeTrackingCalendarFormatter.php delete mode 100644 sources/app/Formatter/TaskAutoCompleteFormatter.php delete mode 100644 sources/app/Formatter/TaskCalendarFormatter.php delete mode 100644 sources/app/Formatter/TaskGanttFormatter.php delete mode 100644 sources/app/Formatter/TaskICalFormatter.php delete mode 100644 sources/app/Formatter/UserAutoCompleteFormatter.php delete mode 100644 sources/app/Group/DatabaseBackendGroupProvider.php delete mode 100644 sources/app/Group/DatabaseGroupProvider.php delete mode 100644 sources/app/Group/LdapBackendGroupProvider.php delete mode 100644 sources/app/Group/LdapGroupProvider.php delete mode 100644 sources/app/Helper/AppHelper.php delete mode 100644 sources/app/Helper/AssetHelper.php delete mode 100644 sources/app/Helper/AvatarHelper.php delete mode 100644 sources/app/Helper/BoardHelper.php delete mode 100644 sources/app/Helper/CalendarHelper.php delete mode 100644 sources/app/Helper/DateHelper.php delete mode 100644 sources/app/Helper/FileHelper.php delete mode 100644 sources/app/Helper/FormHelper.php delete mode 100644 sources/app/Helper/HookHelper.php delete mode 100644 sources/app/Helper/ICalHelper.php delete mode 100644 sources/app/Helper/LayoutHelper.php delete mode 100644 sources/app/Helper/MailHelper.php delete mode 100644 sources/app/Helper/ModelHelper.php delete mode 100644 sources/app/Helper/ProjectActivityHelper.php delete mode 100644 sources/app/Helper/ProjectHeaderHelper.php delete mode 100644 sources/app/Helper/SubtaskHelper.php delete mode 100644 sources/app/Helper/TaskHelper.php delete mode 100644 sources/app/Helper/TextHelper.php delete mode 100644 sources/app/Helper/UrlHelper.php delete mode 100644 sources/app/Helper/UserHelper.php delete mode 100644 sources/app/Import/TaskImport.php delete mode 100644 sources/app/Import/UserImport.php delete mode 100644 sources/app/Job/BaseJob.php delete mode 100644 sources/app/Job/EmailJob.php delete mode 100644 sources/app/Job/HttpAsyncJob.php delete mode 100644 sources/app/Job/NotificationJob.php delete mode 100644 sources/app/Job/ProjectMetricJob.php delete mode 100644 sources/app/Library/password.php delete mode 100644 sources/app/Locale/bs_BA/translations.php delete mode 100644 sources/app/Locale/cs_CZ/translations.php delete mode 100644 sources/app/Locale/da_DK/translations.php delete mode 100644 sources/app/Locale/de_DE/translations.php delete mode 100644 sources/app/Locale/el_GR/translations.php delete mode 100644 sources/app/Locale/es_ES/translations.php delete mode 100644 sources/app/Locale/fi_FI/translations.php delete mode 100644 sources/app/Locale/fr_FR/translations.php delete mode 100644 sources/app/Locale/hu_HU/translations.php delete mode 100644 sources/app/Locale/id_ID/translations.php delete mode 100644 sources/app/Locale/it_IT/translations.php delete mode 100644 sources/app/Locale/ja_JP/translations.php delete mode 100644 sources/app/Locale/ko_KR/translations.php delete mode 100644 sources/app/Locale/my_MY/translations.php delete mode 100644 sources/app/Locale/nb_NO/translations.php delete mode 100644 sources/app/Locale/nl_NL/translations.php delete mode 100644 sources/app/Locale/pl_PL/translations.php delete mode 100644 sources/app/Locale/pt_BR/translations.php delete mode 100644 sources/app/Locale/pt_PT/translations.php delete mode 100644 sources/app/Locale/ru_RU/translations.php delete mode 100644 sources/app/Locale/sr_Latn_RS/translations.php delete mode 100644 sources/app/Locale/sv_SE/translations.php delete mode 100644 sources/app/Locale/th_TH/translations.php delete mode 100644 sources/app/Locale/tr_TR/translations.php delete mode 100644 sources/app/Locale/zh_CN/translations.php delete mode 100644 sources/app/Middleware/ApplicationAuthorizationMiddleware.php delete mode 100644 sources/app/Middleware/AuthenticationMiddleware.php delete mode 100644 sources/app/Middleware/BootstrapMiddleware.php delete mode 100644 sources/app/Middleware/PostAuthenticationMiddleware.php delete mode 100644 sources/app/Middleware/ProjectAuthorizationMiddleware.php delete mode 100644 sources/app/Model/ActionModel.php delete mode 100644 sources/app/Model/ActionParameterModel.php delete mode 100644 sources/app/Model/AvatarFileModel.php delete mode 100644 sources/app/Model/BoardModel.php delete mode 100644 sources/app/Model/CategoryModel.php delete mode 100644 sources/app/Model/ColorModel.php delete mode 100644 sources/app/Model/ColumnModel.php delete mode 100644 sources/app/Model/CommentModel.php delete mode 100644 sources/app/Model/ConfigModel.php delete mode 100644 sources/app/Model/CurrencyModel.php delete mode 100644 sources/app/Model/CustomFilterModel.php delete mode 100644 sources/app/Model/FileModel.php delete mode 100644 sources/app/Model/GroupMemberModel.php delete mode 100644 sources/app/Model/GroupModel.php delete mode 100644 sources/app/Model/LanguageModel.php delete mode 100644 sources/app/Model/LastLoginModel.php delete mode 100644 sources/app/Model/LinkModel.php delete mode 100644 sources/app/Model/MetadataModel.php delete mode 100644 sources/app/Model/NotificationModel.php delete mode 100644 sources/app/Model/NotificationTypeModel.php delete mode 100644 sources/app/Model/PasswordResetModel.php delete mode 100644 sources/app/Model/ProjectActivityModel.php delete mode 100644 sources/app/Model/ProjectDailyColumnStatsModel.php delete mode 100644 sources/app/Model/ProjectDailyStatsModel.php delete mode 100644 sources/app/Model/ProjectDuplicationModel.php delete mode 100644 sources/app/Model/ProjectFileModel.php delete mode 100644 sources/app/Model/ProjectGroupRoleModel.php delete mode 100644 sources/app/Model/ProjectMetadataModel.php delete mode 100644 sources/app/Model/ProjectModel.php delete mode 100644 sources/app/Model/ProjectNotificationModel.php delete mode 100644 sources/app/Model/ProjectNotificationTypeModel.php delete mode 100644 sources/app/Model/ProjectPermissionModel.php delete mode 100644 sources/app/Model/ProjectTaskDuplicationModel.php delete mode 100644 sources/app/Model/ProjectTaskPriorityModel.php delete mode 100644 sources/app/Model/ProjectUserRoleModel.php delete mode 100644 sources/app/Model/RememberMeSessionModel.php delete mode 100644 sources/app/Model/SettingModel.php delete mode 100644 sources/app/Model/SubtaskModel.php delete mode 100644 sources/app/Model/SubtaskTimeTrackingModel.php delete mode 100644 sources/app/Model/SwimlaneModel.php delete mode 100644 sources/app/Model/TagDuplicationModel.php delete mode 100644 sources/app/Model/TagModel.php delete mode 100644 sources/app/Model/TaskAnalyticModel.php delete mode 100644 sources/app/Model/TaskCreationModel.php delete mode 100644 sources/app/Model/TaskDuplicationModel.php delete mode 100644 sources/app/Model/TaskExternalLinkModel.php delete mode 100644 sources/app/Model/TaskFileModel.php delete mode 100644 sources/app/Model/TaskFinderModel.php delete mode 100644 sources/app/Model/TaskLinkModel.php delete mode 100644 sources/app/Model/TaskMetadataModel.php delete mode 100644 sources/app/Model/TaskModel.php delete mode 100644 sources/app/Model/TaskModificationModel.php delete mode 100644 sources/app/Model/TaskPositionModel.php delete mode 100644 sources/app/Model/TaskProjectDuplicationModel.php delete mode 100644 sources/app/Model/TaskProjectMoveModel.php delete mode 100644 sources/app/Model/TaskRecurrenceModel.php delete mode 100644 sources/app/Model/TaskStatusModel.php delete mode 100644 sources/app/Model/TaskTagModel.php delete mode 100644 sources/app/Model/TimezoneModel.php delete mode 100644 sources/app/Model/TransitionModel.php delete mode 100644 sources/app/Model/UserLockingModel.php delete mode 100644 sources/app/Model/UserMentionModel.php delete mode 100644 sources/app/Model/UserMetadataModel.php delete mode 100644 sources/app/Model/UserModel.php delete mode 100644 sources/app/Model/UserNotificationFilterModel.php delete mode 100644 sources/app/Model/UserNotificationModel.php delete mode 100644 sources/app/Model/UserNotificationTypeModel.php delete mode 100644 sources/app/Model/UserUnreadNotificationModel.php delete mode 100644 sources/app/Notification/ActivityStreamNotification.php delete mode 100644 sources/app/Notification/MailNotification.php delete mode 100644 sources/app/Notification/WebNotification.php delete mode 100644 sources/app/Notification/WebhookNotification.php delete mode 100644 sources/app/Schema/Mysql.php delete mode 100644 sources/app/Schema/Postgres.php delete mode 100644 sources/app/Schema/Sql/mysql.sql delete mode 100644 sources/app/Schema/Sql/postgres.sql delete mode 100644 sources/app/Schema/Sqlite.php delete mode 100644 sources/app/ServiceProvider/ActionProvider.php delete mode 100644 sources/app/ServiceProvider/ApiProvider.php delete mode 100644 sources/app/ServiceProvider/AuthenticationProvider.php delete mode 100644 sources/app/ServiceProvider/AvatarProvider.php delete mode 100644 sources/app/ServiceProvider/ClassProvider.php delete mode 100644 sources/app/ServiceProvider/CommandProvider.php delete mode 100644 sources/app/ServiceProvider/DatabaseProvider.php delete mode 100644 sources/app/ServiceProvider/EventDispatcherProvider.php delete mode 100644 sources/app/ServiceProvider/ExternalLinkProvider.php delete mode 100644 sources/app/ServiceProvider/FilterProvider.php delete mode 100644 sources/app/ServiceProvider/GroupProvider.php delete mode 100644 sources/app/ServiceProvider/HelperProvider.php delete mode 100644 sources/app/ServiceProvider/LoggingProvider.php delete mode 100644 sources/app/ServiceProvider/MailProvider.php delete mode 100644 sources/app/ServiceProvider/NotificationProvider.php delete mode 100644 sources/app/ServiceProvider/PluginProvider.php delete mode 100644 sources/app/ServiceProvider/QueueProvider.php delete mode 100644 sources/app/ServiceProvider/RouteProvider.php delete mode 100644 sources/app/ServiceProvider/SessionProvider.php delete mode 100644 sources/app/Subscriber/AuthSubscriber.php delete mode 100644 sources/app/Subscriber/BaseSubscriber.php delete mode 100644 sources/app/Subscriber/BootstrapSubscriber.php delete mode 100644 sources/app/Subscriber/LdapUserPhotoSubscriber.php delete mode 100644 sources/app/Subscriber/NotificationSubscriber.php delete mode 100644 sources/app/Subscriber/ProjectDailySummarySubscriber.php delete mode 100644 sources/app/Subscriber/ProjectModificationDateSubscriber.php delete mode 100644 sources/app/Subscriber/RecurringTaskSubscriber.php delete mode 100644 sources/app/Subscriber/SubtaskTimeTrackingSubscriber.php delete mode 100644 sources/app/Subscriber/TransitionSubscriber.php delete mode 100644 sources/app/Template/action/index.php delete mode 100644 sources/app/Template/action/remove.php delete mode 100644 sources/app/Template/action_creation/create.php delete mode 100644 sources/app/Template/action_creation/event.php delete mode 100644 sources/app/Template/action_creation/params.php delete mode 100644 sources/app/Template/activity/filter_dropdown.php delete mode 100644 sources/app/Template/activity/project.php delete mode 100644 sources/app/Template/activity/task.php delete mode 100644 sources/app/Template/analytic/avg_time_columns.php delete mode 100644 sources/app/Template/analytic/burndown.php delete mode 100644 sources/app/Template/analytic/cfd.php delete mode 100644 sources/app/Template/analytic/compare_hours.php delete mode 100644 sources/app/Template/analytic/layout.php delete mode 100644 sources/app/Template/analytic/lead_cycle_time.php delete mode 100644 sources/app/Template/analytic/sidebar.php delete mode 100644 sources/app/Template/analytic/tasks.php delete mode 100644 sources/app/Template/analytic/users.php delete mode 100644 sources/app/Template/app/filters_helper.php delete mode 100644 sources/app/Template/app/forbidden.php delete mode 100644 sources/app/Template/app/notfound.php delete mode 100644 sources/app/Template/auth/index.php delete mode 100644 sources/app/Template/avatar_file/show.php delete mode 100644 sources/app/Template/board/table_column.php delete mode 100644 sources/app/Template/board/table_container.php delete mode 100644 sources/app/Template/board/table_swimlane.php delete mode 100644 sources/app/Template/board/table_tasks.php delete mode 100644 sources/app/Template/board/task_avatar.php delete mode 100644 sources/app/Template/board/task_footer.php delete mode 100644 sources/app/Template/board/task_private.php delete mode 100644 sources/app/Template/board/task_public.php delete mode 100644 sources/app/Template/board/tooltip_comments.php delete mode 100644 sources/app/Template/board/tooltip_description.php delete mode 100644 sources/app/Template/board/tooltip_external_links.php delete mode 100644 sources/app/Template/board/tooltip_files.php delete mode 100644 sources/app/Template/board/tooltip_subtasks.php delete mode 100644 sources/app/Template/board/tooltip_tasklinks.php delete mode 100644 sources/app/Template/board/view_private.php delete mode 100644 sources/app/Template/board/view_public.php delete mode 100644 sources/app/Template/board_popover/close_all_tasks_column.php delete mode 100644 sources/app/Template/calendar/show.php delete mode 100644 sources/app/Template/category/edit.php delete mode 100644 sources/app/Template/category/index.php delete mode 100644 sources/app/Template/category/remove.php delete mode 100644 sources/app/Template/column/create.php delete mode 100644 sources/app/Template/column/edit.php delete mode 100644 sources/app/Template/column/index.php delete mode 100644 sources/app/Template/column/remove.php delete mode 100644 sources/app/Template/comment/create.php delete mode 100644 sources/app/Template/comment/edit.php delete mode 100644 sources/app/Template/comment/remove.php delete mode 100644 sources/app/Template/comment/show.php delete mode 100644 sources/app/Template/comments/create.php delete mode 100644 sources/app/Template/comments/show.php delete mode 100644 sources/app/Template/config/about.php delete mode 100644 sources/app/Template/config/api.php delete mode 100644 sources/app/Template/config/application.php delete mode 100644 sources/app/Template/config/board.php delete mode 100644 sources/app/Template/config/calendar.php delete mode 100644 sources/app/Template/config/email.php delete mode 100644 sources/app/Template/config/integrations.php delete mode 100644 sources/app/Template/config/keyboard_shortcuts.php delete mode 100644 sources/app/Template/config/layout.php delete mode 100644 sources/app/Template/config/project.php delete mode 100644 sources/app/Template/config/sidebar.php delete mode 100644 sources/app/Template/config/webhook.php delete mode 100644 sources/app/Template/currency/index.php delete mode 100644 sources/app/Template/custom_filter/add.php delete mode 100644 sources/app/Template/custom_filter/edit.php delete mode 100644 sources/app/Template/custom_filter/index.php delete mode 100644 sources/app/Template/custom_filter/remove.php delete mode 100644 sources/app/Template/dashboard/activity.php delete mode 100644 sources/app/Template/dashboard/calendar.php delete mode 100644 sources/app/Template/dashboard/layout.php delete mode 100644 sources/app/Template/dashboard/notifications.php delete mode 100644 sources/app/Template/dashboard/projects.php delete mode 100644 sources/app/Template/dashboard/show.php delete mode 100644 sources/app/Template/dashboard/sidebar.php delete mode 100644 sources/app/Template/dashboard/subtasks.php delete mode 100644 sources/app/Template/dashboard/tasks.php delete mode 100644 sources/app/Template/doc/show.php delete mode 100644 sources/app/Template/event/comment_create.php delete mode 100644 sources/app/Template/event/comment_update.php delete mode 100644 sources/app/Template/event/events.php delete mode 100644 sources/app/Template/event/subtask_create.php delete mode 100644 sources/app/Template/event/subtask_update.php delete mode 100644 sources/app/Template/event/task_assignee_change.php delete mode 100644 sources/app/Template/event/task_close.php delete mode 100644 sources/app/Template/event/task_create.php delete mode 100644 sources/app/Template/event/task_file_create.php delete mode 100644 sources/app/Template/event/task_move_column.php delete mode 100644 sources/app/Template/event/task_move_position.php delete mode 100644 sources/app/Template/event/task_move_swimlane.php delete mode 100644 sources/app/Template/event/task_open.php delete mode 100644 sources/app/Template/event/task_update.php delete mode 100644 sources/app/Template/export/sidebar.php delete mode 100644 sources/app/Template/export/subtasks.php delete mode 100644 sources/app/Template/export/summary.php delete mode 100644 sources/app/Template/export/tasks.php delete mode 100644 sources/app/Template/export/transitions.php delete mode 100644 sources/app/Template/feed/project.php delete mode 100644 sources/app/Template/feed/user.php delete mode 100644 sources/app/Template/file_viewer/show.php delete mode 100644 sources/app/Template/group/associate.php delete mode 100644 sources/app/Template/group/dissociate.php delete mode 100644 sources/app/Template/group/index.php delete mode 100644 sources/app/Template/group/remove.php delete mode 100644 sources/app/Template/group/users.php delete mode 100644 sources/app/Template/group_creation/show.php delete mode 100644 sources/app/Template/group_modification/show.php delete mode 100644 sources/app/Template/header.php delete mode 100644 sources/app/Template/layout.php delete mode 100644 sources/app/Template/link/create.php delete mode 100644 sources/app/Template/link/edit.php delete mode 100644 sources/app/Template/link/index.php delete mode 100644 sources/app/Template/link/remove.php delete mode 100644 sources/app/Template/notification/comment_create.php delete mode 100644 sources/app/Template/notification/comment_update.php delete mode 100644 sources/app/Template/notification/comment_user_mention.php delete mode 100644 sources/app/Template/notification/footer.php delete mode 100644 sources/app/Template/notification/subtask_create.php delete mode 100644 sources/app/Template/notification/subtask_update.php delete mode 100644 sources/app/Template/notification/task_assignee_change.php delete mode 100644 sources/app/Template/notification/task_close.php delete mode 100644 sources/app/Template/notification/task_create.php delete mode 100644 sources/app/Template/notification/task_file_create.php delete mode 100644 sources/app/Template/notification/task_move_column.php delete mode 100644 sources/app/Template/notification/task_move_position.php delete mode 100644 sources/app/Template/notification/task_move_swimlane.php delete mode 100644 sources/app/Template/notification/task_open.php delete mode 100644 sources/app/Template/notification/task_overdue.php delete mode 100644 sources/app/Template/notification/task_update.php delete mode 100644 sources/app/Template/notification/task_user_mention.php delete mode 100644 sources/app/Template/password_reset/change.php delete mode 100644 sources/app/Template/password_reset/create.php delete mode 100644 sources/app/Template/password_reset/email.php delete mode 100644 sources/app/Template/plugin/directory.php delete mode 100644 sources/app/Template/plugin/layout.php delete mode 100644 sources/app/Template/plugin/remove.php delete mode 100644 sources/app/Template/plugin/show.php delete mode 100644 sources/app/Template/plugin/sidebar.php delete mode 100644 sources/app/Template/project/dropdown.php delete mode 100644 sources/app/Template/project/layout.php delete mode 100644 sources/app/Template/project/sidebar.php delete mode 100644 sources/app/Template/project_action_duplication/show.php delete mode 100644 sources/app/Template/project_creation/create.php delete mode 100644 sources/app/Template/project_edit/dates.php delete mode 100644 sources/app/Template/project_edit/description.php delete mode 100644 sources/app/Template/project_edit/general.php delete mode 100644 sources/app/Template/project_edit/task_priority.php delete mode 100644 sources/app/Template/project_file/create.php delete mode 100644 sources/app/Template/project_file/remove.php delete mode 100644 sources/app/Template/project_gantt/show.php delete mode 100644 sources/app/Template/project_header/dropdown.php delete mode 100644 sources/app/Template/project_header/header.php delete mode 100644 sources/app/Template/project_header/search.php delete mode 100644 sources/app/Template/project_header/views.php delete mode 100644 sources/app/Template/project_list/show.php delete mode 100644 sources/app/Template/project_overview/activity.php delete mode 100644 sources/app/Template/project_overview/attachments.php delete mode 100644 sources/app/Template/project_overview/columns.php delete mode 100644 sources/app/Template/project_overview/description.php delete mode 100644 sources/app/Template/project_overview/files.php delete mode 100644 sources/app/Template/project_overview/images.php delete mode 100644 sources/app/Template/project_overview/information.php delete mode 100644 sources/app/Template/project_overview/show.php delete mode 100644 sources/app/Template/project_permission/index.php delete mode 100644 sources/app/Template/project_status/disable.php delete mode 100644 sources/app/Template/project_status/enable.php delete mode 100644 sources/app/Template/project_status/remove.php delete mode 100644 sources/app/Template/project_tag/create.php delete mode 100644 sources/app/Template/project_tag/edit.php delete mode 100644 sources/app/Template/project_tag/index.php delete mode 100644 sources/app/Template/project_tag/remove.php delete mode 100644 sources/app/Template/project_user_overview/layout.php delete mode 100644 sources/app/Template/project_user_overview/roles.php delete mode 100644 sources/app/Template/project_user_overview/sidebar.php delete mode 100644 sources/app/Template/project_user_overview/tasks.php delete mode 100644 sources/app/Template/project_user_overview/tooltip_users.php delete mode 100644 sources/app/Template/project_view/duplicate.php delete mode 100644 sources/app/Template/project_view/integrations.php delete mode 100644 sources/app/Template/project_view/notifications.php delete mode 100644 sources/app/Template/project_view/share.php delete mode 100644 sources/app/Template/project_view/show.php delete mode 100644 sources/app/Template/search/activity.php delete mode 100644 sources/app/Template/search/index.php delete mode 100644 sources/app/Template/search/results.php delete mode 100644 sources/app/Template/subtask/create.php delete mode 100644 sources/app/Template/subtask/edit.php delete mode 100644 sources/app/Template/subtask/menu.php delete mode 100644 sources/app/Template/subtask/remove.php delete mode 100644 sources/app/Template/subtask/show.php delete mode 100644 sources/app/Template/subtask/table.php delete mode 100644 sources/app/Template/subtask_converter/show.php delete mode 100644 sources/app/Template/subtask_restriction/show.php delete mode 100644 sources/app/Template/swimlane/create.php delete mode 100644 sources/app/Template/swimlane/edit.php delete mode 100644 sources/app/Template/swimlane/edit_default.php delete mode 100644 sources/app/Template/swimlane/index.php delete mode 100644 sources/app/Template/swimlane/remove.php delete mode 100644 sources/app/Template/swimlane/table.php delete mode 100644 sources/app/Template/tag/create.php delete mode 100644 sources/app/Template/tag/edit.php delete mode 100644 sources/app/Template/tag/index.php delete mode 100644 sources/app/Template/tag/remove.php delete mode 100644 sources/app/Template/task/analytics.php delete mode 100644 sources/app/Template/task/changes.php delete mode 100644 sources/app/Template/task/description.php delete mode 100644 sources/app/Template/task/details.php delete mode 100644 sources/app/Template/task/dropdown.php delete mode 100644 sources/app/Template/task/layout.php delete mode 100644 sources/app/Template/task/public.php delete mode 100644 sources/app/Template/task/show.php delete mode 100644 sources/app/Template/task/sidebar.php delete mode 100644 sources/app/Template/task/time_tracking_details.php delete mode 100644 sources/app/Template/task/time_tracking_summary.php delete mode 100644 sources/app/Template/task/transitions.php delete mode 100644 sources/app/Template/task_bulk/show.php delete mode 100644 sources/app/Template/task_creation/show.php delete mode 100644 sources/app/Template/task_duplication/copy.php delete mode 100644 sources/app/Template/task_duplication/duplicate.php delete mode 100644 sources/app/Template/task_duplication/move.php delete mode 100644 sources/app/Template/task_external_link/create.php delete mode 100644 sources/app/Template/task_external_link/edit.php delete mode 100644 sources/app/Template/task_external_link/find.php delete mode 100644 sources/app/Template/task_external_link/form.php delete mode 100644 sources/app/Template/task_external_link/remove.php delete mode 100644 sources/app/Template/task_external_link/show.php delete mode 100644 sources/app/Template/task_external_link/table.php delete mode 100644 sources/app/Template/task_file/create.php delete mode 100644 sources/app/Template/task_file/files.php delete mode 100644 sources/app/Template/task_file/images.php delete mode 100644 sources/app/Template/task_file/remove.php delete mode 100644 sources/app/Template/task_file/screenshot.php delete mode 100644 sources/app/Template/task_file/show.php delete mode 100644 sources/app/Template/task_gantt/show.php delete mode 100644 sources/app/Template/task_gantt_creation/show.php delete mode 100644 sources/app/Template/task_import/show.php delete mode 100644 sources/app/Template/task_import/sidebar.php delete mode 100644 sources/app/Template/task_internal_link/create.php delete mode 100644 sources/app/Template/task_internal_link/edit.php delete mode 100644 sources/app/Template/task_internal_link/remove.php delete mode 100644 sources/app/Template/task_internal_link/show.php delete mode 100644 sources/app/Template/task_internal_link/table.php delete mode 100644 sources/app/Template/task_list/show.php delete mode 100644 sources/app/Template/task_modification/show.php delete mode 100644 sources/app/Template/task_recurrence/edit.php delete mode 100644 sources/app/Template/task_recurrence/info.php delete mode 100644 sources/app/Template/task_status/close.php delete mode 100644 sources/app/Template/task_status/open.php delete mode 100644 sources/app/Template/task_suppression/remove.php delete mode 100644 sources/app/Template/twofactor/check.php delete mode 100644 sources/app/Template/twofactor/disable.php delete mode 100644 sources/app/Template/twofactor/index.php delete mode 100644 sources/app/Template/twofactor/show.php delete mode 100644 sources/app/Template/user_creation/local.php delete mode 100644 sources/app/Template/user_creation/remote.php delete mode 100644 sources/app/Template/user_credential/authentication.php delete mode 100644 sources/app/Template/user_credential/password.php delete mode 100644 sources/app/Template/user_import/show.php delete mode 100644 sources/app/Template/user_list/dropdown.php delete mode 100644 sources/app/Template/user_list/show.php delete mode 100644 sources/app/Template/user_modification/show.php delete mode 100644 sources/app/Template/user_status/disable.php delete mode 100644 sources/app/Template/user_status/enable.php delete mode 100644 sources/app/Template/user_status/remove.php delete mode 100644 sources/app/Template/user_view/external.php delete mode 100644 sources/app/Template/user_view/integrations.php delete mode 100644 sources/app/Template/user_view/last.php delete mode 100644 sources/app/Template/user_view/layout.php delete mode 100644 sources/app/Template/user_view/notifications.php delete mode 100644 sources/app/Template/user_view/password_reset.php delete mode 100644 sources/app/Template/user_view/profile.php delete mode 100644 sources/app/Template/user_view/sessions.php delete mode 100644 sources/app/Template/user_view/share.php delete mode 100644 sources/app/Template/user_view/show.php delete mode 100644 sources/app/Template/user_view/sidebar.php delete mode 100644 sources/app/Template/user_view/timesheet.php delete mode 100644 sources/app/User/Avatar/AvatarFileProvider.php delete mode 100644 sources/app/User/Avatar/GravatarProvider.php delete mode 100644 sources/app/User/Avatar/LetterAvatarProvider.php delete mode 100644 sources/app/User/DatabaseUserProvider.php delete mode 100644 sources/app/User/LdapUserProvider.php delete mode 100644 sources/app/User/OAuthUserProvider.php delete mode 100644 sources/app/User/ReverseProxyUserProvider.php delete mode 100644 sources/app/Validator/ActionValidator.php delete mode 100644 sources/app/Validator/AuthValidator.php delete mode 100644 sources/app/Validator/BaseValidator.php delete mode 100644 sources/app/Validator/CategoryValidator.php delete mode 100644 sources/app/Validator/ColumnValidator.php delete mode 100644 sources/app/Validator/CommentValidator.php delete mode 100644 sources/app/Validator/CurrencyValidator.php delete mode 100644 sources/app/Validator/CustomFilterValidator.php delete mode 100644 sources/app/Validator/ExternalLinkValidator.php delete mode 100644 sources/app/Validator/GroupValidator.php delete mode 100644 sources/app/Validator/LinkValidator.php delete mode 100644 sources/app/Validator/PasswordResetValidator.php delete mode 100644 sources/app/Validator/ProjectValidator.php delete mode 100644 sources/app/Validator/SubtaskValidator.php delete mode 100644 sources/app/Validator/SwimlaneValidator.php delete mode 100644 sources/app/Validator/TagValidator.php delete mode 100644 sources/app/Validator/TaskLinkValidator.php delete mode 100644 sources/app/Validator/TaskValidator.php delete mode 100644 sources/app/Validator/UserValidator.php delete mode 100644 sources/app/check_setup.php delete mode 100644 sources/app/common.php delete mode 100644 sources/app/constants.php delete mode 100644 sources/app/functions.php delete mode 100644 sources/assets/css/app.min.css delete mode 100644 sources/assets/css/chosen-sprite.png delete mode 100644 sources/assets/css/chosen-sprite@2x.png delete mode 100644 sources/assets/css/images/ui-bg_flat_0_aaaaaa_40x100.png delete mode 100644 sources/assets/css/images/ui-bg_flat_75_ffffff_40x100.png delete mode 100644 sources/assets/css/images/ui-bg_glass_55_fbf9ee_1x400.png delete mode 100644 sources/assets/css/images/ui-bg_glass_65_ffffff_1x400.png delete mode 100644 sources/assets/css/images/ui-bg_glass_75_dadada_1x400.png delete mode 100644 sources/assets/css/images/ui-bg_glass_75_e6e6e6_1x400.png delete mode 100644 sources/assets/css/images/ui-bg_glass_95_fef1ec_1x400.png delete mode 100644 sources/assets/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png delete mode 100644 sources/assets/css/images/ui-icons_222222_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_2e83ff_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_444444_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_454545_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_555555_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_777620_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_777777_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_888888_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_cc0000_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_cd0a0a_256x240.png delete mode 100644 sources/assets/css/images/ui-icons_ffffff_256x240.png delete mode 100644 sources/assets/css/print.min.css delete mode 100644 sources/assets/css/src/accordion.css delete mode 100644 sources/assets/css/src/activity.css delete mode 100644 sources/assets/css/src/alert.css delete mode 100644 sources/assets/css/src/avatar.css delete mode 100644 sources/assets/css/src/base.css delete mode 100644 sources/assets/css/src/board.css delete mode 100644 sources/assets/css/src/button.css delete mode 100644 sources/assets/css/src/comment.css delete mode 100644 sources/assets/css/src/confirm.css delete mode 100644 sources/assets/css/src/dashboard.css delete mode 100644 sources/assets/css/src/dropdown.css delete mode 100644 sources/assets/css/src/files.css delete mode 100644 sources/assets/css/src/filters.css delete mode 100644 sources/assets/css/src/form.css delete mode 100644 sources/assets/css/src/gantt.css delete mode 100644 sources/assets/css/src/header.css delete mode 100644 sources/assets/css/src/links.css delete mode 100644 sources/assets/css/src/listing.css delete mode 100644 sources/assets/css/src/markdown.css delete mode 100644 sources/assets/css/src/pagination.css delete mode 100644 sources/assets/css/src/popover.css delete mode 100644 sources/assets/css/src/print.css delete mode 100644 sources/assets/css/src/project.css delete mode 100644 sources/assets/css/src/responsive.css delete mode 100644 sources/assets/css/src/sidebar.css delete mode 100644 sources/assets/css/src/subtask.css delete mode 100644 sources/assets/css/src/table.css delete mode 100644 sources/assets/css/src/task.css delete mode 100644 sources/assets/css/src/tasklink.css delete mode 100644 sources/assets/css/src/title.css delete mode 100644 sources/assets/css/src/tooltip.css delete mode 100644 sources/assets/css/src/upload.css delete mode 100644 sources/assets/css/src/views.css delete mode 100644 sources/assets/css/vendor.min.css delete mode 100644 sources/assets/fonts/FontAwesome.otf delete mode 100644 sources/assets/fonts/fontawesome-webfont.eot delete mode 100644 sources/assets/fonts/fontawesome-webfont.svg delete mode 100644 sources/assets/fonts/fontawesome-webfont.ttf delete mode 100644 sources/assets/fonts/fontawesome-webfont.woff delete mode 100644 sources/assets/fonts/fontawesome-webfont.woff2 delete mode 100644 sources/assets/img/favicon.png delete mode 100644 sources/assets/img/gravatar-icon.png delete mode 100644 sources/assets/img/icon.svg delete mode 100644 sources/assets/img/touch-icon-ipad-retina.png delete mode 100644 sources/assets/img/touch-icon-ipad.png delete mode 100644 sources/assets/img/touch-icon-iphone-retina.png delete mode 100644 sources/assets/img/touch-icon-iphone.png delete mode 100644 sources/assets/js/app.min.js delete mode 100644 sources/assets/js/src/Accordion.js delete mode 100644 sources/assets/js/src/App.js delete mode 100644 sources/assets/js/src/AvgTimeColumnChart.js delete mode 100644 sources/assets/js/src/BoardCollapsedMode.js delete mode 100644 sources/assets/js/src/BoardColumnScrolling.js delete mode 100644 sources/assets/js/src/BoardColumnView.js delete mode 100644 sources/assets/js/src/BoardDragAndDrop.js delete mode 100644 sources/assets/js/src/BoardHorizontalScrolling.js delete mode 100644 sources/assets/js/src/BoardPolling.js delete mode 100644 sources/assets/js/src/BoardTask.js delete mode 100644 sources/assets/js/src/Bootstrap.js delete mode 100644 sources/assets/js/src/BurndownChart.js delete mode 100644 sources/assets/js/src/Calendar.js delete mode 100644 sources/assets/js/src/Column.js delete mode 100644 sources/assets/js/src/CompareHoursColumnChart.js delete mode 100644 sources/assets/js/src/CumulativeFlowDiagram.js delete mode 100644 sources/assets/js/src/Dropdown.js delete mode 100644 sources/assets/js/src/FileUpload.js delete mode 100644 sources/assets/js/src/Gantt.js delete mode 100644 sources/assets/js/src/LeadCycleTimeChart.js delete mode 100644 sources/assets/js/src/Markdown.js delete mode 100644 sources/assets/js/src/Namespace.js delete mode 100644 sources/assets/js/src/Notification.js delete mode 100644 sources/assets/js/src/Popover.js delete mode 100644 sources/assets/js/src/ProjectCreation.js delete mode 100644 sources/assets/js/src/ProjectPermission.js delete mode 100644 sources/assets/js/src/Screenshot.js delete mode 100644 sources/assets/js/src/Search.js delete mode 100644 sources/assets/js/src/Session.js delete mode 100644 sources/assets/js/src/Subtask.js delete mode 100644 sources/assets/js/src/Swimlane.js delete mode 100644 sources/assets/js/src/Task.js delete mode 100644 sources/assets/js/src/TaskRepartitionChart.js delete mode 100644 sources/assets/js/src/TaskTimeColumnChart.js delete mode 100644 sources/assets/js/src/Tooltip.js delete mode 100644 sources/assets/js/src/UserRepartitionChart.js delete mode 100644 sources/assets/js/vendor.min.js delete mode 100644 sources/config.default.php delete mode 100644 sources/data/.htaccess delete mode 100644 sources/data/web.config delete mode 100644 sources/doc/2fa.markdown delete mode 100644 sources/doc/analytics-tasks.markdown delete mode 100644 sources/doc/analytics.markdown delete mode 100644 sources/doc/api-action-procedures.markdown delete mode 100644 sources/doc/api-application-procedures.markdown delete mode 100644 sources/doc/api-authentication.markdown delete mode 100644 sources/doc/api-board-procedures.markdown delete mode 100644 sources/doc/api-category-procedures.markdown delete mode 100644 sources/doc/api-column-procedures.markdown delete mode 100644 sources/doc/api-comment-procedures.markdown delete mode 100644 sources/doc/api-examples.markdown delete mode 100644 sources/doc/api-external-task-link-procedures.markdown delete mode 100644 sources/doc/api-group-member-procedures.markdown delete mode 100644 sources/doc/api-group-procedures.markdown delete mode 100644 sources/doc/api-internal-task-link-procedures.markdown delete mode 100644 sources/doc/api-json-rpc.markdown delete mode 100644 sources/doc/api-link-procedures.markdown delete mode 100644 sources/doc/api-me-procedures.markdown delete mode 100644 sources/doc/api-project-file-procedures.markdown delete mode 100644 sources/doc/api-project-permission-procedures.markdown delete mode 100644 sources/doc/api-project-procedures.markdown delete mode 100644 sources/doc/api-subtask-procedures.markdown delete mode 100644 sources/doc/api-subtask-time-tracking-procedures.markdown delete mode 100644 sources/doc/api-swimlane-procedures.markdown delete mode 100644 sources/doc/api-task-file-procedures.markdown delete mode 100644 sources/doc/api-task-procedures.markdown delete mode 100644 sources/doc/api-user-procedures.markdown delete mode 100644 sources/doc/application-configuration.markdown delete mode 100644 sources/doc/assets.markdown delete mode 100644 sources/doc/automatic-actions.markdown delete mode 100644 sources/doc/board-collapsed-expanded.markdown delete mode 100644 sources/doc/board-configuration.markdown delete mode 100644 sources/doc/board-horizontal-scrolling-and-compact-view.markdown delete mode 100644 sources/doc/board-show-hide-columns.markdown delete mode 100644 sources/doc/bruteforce-protection.markdown delete mode 100644 sources/doc/calendar-configuration.markdown delete mode 100644 sources/doc/calendar.markdown delete mode 100644 sources/doc/centos-installation.markdown delete mode 100644 sources/doc/cli.markdown delete mode 100644 sources/doc/closing-tasks.markdown delete mode 100644 sources/doc/cloudron.markdown delete mode 100644 sources/doc/coding-standards.markdown delete mode 100644 sources/doc/config.markdown delete mode 100644 sources/doc/contributing.markdown delete mode 100644 sources/doc/create-tasks-by-email.markdown delete mode 100644 sources/doc/creating-projects.markdown delete mode 100644 sources/doc/creating-tasks.markdown delete mode 100644 sources/doc/cronjob.markdown delete mode 100644 sources/doc/currency-rate.markdown delete mode 100644 sources/doc/custom-filters.markdown delete mode 100644 sources/doc/debian-installation.markdown delete mode 100644 sources/doc/docker.markdown delete mode 100644 sources/doc/duplicate-move-tasks.markdown delete mode 100644 sources/doc/editing-projects.markdown delete mode 100644 sources/doc/email-configuration.markdown delete mode 100644 sources/doc/env.markdown delete mode 100644 sources/doc/es_ES/calendar-configuration.markdown delete mode 100644 sources/doc/es_ES/email-configuration.markdown delete mode 100644 sources/doc/es_ES/kanban-vs-todo-and-scrum.markdown delete mode 100644 sources/doc/faq.markdown delete mode 100644 sources/doc/fr_FR/2fa.markdown delete mode 100644 sources/doc/fr_FR/analytics-tasks.markdown delete mode 100644 sources/doc/fr_FR/analytics.markdown delete mode 100644 sources/doc/fr_FR/application-configuration.markdown delete mode 100644 sources/doc/fr_FR/application-configuration.markup delete mode 100644 sources/doc/fr_FR/automatic-actions.markdown delete mode 100644 sources/doc/fr_FR/board-collapsed-expanded.markdown delete mode 100644 sources/doc/fr_FR/board-configuration.markdown delete mode 100644 sources/doc/fr_FR/board-horizontal-scrolling-and-compact-view.markdown delete mode 100644 sources/doc/fr_FR/board-show-hide-columns.markdown delete mode 100644 sources/doc/fr_FR/calendar-configuration.markdown delete mode 100644 sources/doc/fr_FR/calendar.markdown delete mode 100644 sources/doc/fr_FR/closing-tasks.markdown delete mode 100644 sources/doc/fr_FR/create-tasks-by-email.markdown delete mode 100644 sources/doc/fr_FR/creating-projects.markdown delete mode 100644 sources/doc/fr_FR/creating-tasks.markdown delete mode 100644 sources/doc/fr_FR/currency-rate.markdown delete mode 100644 sources/doc/fr_FR/duplicate-move-tasks.markdown delete mode 100644 sources/doc/fr_FR/editing-projects.markdown delete mode 100644 sources/doc/fr_FR/gantt-chart-projects.markdown delete mode 100644 sources/doc/fr_FR/gantt-chart-tasks.markdown delete mode 100644 sources/doc/fr_FR/index.markdown delete mode 100644 sources/doc/fr_FR/kanban-vs-todo-and-scrum.markdown delete mode 100644 sources/doc/fr_FR/keyboard-shortcuts.markdown delete mode 100644 sources/doc/fr_FR/link-labels.markdown delete mode 100644 sources/doc/fr_FR/notifications.markdown delete mode 100644 sources/doc/fr_FR/project-configuration.markdown delete mode 100644 sources/doc/fr_FR/project-permissions.markdown delete mode 100644 sources/doc/fr_FR/project-types.markdown delete mode 100644 sources/doc/fr_FR/project-views.markdown delete mode 100644 sources/doc/fr_FR/recurring-tasks.markdown delete mode 100644 sources/doc/fr_FR/removing-projects.markdown delete mode 100644 sources/doc/fr_FR/roles.markdown delete mode 100644 sources/doc/fr_FR/screenshots.markdown delete mode 100644 sources/doc/fr_FR/screenshots/automatic-action-creation.png delete mode 100644 sources/doc/fr_FR/screenshots/board-collapsed-mode.png delete mode 100644 sources/doc/fr_FR/screenshots/board-compact-mode.png delete mode 100644 sources/doc/fr_FR/screenshots/board-expanded-mode.png delete mode 100644 sources/doc/fr_FR/screenshots/board-task-limit.png delete mode 100644 sources/doc/fr_FR/screenshots/board-view.png delete mode 100644 sources/doc/fr_FR/screenshots/calendar-view.png delete mode 100644 sources/doc/fr_FR/screenshots/gantt-view.png delete mode 100644 sources/doc/fr_FR/screenshots/hide-column.png delete mode 100644 sources/doc/fr_FR/screenshots/list-view.png delete mode 100644 sources/doc/fr_FR/screenshots/new-project.png delete mode 100644 sources/doc/fr_FR/screenshots/new-user.png delete mode 100644 sources/doc/fr_FR/screenshots/project-disable-sharing.png delete mode 100644 sources/doc/fr_FR/screenshots/project-edition.png delete mode 100644 sources/doc/fr_FR/screenshots/project-enable-sharing.png delete mode 100644 sources/doc/fr_FR/screenshots/project-permissions.png delete mode 100644 sources/doc/fr_FR/screenshots/project-view.png delete mode 100644 sources/doc/fr_FR/screenshots/show-column.png delete mode 100644 sources/doc/fr_FR/screenshots/swimlane-configuration.png delete mode 100644 sources/doc/fr_FR/screenshots/swimlanes.png delete mode 100644 sources/doc/fr_FR/screenshots/task-creation-board.png delete mode 100644 sources/doc/fr_FR/screenshots/task-creation-form.png delete mode 100644 sources/doc/fr_FR/sharing-projects.markdown delete mode 100644 sources/doc/fr_FR/subtasks.markdown delete mode 100644 sources/doc/fr_FR/swimlanes.markdown delete mode 100644 sources/doc/fr_FR/task-links.markdown delete mode 100644 sources/doc/fr_FR/time-tracking.markdown delete mode 100644 sources/doc/fr_FR/transitions.markdown delete mode 100644 sources/doc/fr_FR/usage-examples.markdown delete mode 100644 sources/doc/fr_FR/user-management.markdown delete mode 100644 sources/doc/fr_FR/what-is-kanban.markdown delete mode 100644 sources/doc/freebsd-installation.markdown delete mode 100644 sources/doc/gantt-chart-projects.markdown delete mode 100644 sources/doc/gantt-chart-tasks.markdown delete mode 100644 sources/doc/groups.markdown delete mode 100644 sources/doc/heroku.markdown delete mode 100644 sources/doc/ical.markdown delete mode 100644 sources/doc/index.markdown delete mode 100644 sources/doc/installation.markdown delete mode 100644 sources/doc/kanban-vs-todo-and-scrum.markdown delete mode 100644 sources/doc/keyboard-shortcuts.markdown delete mode 100644 sources/doc/ldap-authentication.markdown delete mode 100644 sources/doc/ldap-configuration-examples.markdown delete mode 100644 sources/doc/ldap-group-sync.markdown delete mode 100644 sources/doc/ldap-parameters.markdown delete mode 100644 sources/doc/ldap-profile-picture.markdown delete mode 100644 sources/doc/link-labels.markdown delete mode 100644 sources/doc/mysql-configuration.markdown delete mode 100644 sources/doc/nice-urls.markdown delete mode 100644 sources/doc/nitrous.markdown delete mode 100644 sources/doc/notifications.markdown delete mode 100644 sources/doc/performances.markdown delete mode 100644 sources/doc/plugin-authentication-architecture.markdown delete mode 100644 sources/doc/plugin-authentication.markdown delete mode 100644 sources/doc/plugin-authorization-architecture.markdown delete mode 100644 sources/doc/plugin-automatic-actions.markdown delete mode 100644 sources/doc/plugin-avatar-provider.markdown delete mode 100644 sources/doc/plugin-directory.markdown delete mode 100644 sources/doc/plugin-events.markdown delete mode 100644 sources/doc/plugin-external-link.markdown delete mode 100644 sources/doc/plugin-group-provider.markdown delete mode 100644 sources/doc/plugin-helpers.markdown delete mode 100644 sources/doc/plugin-hooks.markdown delete mode 100644 sources/doc/plugin-ldap-client.markdown delete mode 100644 sources/doc/plugin-mail-transports.markdown delete mode 100644 sources/doc/plugin-metadata.markdown delete mode 100644 sources/doc/plugin-notifications.markdown delete mode 100644 sources/doc/plugin-overrides.markdown delete mode 100644 sources/doc/plugin-registration.markdown delete mode 100644 sources/doc/plugin-routes.markdown delete mode 100644 sources/doc/plugin-schema-migrations.markdown delete mode 100644 sources/doc/plugins.markdown delete mode 100644 sources/doc/postgresql-configuration.markdown delete mode 100644 sources/doc/project-configuration.markdown delete mode 100644 sources/doc/project-permissions.markdown delete mode 100644 sources/doc/project-types.markdown delete mode 100644 sources/doc/project-views.markdown delete mode 100644 sources/doc/recurring-tasks.markdown delete mode 100644 sources/doc/removing-projects.markdown delete mode 100644 sources/doc/requirements.markdown delete mode 100644 sources/doc/reverse-proxy-authentication.markdown delete mode 100644 sources/doc/roles.markdown delete mode 100644 sources/doc/rss.markdown delete mode 100644 sources/doc/screenshots.markdown delete mode 100644 sources/doc/screenshots/automatic-action-creation.png delete mode 100644 sources/doc/screenshots/board-collapsed-mode.png delete mode 100644 sources/doc/screenshots/board-compact-mode.png delete mode 100644 sources/doc/screenshots/board-expanded-mode.png delete mode 100644 sources/doc/screenshots/board-task-limit.png delete mode 100644 sources/doc/screenshots/board-view.png delete mode 100644 sources/doc/screenshots/calendar-view.png delete mode 100644 sources/doc/screenshots/gantt-view.png delete mode 100644 sources/doc/screenshots/groups-management.png delete mode 100644 sources/doc/screenshots/hide-column.png delete mode 100644 sources/doc/screenshots/list-view.png delete mode 100644 sources/doc/screenshots/mention-autocomplete.png delete mode 100644 sources/doc/screenshots/new-project.png delete mode 100644 sources/doc/screenshots/new-user.png delete mode 100644 sources/doc/screenshots/project-disable-sharing.png delete mode 100644 sources/doc/screenshots/project-edition.png delete mode 100644 sources/doc/screenshots/project-enable-sharing.png delete mode 100644 sources/doc/screenshots/project-permissions.png delete mode 100644 sources/doc/screenshots/project-remove.png delete mode 100644 sources/doc/screenshots/project-view.png delete mode 100644 sources/doc/screenshots/show-column.png delete mode 100644 sources/doc/screenshots/swimlane-configuration.png delete mode 100644 sources/doc/screenshots/swimlanes.png delete mode 100644 sources/doc/screenshots/tags-board.png delete mode 100644 sources/doc/screenshots/tags-global.png delete mode 100644 sources/doc/screenshots/tags-projects.png delete mode 100644 sources/doc/screenshots/tags-search.png delete mode 100644 sources/doc/screenshots/tags-task.png delete mode 100644 sources/doc/screenshots/task-creation-board.png delete mode 100644 sources/doc/screenshots/task-creation-form.png delete mode 100644 sources/doc/search.markdown delete mode 100644 sources/doc/sharing-projects.markdown delete mode 100644 sources/doc/sqlite-database.markdown delete mode 100644 sources/doc/subtasks.markdown delete mode 100644 sources/doc/suse-installation.markdown delete mode 100644 sources/doc/swimlanes.markdown delete mode 100644 sources/doc/syntax-guide.markdown delete mode 100644 sources/doc/tags.markdown delete mode 100644 sources/doc/task-links.markdown delete mode 100644 sources/doc/tests.markdown delete mode 100644 sources/doc/time-tracking.markdown delete mode 100644 sources/doc/transitions.markdown delete mode 100644 sources/doc/translations.markdown delete mode 100644 sources/doc/ubuntu-installation.markdown delete mode 100644 sources/doc/update.markdown delete mode 100644 sources/doc/usage-examples.markdown delete mode 100644 sources/doc/user-management.markdown delete mode 100644 sources/doc/user-mentions.markdown delete mode 100644 sources/doc/user-types.markdown delete mode 100644 sources/doc/vagrant.markdown delete mode 100644 sources/doc/webhooks.markdown delete mode 100644 sources/doc/what-is-kanban.markdown delete mode 100644 sources/doc/windows-apache-installation.markdown delete mode 100644 sources/doc/windows-iis-installation.markdown delete mode 100644 sources/doc/worker.markdown delete mode 100644 sources/favicon.ico delete mode 100644 sources/index.php delete mode 100644 sources/jsonrpc.php delete mode 100755 sources/kanboard delete mode 100644 sources/robots.txt create mode 120000 sources/vendor/bin/picofeed create mode 100644 sources/vendor/christian-riesen/base32/.gitignore create mode 100644 sources/vendor/christian-riesen/base32/.travis.yml create mode 100644 sources/vendor/christian-riesen/base32/README.md create mode 100644 sources/vendor/christian-riesen/base32/composer.json create mode 100644 sources/vendor/christian-riesen/base32/tests/Base32Test.php create mode 100644 sources/vendor/christian-riesen/base32/tests/bootstrap.php create mode 100644 sources/vendor/christian-riesen/otp/.gitignore create mode 100644 sources/vendor/christian-riesen/otp/.travis.yml create mode 100644 sources/vendor/christian-riesen/otp/README.md create mode 100644 sources/vendor/christian-riesen/otp/composer.json create mode 100644 sources/vendor/christian-riesen/otp/tests/Otp/GoogleAuthenticatorTest.php create mode 100644 sources/vendor/christian-riesen/otp/tests/Otp/OtpTest.php create mode 100644 sources/vendor/eluceo/ical/.gitignore create mode 100644 sources/vendor/eluceo/ical/.travis.yml create mode 100644 sources/vendor/eluceo/ical/README.md create mode 100644 sources/vendor/eluceo/ical/composer.json create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/Component/CalendarIntegrationTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/ComponentTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/ParameterBagTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/Property/ArrayValueTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/Property/Event/DescriptionTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/Property/Event/OrganizerTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/Property/Event/RecurrenceRuleTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/Property/StringValueTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/PropertyBagTest.php create mode 100644 sources/vendor/eluceo/ical/tests/Eluceo/iCal/PropertyTest.php create mode 100644 sources/vendor/erusev/parsedown/.travis.yml create mode 100644 sources/vendor/erusev/parsedown/README.md create mode 100644 sources/vendor/erusev/parsedown/composer.json create mode 100644 sources/vendor/erusev/parsedown/test/CommonMarkTest.php create mode 100644 sources/vendor/erusev/parsedown/test/ParsedownTest.php create mode 100644 sources/vendor/erusev/parsedown/test/TestParsedown.php create mode 100644 sources/vendor/erusev/parsedown/test/bootstrap.php create mode 100644 sources/vendor/erusev/parsedown/test/data/aesthetic_table.html create mode 100644 sources/vendor/erusev/parsedown/test/data/aesthetic_table.md create mode 100644 sources/vendor/erusev/parsedown/test/data/aligned_table.html create mode 100644 sources/vendor/erusev/parsedown/test/data/aligned_table.md create mode 100644 sources/vendor/erusev/parsedown/test/data/atx_heading.html create mode 100644 sources/vendor/erusev/parsedown/test/data/atx_heading.md create mode 100644 sources/vendor/erusev/parsedown/test/data/automatic_link.html create mode 100644 sources/vendor/erusev/parsedown/test/data/automatic_link.md create mode 100644 sources/vendor/erusev/parsedown/test/data/block-level_html.html create mode 100644 sources/vendor/erusev/parsedown/test/data/block-level_html.md create mode 100644 sources/vendor/erusev/parsedown/test/data/code_block.html create mode 100644 sources/vendor/erusev/parsedown/test/data/code_block.md create mode 100644 sources/vendor/erusev/parsedown/test/data/code_span.html create mode 100644 sources/vendor/erusev/parsedown/test/data/code_span.md create mode 100644 sources/vendor/erusev/parsedown/test/data/compound_blockquote.html create mode 100644 sources/vendor/erusev/parsedown/test/data/compound_blockquote.md create mode 100644 sources/vendor/erusev/parsedown/test/data/compound_emphasis.html create mode 100644 sources/vendor/erusev/parsedown/test/data/compound_emphasis.md create mode 100644 sources/vendor/erusev/parsedown/test/data/compound_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/compound_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/deeply_nested_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/deeply_nested_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/em_strong.html create mode 100644 sources/vendor/erusev/parsedown/test/data/em_strong.md create mode 100644 sources/vendor/erusev/parsedown/test/data/email.html create mode 100644 sources/vendor/erusev/parsedown/test/data/email.md create mode 100644 sources/vendor/erusev/parsedown/test/data/emphasis.html create mode 100644 sources/vendor/erusev/parsedown/test/data/emphasis.md create mode 100644 sources/vendor/erusev/parsedown/test/data/escaping.html create mode 100644 sources/vendor/erusev/parsedown/test/data/escaping.md create mode 100644 sources/vendor/erusev/parsedown/test/data/fenced_code_block.html create mode 100644 sources/vendor/erusev/parsedown/test/data/fenced_code_block.md create mode 100644 sources/vendor/erusev/parsedown/test/data/horizontal_rule.html create mode 100644 sources/vendor/erusev/parsedown/test/data/horizontal_rule.md create mode 100644 sources/vendor/erusev/parsedown/test/data/html_comment.html create mode 100644 sources/vendor/erusev/parsedown/test/data/html_comment.md create mode 100644 sources/vendor/erusev/parsedown/test/data/html_entity.html create mode 100644 sources/vendor/erusev/parsedown/test/data/html_entity.md create mode 100644 sources/vendor/erusev/parsedown/test/data/image_reference.html create mode 100644 sources/vendor/erusev/parsedown/test/data/image_reference.md create mode 100644 sources/vendor/erusev/parsedown/test/data/image_title.html create mode 100644 sources/vendor/erusev/parsedown/test/data/image_title.md create mode 100644 sources/vendor/erusev/parsedown/test/data/implicit_reference.html create mode 100644 sources/vendor/erusev/parsedown/test/data/implicit_reference.md create mode 100644 sources/vendor/erusev/parsedown/test/data/inline_link.html create mode 100644 sources/vendor/erusev/parsedown/test/data/inline_link.md create mode 100644 sources/vendor/erusev/parsedown/test/data/inline_link_title.html create mode 100644 sources/vendor/erusev/parsedown/test/data/inline_link_title.md create mode 100644 sources/vendor/erusev/parsedown/test/data/inline_title.html create mode 100644 sources/vendor/erusev/parsedown/test/data/inline_title.md create mode 100644 sources/vendor/erusev/parsedown/test/data/lazy_blockquote.html create mode 100644 sources/vendor/erusev/parsedown/test/data/lazy_blockquote.md create mode 100644 sources/vendor/erusev/parsedown/test/data/lazy_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/lazy_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/line_break.html create mode 100644 sources/vendor/erusev/parsedown/test/data/line_break.md create mode 100644 sources/vendor/erusev/parsedown/test/data/multiline_list_paragraph.html create mode 100644 sources/vendor/erusev/parsedown/test/data/multiline_list_paragraph.md create mode 100644 sources/vendor/erusev/parsedown/test/data/nested_block-level_html.html create mode 100644 sources/vendor/erusev/parsedown/test/data/nested_block-level_html.md create mode 100644 sources/vendor/erusev/parsedown/test/data/ordered_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/ordered_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/paragraph_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/paragraph_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/reference_title.html create mode 100644 sources/vendor/erusev/parsedown/test/data/reference_title.md create mode 100644 sources/vendor/erusev/parsedown/test/data/self-closing_html.html create mode 100644 sources/vendor/erusev/parsedown/test/data/self-closing_html.md create mode 100644 sources/vendor/erusev/parsedown/test/data/separated_nested_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/separated_nested_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/setext_header.html create mode 100644 sources/vendor/erusev/parsedown/test/data/setext_header.md create mode 100644 sources/vendor/erusev/parsedown/test/data/simple_blockquote.html create mode 100644 sources/vendor/erusev/parsedown/test/data/simple_blockquote.md create mode 100644 sources/vendor/erusev/parsedown/test/data/simple_table.html create mode 100644 sources/vendor/erusev/parsedown/test/data/simple_table.md create mode 100644 sources/vendor/erusev/parsedown/test/data/span-level_html.html create mode 100644 sources/vendor/erusev/parsedown/test/data/span-level_html.md create mode 100644 sources/vendor/erusev/parsedown/test/data/sparse_dense_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/sparse_dense_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/sparse_html.html create mode 100644 sources/vendor/erusev/parsedown/test/data/sparse_html.md create mode 100644 sources/vendor/erusev/parsedown/test/data/sparse_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/sparse_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/special_characters.html create mode 100644 sources/vendor/erusev/parsedown/test/data/special_characters.md create mode 100644 sources/vendor/erusev/parsedown/test/data/strikethrough.html create mode 100644 sources/vendor/erusev/parsedown/test/data/strikethrough.md create mode 100644 sources/vendor/erusev/parsedown/test/data/strong_em.html create mode 100644 sources/vendor/erusev/parsedown/test/data/strong_em.md create mode 100644 sources/vendor/erusev/parsedown/test/data/tab-indented_code_block.html create mode 100644 sources/vendor/erusev/parsedown/test/data/tab-indented_code_block.md create mode 100644 sources/vendor/erusev/parsedown/test/data/table_inline_markdown.html create mode 100644 sources/vendor/erusev/parsedown/test/data/table_inline_markdown.md create mode 100644 sources/vendor/erusev/parsedown/test/data/text_reference.html create mode 100644 sources/vendor/erusev/parsedown/test/data/text_reference.md create mode 100644 sources/vendor/erusev/parsedown/test/data/unordered_list.html create mode 100644 sources/vendor/erusev/parsedown/test/data/unordered_list.md create mode 100644 sources/vendor/erusev/parsedown/test/data/untidy_table.html create mode 100644 sources/vendor/erusev/parsedown/test/data/untidy_table.md create mode 100644 sources/vendor/erusev/parsedown/test/data/url_autolinking.html create mode 100644 sources/vendor/erusev/parsedown/test/data/url_autolinking.md create mode 100644 sources/vendor/erusev/parsedown/test/data/whitespace.html create mode 100644 sources/vendor/erusev/parsedown/test/data/whitespace.md create mode 100644 sources/vendor/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php rename sources/{ => vendor/fguillot/picofeed}/LICENSE (96%) create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Base.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/ClientException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/Curl.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/ForbiddenException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/HttpHeaders.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/InvalidCertificateException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/InvalidUrlException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/MaxRedirectException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/MaxSizeException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/Stream.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/TimeoutException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/UnauthorizedException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Client/Url.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Encoding/Encoding.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Tag.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Generator/ContentGeneratorInterface.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Generator/FileContentGenerator.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Generator/YoutubeContentGenerator.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Logging/Logger.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/DateParser.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Feed.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Item.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/MalformedXmlException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Parser.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/ParserException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/ParserInterface.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Rss10.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Rss20.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Rss91.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Rss92.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/XmlEntityException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Parser/XmlParser.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/PicoFeedException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Processor/ContentFilterProcessor.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Processor/ContentGeneratorProcessor.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Processor/ItemPostProcessor.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Processor/ItemProcessorInterface.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Processor/ScraperProcessor.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Favicon.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Reader/Reader.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Reader/ReaderException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Reader/SubscriptionNotFoundException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Reader/UnsupportedFeedFormatException.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.blog.lemonde.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.blogs.nytimes.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.igen.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.nytimes.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.over-blog.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.phoronix.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.slate.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.theguardian.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.wikipedia.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.wired.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/.wsj.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/01net.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/abstrusegoose.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/alainonline.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/aljazeera.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/allafrica.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/allgemeine-zeitung.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/amazingsuperpowers.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/anythingcomic.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/ap.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/areadvd.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/arstechnica.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/awkwardzombie.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/bangkokpost.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/bgr.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/bigfootjustice.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/bizjournals.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/blog.fefe.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/blog.mapillary.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/buenosairesherald.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/bunicomic.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/buttersafe.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/cad-comic.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/chaoslife.findchaos.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/cliquerefresh.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/cnet.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/consomac.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/cowbirdsinlove.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/csmonitor.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/dailyjs.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/dailyreporter.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/dailytech.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/degroupnews.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/derstandard.at.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/dilbert.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/discovermagazine.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/distrowatch.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/dozodomo.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/drawingboardcomic.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/encyclopedie.naheulbeuk.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/endlessorigami.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/engadget.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/escapistmagazine.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/espn.go.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/exocomics.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/explosm.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/extrafabulouscomics.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/fastcodesign.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/fastcoexist.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/fastcompany.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/ffworld.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/foreignpolicy.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/fossbytes.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/fowllanguagecomics.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/geek.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/gerbilwithajetpack.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/giantitp.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/github.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/gocomics.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/golem.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/happletea.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/heise.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/huffingtonpost.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/imogenquest.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/ing.dk.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/invisiblebread.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/ir.amd.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/japantimes.co.jp.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/japantoday.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/journaldugeek.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/jsonline.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/kanpai.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/karriere.jobfinder.dk.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/koreaherald.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/koreatimes.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/lastplacecomics.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/lejapon.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/lesjoiesducode.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/lfg.co.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/lifehacker.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/linux.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/linuxinsider.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/lists.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/loadingartist.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/loldwell.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/lukesurl.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/macg.co.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/marc.info.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/marriedtothesea.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/marycagle.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/maximumble.thebookofbiff.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/medium.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/mercworks.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/metronieuws.nl.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/milwaukeenns.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/mlb.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/mokepon.smackjeeves.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/monwindowsphone.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/mrlovenstein.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/muckrock.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/nationaljournal.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/nature.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/nba.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/nedroid.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/networkworld.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/neustadt-ticker.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/niceteethcomic.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/nichtlustig.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/oglaf.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/onhax.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/onmilwaukee.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/opensource.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/optipess.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/osnews.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/pastebin.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/peebleslab.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/plus.google.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/popstrip.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/recode.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/satwcomic.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/securityfocus.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/sitepoint.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/slashdot.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/soundandvision.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/spiegel.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/stereophile.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/stupidfox.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/subtraction.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/sz.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/techcrunch.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/theatlantic.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/thegamercat.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/thehindu.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/thelocal.se.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/themerepublic.net.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/thenewslens.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/theonion.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/treehugger.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/treelobsters.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/twogag.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/undeadly.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/upi.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/version2.dk.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/vgcats.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/vuxml.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.bgr.in.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.cnn.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.developpez.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.forbes.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.npr.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.numerama.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.pcinpact.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.slate.fr.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/www.zeit.de.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/xkcd.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Rules/zdnet.com.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Scraper/CandidateParser.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Scraper/ParserInterface.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Scraper/RuleLoader.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Scraper/RuleParser.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Scraper/Scraper.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/Subscription.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomHelper.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php create mode 100644 sources/vendor/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php create mode 100644 sources/vendor/fguillot/picofeed/picofeed create mode 100644 sources/vendor/gregwar/captcha/.gitignore create mode 100644 sources/vendor/gregwar/captcha/.travis.yml create mode 100644 sources/vendor/gregwar/captcha/README.md create mode 100644 sources/vendor/gregwar/captcha/composer.json create mode 100644 sources/vendor/paragonie/random_compat/README.md create mode 100644 sources/vendor/paragonie/random_compat/composer.json create mode 100644 sources/vendor/pimple/pimple/.gitignore create mode 100644 sources/vendor/pimple/pimple/.travis.yml create mode 100644 sources/vendor/pimple/pimple/composer.json create mode 100644 sources/vendor/pimple/pimple/ext/pimple/.gitignore create mode 100644 sources/vendor/pimple/pimple/ext/pimple/README.md create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/001.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/002.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/003.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/004.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/005.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/006.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/007.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/008.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/009.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/010.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/011.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/012.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/013.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/014.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/015.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/016.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/017.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/018.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/019.phpt create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/bench.phpb create mode 100644 sources/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb create mode 100644 sources/vendor/psr/log/.gitignore create mode 100644 sources/vendor/psr/log/README.md create mode 100644 sources/vendor/psr/log/composer.json create mode 100644 sources/vendor/ramsey/array_column/.gitignore create mode 100644 sources/vendor/ramsey/array_column/.travis.yml create mode 100644 sources/vendor/ramsey/array_column/README.md create mode 100644 sources/vendor/ramsey/array_column/composer.json create mode 100644 sources/vendor/ramsey/array_column/tests/ArrayColumnTest.php create mode 100644 sources/vendor/ramsey/array_column/tests/bootstrap.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/.gitignore create mode 100644 sources/vendor/swiftmailer/swiftmailer/.travis.yml create mode 100644 sources/vendor/swiftmailer/swiftmailer/composer.json create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/headers.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/help-resources.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/including-the-files.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/index.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/installing.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/introduction.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/japanese.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/messages.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/overview.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/plugins.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/sending.rst create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/uml/Encoders.graffle create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/uml/Mime.graffle create mode 100644 sources/vendor/swiftmailer/swiftmailer/doc/uml/Transports.graffle create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/IdenticalBinaryConstraint.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/StreamCollector.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/SwiftMailerSmokeTestCase.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/SwiftMailerTestCase.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/charsets/iso-2022-jp/one.txt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/charsets/iso-8859-1/one.txt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/charsets/utf-8/one.txt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/charsets/utf-8/three.txt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/charsets/utf-8/two.txt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/dkim/dkim.test.priv create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/dkim/dkim.test.pub create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/files/data.txt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/files/swiftmailer.png create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/CA.srl create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/ca.crt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/ca.key create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/create-cert.sh create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/encrypt.crt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/encrypt.key create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/encrypt2.crt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/encrypt2.key create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/intermediate.crt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/intermediate.key create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/sign.crt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/sign.key create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/sign2.crt create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/_samples/smime/sign2.key create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance.conf.php.default create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/AttachmentAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/ByteStream/FileByteStreamAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/CharacterReaderFactory/SimpleCharacterReaderFactoryAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/DependencyContainerAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/EmbeddedFileAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Encoder/Base64EncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Encoder/QpEncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Encoder/Rfc2231EncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/EncodingAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/KeyCache/ArrayKeyCacheAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/KeyCache/DiskKeyCacheAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/MessageAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/AttachmentAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/ContentEncoder/Base64ContentEncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/ContentEncoder/NativeQpContentEncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/ContentEncoder/PlainContentEncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/ContentEncoder/QpContentEncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/EmbeddedFileAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/HeaderEncoder/Base64HeaderEncoderAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/MimePartAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Mime/SimpleMessageAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/MimePartAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Transport/StreamBuffer/AbstractStreamBufferAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Transport/StreamBuffer/BasicSocketAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Transport/StreamBuffer/ProcessAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Transport/StreamBuffer/SocketTimeoutTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Transport/StreamBuffer/SslSocketAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/acceptance/Swift/Transport/StreamBuffer/TlsSocketAcceptanceTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bootstrap.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug111Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug118Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug206Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug274Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug34Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug35Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug38Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug518Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug51Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug534Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug71Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/Bug76Test.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/bug/Swift/BugFileByteStreamConsecutiveReadCallsTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/fixtures/MimeEntityFixture.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/smoke.conf.php.default create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/smoke/Swift/Smoke/AttachmentSmokeTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/smoke/Swift/Smoke/BasicSmokeTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/smoke/Swift/Smoke/HtmlWithAttachmentSmokeTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/smoke/Swift/Smoke/InternationalSmokeTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/ByteStream/ArrayByteStreamTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/CharacterReader/GenericFixedWidthReaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/CharacterReader/UsAsciiReaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/CharacterReader/Utf8ReaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/CharacterStream/ArrayCharacterStreamTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/DependencyContainerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Encoder/Base64EncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Encoder/QpEncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Encoder/Rfc2231EncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Events/CommandEventTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Events/EventObjectTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Events/ResponseEventTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Events/SendEventTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Events/SimpleEventDispatcherTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Events/TransportChangeEventTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Events/TransportExceptionEventTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/KeyCache/ArrayKeyCacheTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/KeyCache/SimpleKeyCacheInputStreamTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mailer/ArrayRecipientIteratorTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/MailerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/MessageTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AbstractMimeEntityTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AttachmentTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/Base64ContentEncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/PlainContentEncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/QpContentEncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/EmbeddedFileTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/Base64HeaderEncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/QpHeaderEncoderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/DateHeaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/IdentificationHeaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/MailboxHeaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/ParameterizedHeaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/PathHeaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/UnstructuredHeaderTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/MimePartTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderFactoryTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderSetTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMessageTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMimeEntityTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/AntiFloodPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/BandwidthMonitorPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/DecoratorPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/LoggerPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/Loggers/ArrayLoggerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/Loggers/EchoLoggerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/PopBeforeSmtpPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/RedirectingPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/ReporterPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/Reporters/HitReporterTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/Reporters/HtmlReporterTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Plugins/ThrottlerPluginTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/DKIMSignerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/OpenDKIMSignerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/SMimeSignerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/StreamFilters/ByteArrayReplacementFilterTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/StreamFilters/StringReplacementFilterFactoryTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/StreamFilters/StringReplacementFilterTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/AbstractSmtpEventSupportTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/AbstractSmtpTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/Esmtp/Auth/CramMd5AuthenticatorTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/Esmtp/Auth/LoginAuthenticatorTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/Esmtp/Auth/NTLMAuthenticatorTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/Esmtp/Auth/PlainAuthenticatorTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/Esmtp/AuthHandlerTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/EsmtpTransport/ExtensionSupportTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/EsmtpTransportTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/FailoverTransportTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/LoadBalancedTransportTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/MailTransportTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/SendmailTransportTest.php create mode 100644 sources/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Transport/StreamBufferTest.php create mode 100644 sources/vendor/symfony/console/.gitignore create mode 100644 sources/vendor/symfony/console/README.md create mode 100644 sources/vendor/symfony/console/composer.json create mode 100644 sources/vendor/symfony/event-dispatcher/.gitignore create mode 100644 sources/vendor/symfony/event-dispatcher/README.md create mode 100644 sources/vendor/symfony/event-dispatcher/composer.json create mode 100644 sources/vendor/symfony/polyfill-mbstring/README.md create mode 100644 sources/vendor/symfony/polyfill-mbstring/composer.json create mode 100644 sources/vendor/zendframework/zendxml/.gitignore create mode 100644 sources/vendor/zendframework/zendxml/.travis.yml create mode 100644 sources/vendor/zendframework/zendxml/CHANGELOG.md create mode 100644 sources/vendor/zendframework/zendxml/LICENSE.md create mode 100644 sources/vendor/zendframework/zendxml/README.md create mode 100644 sources/vendor/zendframework/zendxml/composer.json create mode 100644 sources/vendor/zendframework/zendxml/library/ZendXml/Exception/ExceptionInterface.php create mode 100644 sources/vendor/zendframework/zendxml/library/ZendXml/Exception/InvalidArgumentException.php create mode 100644 sources/vendor/zendframework/zendxml/library/ZendXml/Exception/RuntimeException.php create mode 100644 sources/vendor/zendframework/zendxml/library/ZendXml/Security.php create mode 100644 sources/vendor/zendframework/zendxml/tests/Bootstrap.php create mode 100644 sources/vendor/zendframework/zendxml/tests/ZendXmlTest/MultibyteTest.php create mode 100644 sources/vendor/zendframework/zendxml/tests/ZendXmlTest/SecurityTest.php create mode 100644 sources/vendor/zendframework/zendxml/tests/phpunit.xml.dist delete mode 100644 sources/web.config diff --git a/README.markdown b/README.markdown index e1216e6..5561ca1 100644 --- a/README.markdown +++ b/README.markdown @@ -33,7 +33,7 @@ From command line: Infos ----- -Kanboard v1.0.31 +Kanboard v1.0.35 Yunohost forum thread: diff --git a/conf/config.php b/conf/config.php index 1bf41e4..d0a427f 100644 --- a/conf/config.php +++ b/conf/config.php @@ -1,5 +1,8 @@ - Options -MultiViews - - SetEnv HTTP_MOD_REWRITE On - - RewriteEngine On - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^ index.php [QSA,L] - - - - - = 2.3> - Require all denied - - - Order allow,deny - Deny from all - - - - - Order allow,deny - Deny from all - - diff --git a/sources/ChangeLog b/sources/ChangeLog deleted file mode 100644 index 7e6662d..0000000 --- a/sources/ChangeLog +++ /dev/null @@ -1,637 +0,0 @@ -Version 1.0.31 --------------- - -New features: - -* Added tags: global and specific by project -* Added application and project roles validation for API procedure calls -* Added new API call: "getProjectByIdentifier" -* Added new API calls for external task links, project attachments and subtask time tracking - -Improvements: - -* Use PHP 7 for the Docker image -* Preserve role for existing users when using ReverseProxy authentication -* Handle priority for task and project duplication -* Expose task reference field to the user interface -* Improve ICal export -* Added argument owner_id and identifier to project API calls -* Rewrite integration tests to run with Docker containers -* Use the same task form layout everywhere -* Removed some tasks dropdown menus that are now available with task edit form -* Make embedded documentation readable in multiple languages (if a translation is available) -* Added acceptance tests (browser tests) - -Bug fixes: - -* Fixed broken CSV exports -* Fixed identical background color for LetterAvatar on 32bits platforms (Hash greater than PHP_MAX_INT) -* Fixed lexer issue with non word characters -* Flush memory cache in worker to get latest config values -* Fixed empty title for web notification with only one overdue task -* Take default swimlane into consideration for SwimlaneModel::getFirstActiveSwimlane() -* Fixed "due today" highlighting - -Version 1.0.30 --------------- - -Improvements: - -* Show tasks that are due today in a different color - -Bug fixes: - -* Fixed wrong controller for search in dashboard -* Fixed plural form in alert message -* Fixed CSS cosmetic issue with popover and tooltips - -Version 1.0.29 --------------- - -New features: - -* Manage plugin from the user interface and from the command line -* Added support for background workers -* Added the possibility to convert a subtask to a task -* Added menu entry to add tasks from all project views -* Add tasks in bulk from the board -* Add dropdown for projects -* Added config parameter to allow self-signed certificates for the HTTP client - -Improvements: - -* Display local date format in date picker -* Configure email settings with the user interface in addition to config file -* Upgrade Docker image to Alpine Linux 3.4 -* Move task import to a separate section -* Mark web notification as read when clicking on it -* Support strtotime strings for date search -* Reset failed login counter and unlock user when changing password -* Task do not open anymore in a new window on the Gantt chart -* Do not display task progress for tasks with no start/end date -* Use Gulp and Bower to manage assets -* Controller and Middleware refactoring -* Replace jQuery mobile detection by the library isMobile - -Bug fixes: - -* Fixed user date format parsing for dates that can be valid in multiple formats -* Do not sync user role if LDAP groups are not configured -* Fixed issue with unicode handling for letter based avatars and user initials -* Do not send notifications to disabled users -* Fixed wrong redirect when removing a task from the task view page - -Breaking changes: - -* Webhook to create tasks have been removed, use the API instead -* All controllers have been renamed, people who are not using URL rewriting will see different URLs -* All models have been renamed, plugin maintainers will have to update their plugins - -Version 1.0.28 --------------- - -New features: - -* Added automated action to change task color based on the priority -* Added support for LDAP Posix Groups (OpenLDAP with memberUid or groupOfNames) -* Added support for LDAP user photo attribute (Avatar image) -* Added support for language LDAP attribute -* Added support for Mysql SSL connection -* Search in activity stream -* Search in comments -* Search by task creator -* Added command line utility to reset user password and to disable 2FA - -Improvements: - -* Improve Avatar upload form -* User roles are now synced with LDAP at each login -* Improve web page title on the task view -* Unify task drop-down menu between different views -* Improve LDAP user group membership synchronization -* Category and user filters do not append anymore in search field -* Added more template hooks -* Added tasks search with the API -* Added priority field to API procedures -* Added API procedure "getMemberGroups" -* Added parameters for overdue tasks notifications: group by projects and send only to managers -* Allow people to install Kanboard outside of the DocumentRoot -* Allow plugins to be loaded from another folder -* Filter/Lexer/QueryBuilder refactoring - -Bug fixes: - -* Allow a project owner to manage his own public project -* Fixed PHP warning when removing a user with no Avatar image -* Fixed improper Markdown escaping for some tooltips -* Closing all tasks by column, also update closed tasks -* Fixed wrong task link generation within Markdown text -* Fixed wrong URL on comment toggle link for sorting -* Fixed form submission with Meta+Enter keyboard shortcut -* Removed PHP notices in comment suppression view - -Version 1.0.27 --------------- - -New features: - -* Added Markdown editor -* Added user avatars with pluggable system - - Default is a letter based avatar - - Gravatar - - Avatar Image upload -* Added Korean translation - -Improvements: - -* Added more logging for LDAP client -* Improve schema migration process -* Improve notification configuration form -* Handle state in OAuth2 client -* Allow to use the original template in overridden templates -* Unification of the project header -* Refactoring of Javascript code -* Improve comments design -* Improve task summary sections -* Put back the action sidebar in task view -* Added support for multiple placeholders for LDAP_USER_FILTER -* Added local file link provider -* Show configuration in settings page -* Added "?" to display list of keyboard shortcuts -* Added new keyboard shortcuts for task view -* Always display project name and task title in task views -* Improve automatic action creation -* Move notifications to the bottom of the screen -* Added the possibility to import automatic actions from another project -* Added Ajax loading icon for submit buttons -* Added support for HTTP header "X-Forwarded-Proto: https" - -Bug fixes: - -* Fix bad unique constraints in Mysql table user_has_notifications -* Force integer type for aggregated metrics (Burndown chart concat values instead of summing) -* Fixes cycle time calculation when the start date is defined in the future -* Access allowed to any tasks from the shared public board by changing the URL parameters -* Fix invalid user filter for API procedure createLdapUser() -* Ambiguous column name with very old version of Sqlite - -Version 1.0.26 --------------- - -Breaking changes: - -* API procedures: - - "moveColumnUp" and "moveColumnDown" are replaced by "changeColumnPosition" - - "moveSwimlaneUp" and "moveSwimlaneDown" are replaced by "changeSwimlanePosition" - -New features: - -* Add drag and drop to change subtasks, swimlanes and columns positions -* Add file drag and drop and asynchronous upload -* Enable/Disable users -* Add setting option to disable private projects -* Add new config option to disable logout - -Improvements: - -* Use inline popup to create new columns -* Improve filter box design -* Improve image thumbnails and files table -* Add confirmation inline popup to remove custom filter -* Increase client_max_body_size value for Nginx -* Split Board model into multiple classes -* Improve logging for the Docker image - -Bug fixes: - -* Fix PHP notices during creation of first project and in subtasks table -* Fix filter dropdown not accessible when there are too many items -* Fix regression: unable to change project in "task move/duplicate to another project" - -Version 1.0.25 --------------- - -Breaking changes: - -* Core functionalities moved to external plugins: - - Google Auth: https://github.com/kanboard/plugin-google-auth - - Github Auth: https://github.com/kanboard/plugin-github-auth - - Gitlab Auth: https://github.com/kanboard/plugin-gitlab-auth - -New features: - -* When creating a new project, have the possibility to select another project to duplicate -* Add a "Me" button to assignee form element -* Add external links for tasks with plugin api -* Add project owner (Directly Responsible Individual) -* Add configurable task priority -* Add Greek translation -* Add automatic actions to close tasks with no activity -* Add automatic actions to send an email when there is no activity on a task -* Regroup all daily background tasks in one command: "cronjob" -* Add task dropdown menu on listing pages - -Improvements: - -* New Dockerfile based on Alpine Linux and Nginx/PHP-FPM -* The date time format can be chosen in application settings -* Export only open tasks in iCal feed -* Remove time form on task summary page and move that to task edit form -* Replace box shadow by a larger border width when a task is recently modified -* Do not refresh the whole page when changing subtask status -* Add dropdown menu with inline popup for all task actions -* Change sidebar style -* Change task summary layout -* Use inline popup for subtasks, categories, swimlanes, actions and columns -* Move homepage menus to the user dropdown -* Have a new task assigned to the creator by default instead of "no assignee" -* Show progress for task links in board tooltips -* Simplify code to handle ajax popover and redirects -* Simplify layout and templates generation -* Move task form elements to Task helper - -Bug fixes: - -* Category label is broken on the board if there's a url in the description -* Fix pagination on task time tracking page - -Version 1.0.24 --------------- - -New features: - -* Forgot Password -* Add drop-down menu on each board column title to close all tasks -* Add Malay language -* Add new API procedures for groups, roles, project permissions and to move/duplicate tasks to another project - -Improvements: - -* Avoid to send XHR request when a task has not moved after a drag and drop -* Set maximum dropzone height when the individual column scrolling is disabled -* Always show the search box in board selector -* Replace logout link by a drop-down menu -* Handle notification for group members attached to a project -* Return the highest role for a project when a user is member of multiple groups -* Show in user interface the saving state of the task -* Add drop-down menu for subtasks, categories, swimlanes, columns, custom filters, task links and groups -* Add new template hooks -* Application settings are not cached anymore in the session -* Do not check board status during task move -* Move validators to a separate namespace -* Improve and write unit tests for reports -* Reduce the number of SQL queries for project daily column stats -* Remove event subscriber to update date_moved field -* Make sure that some event subscribers are not executed multiple times -* Show rendering time of individual templates when debug mode is enabled -* Make sure that no events are fired if nothing has been modified in the task -* Make dashboard section title clickable -* Add unit tests for LastLogin - -Bug fixes: - -* Automatic action listeners were using the same instance -* Fix wrong link for category in task footer -* Unable to set currency rate with Postgres database -* Avoid automatic actions that change the color to fire subsequent events -* Unable to unassign a task from the API -* Revert back previous optimizations of TaskPosition (incompatibility with some environment) - -Version 1.0.23 --------------- - -Breaking changes: - -* Plugin API changes for Automatic Actions -* Automatic Action to close a task doesn't have the column parameter anymore (use the action "Close a task in a specific column") -* Action name stored in the database is now the absolute class name -* Core functionalities moved to external plugins: - - Github Webhook: https://github.com/kanboard/plugin-github-webhook - - Gitlab Webhook: https://github.com/kanboard/plugin-gitlab-webhook - - Bitbucket Webhook: https://github.com/kanboard/plugin-bitbucket-webhook - -New features: - -* Added support of user mentions (@username) -* Added report to compare working hours between open and closed tasks -* Added the possibility to define custom routes from plugins -* Added new method to remove metadata - -Improvements: - -* Improve Two-Factor activation and plugin API -* Improving performance during task position change (SQL queries are 3 times faster than before) -* Do not show window scrollbars when individual column scrolling is enabled -* Automatic Actions code improvements and unit tests -* Increase action name column length in actions table - -Bug fixes: - -* Fix compatibility issue with FreeBSD for session.hash_function parameter -* Fix wrong constant name that causes a PHP error in project management section -* Fix pagination in group members listing -* Avoid PHP error when enabling LDAP group provider with PHP < 5.5 - -Version 1.0.22 --------------- - -Breaking changes: - -* LDAP configuration parameters changes (See documentation) -* SQL table changes: - - "users" table: added new column "role" and removed columns "is_admin" and "is_project_admin" - - "project_has_users" table: replaced column "is_owner" with column "role" - - Sqlite does not support alter table, old columns still there but unused -* API procedure changes: - - createUser - - createLdapUser - - updateUser - - updateTask -* Event removed: "session.bootstrap", use "app.boostrap" instead - -New features: - -* Add pluggable authentication and authorization system (complete rewrite) -* Add groups (teams/organization) -* Add LDAP groups synchronization -* Add project group permissions -* Add new project role Viewer -* Add generic LDAP client library -* Add search query attribute for task link -* Add the possibility to define API token in config file -* Add capability to reopen Gitlab issues -* Try to load config.php from /data if not available - -Version 1.0.21 --------------- - -Breaking changes: - -* Projects with duplicate names are now allowed: - - For Postgres and Mysql the unique constraint is removed by database migration - - However Sqlite does not support alter table, only new databases will have the unique constraint removed - -New features: - -* New automatic action: Assign a category based on a link -* Added Bosnian translation - -Improvements: - -* Dropdown menu entries are now clickable outside of the html link -* Improve error handling of plugins -* Use PHP7 function random_bytes() to generate tokens if available -* CSV task export show the assignee name in addition to the assignee username -* Add new hooks for plugins -* Remove workaround for "INSERT ON DUPLICATE KEY UPDATE..." - -Internal code refactoring: - -* Rewrite of session management -* Move some classes to a new namespace Kanboard\Core\Http - -Bug fixes: - -* Loading cs_CZ locale display the wrong language in datetime picker -* Datepicker is closed unexpectedly on blur event -* Fix bug in daily project summary CSV export -* Fix PHP error when adding a new user with email notification enabled -* Add missing template for activity stream to show event "file.create" -* Fix wrong value for PLUGINS_DIR in config.default.php -* Make CSV export compatible with PHP 5.3 -* Avoid Safari to append .html at the end of downloaded files - -Version 1.0.20 --------------- - -Breaking changes: - -* Add namespace Kanboard (update your plugins) -* Move Mailgun, Sendgrid, Postmark, Slack, Hipchat and Jabber to plugins -* ReverseProxy authentication check for each request that the username match the user session - -New features: - -* Add CSV import for users and tasks -* Add Task, User and Project metadata for plugin creators - -Improvements: - -* Allow to change comments sorting -* Add the possibility to append or not custom filters -* Make mail transports pluggable -* Do not show scroll-bars when a column is collapsed on Windows systems -* Regenerate thumbnails if missing - -Bug fixes: - -* People should not see any tasks during a search when they are not associated to a project -* Avoid disabling the default swimlane during renaming when there is no other activated swimlane - -Version 1.0.19 --------------- - -New features: - -* Added web notifications -* Added LDAP group sync -* Added swimlane description -* New plugin system (alpha) -* Added Bahasa Indonesia translation -* Added API procedures: getMyOverdueTasks, getOverdueTasksByProject and GetMyProjects -* Added user API access for procedure getProjectActivity() -* Added config parameter to enable/disable Syslog -* Added custom filters -* Added http client proxy support - -Core functionalities moved to plugins: - -* Budget planning: https://github.com/kanboard/plugin-budget -* SubtaskForecast: https://github.com/kanboard/plugin-subtask-forecast -* Timetable: https://github.com/kanboard/plugin-timetable - -Improvements: - -* When duplicating a task redirect to the new task -* Include more shortcut links into the view "My projects" -* Duplicate a project with tasks will copy the new tasks in the same columns -* Offer alternative method to create Mysql and Postgres databases (import sql dump) -* Make sure there is always a trailing slash for application_url -* Do not show the checkbox "Show default swimlane" when there is no active swimlanes -* Append filters instead of replacing value for users and categories drop-downs -* Do not show empty swimlanes in public view -* Change swimlane layout to save space on the screen -* Add the possibility to set/unset max column height (column scrolling) -* Show "Open this task" in drop-down menu for closed tasks -* Show assignee on card only when someone is assigned (hide nobody text) -* Highlight selected item in drop-down menus -* Gantt chart: change bar color according to task progress -* Replace color drop-down by color picker in task forms -* Creating another task stay in the popover (no full page refresh anymore) -* Avoid scrollbar in Gantt chart for row title on Windows platform -* Remove unnecessary margin for calendar header -* Show localized documentation if available -* Add event subtask.delete -* Add abstract storage layer -* Add abstract cache layer -* Add Docker tag for stable version - -Others: - -* Data directory permission are not checked anymore -* Data directory is not mandatory anymore for people that use a remote database and remote object storage - -Bug fixes: - -* Fix typo in template that prevents Gitlab OAuth link to be displayed -* Fix Markdown preview links focus -* Avoid drop-down menu to be truncated inside a column with scrolling -* Deleting subtask doesn't update task time tracking -* Fix Mysql error about gitlab_id when creating remote user -* Fix subtask timer bug (event called recursively) -* Fix Postgres issue "Cardinality violation" when there is multiple "is_milestone_of" links -* Fix issue with due date greater than year 2038 - -Version 1.0.18 --------------- - -New features: - -* Include documentation in the application -* Add Gitlab authentication -* Add users and categories filters on the board -* Add hide/show columns -* Add Gantt chart for projects and tasks -* Add new role "Project Administrator" -* Add login brute force protection with captcha and account lockdown -* Add new api procedures: getDefaultTaskColor(), getDefaultTaskColors() and getColorList() -* Add user api access -* Add config parameter to define session duration -* Add config parameter to disable/enable RememberMe authentication -* Add start/end date for projects -* Add new automated action to change task color based on the task link -* Add milestone marker in board task -* Add search for task title when using an integer only input -* Add Portuguese (European) translation -* Add Norwegian translation - -Improvements: - -* Add handle to move tasks on touch devices -* Improve file attachments tooltip on the board -* Adjust automatically the height of the placeholder during drag and drop -* Show all tasks when using no search criteria -* Add column vertical scrolling -* Set dynamically column height based on viewport size -* Enable support for Github Enterprise when using Github Authentication -* Update iCalendar library to display organizer name -* Improve sidebar menus -* Add no referrer policy in meta tags -* Run automated unit tests with Sqlite/Mysql/Postgres on Travis-ci -* Add Makefile and remove the "scripts" directory - -Bug fixes: - -* Wrong template name for subtasks tooltip due to previous refactoring -* Fix broken url for closed tasks in project view -* Fix permission issue when changing the url manually -* Fix bug task estimate is reset when using subtask timer -* Fix screenshot feature with Firefox 40 -* Fix bug when uploading files with Cyrilic characters - -Version 1.0.17 --------------- - -New features: - -* Added url rewrite and new routes -* Added new search engine with advanced syntax -* Added global search section -* Added search form on the dashboard -* Added new dashboard layout -* Added new layout for board/calendar/list views -* Added filters helper for search forms -* Added setting option to disable subtask timer -* Added setting option to include or exclude closed tasks into CFD -* Added setting option to define the default task color -* Added new config option to disable automatic creation of LDAP accounts -* Added loading icon on board view -* Prompt user when moving or duplicate a task to another project -* Added current values when moving/duplicate a task to another project and add a loading icon -* Added memory consumption to debug log -* Added form to create remote user -* Added edit form for user authentication -* Added config option to hide login form -* Display OAuth2 urls on integration page -* Added keyboard shortcuts to switch between board/calendar/list view -* Added keyboard shortcut to focus on the search box -* Added Slack channel override -* Added new report: Lead and cycle time for projects -* Added new report: Average time spent into each column -* Added task analytics -* Added icon to set the start date automatically -* Added datetime picker for start date - -Improvements: - -* Updated documentation -* Display user initials when tasks are in collapsed mode -* Show title in tooltip for collapsed tasks -* Improve alert box fadeout to avoid an empty space -* Set focus on the drop-down for category popover -* Make escape keyboard shortcut global -* Check the box remember me by default -* Store redirect login url in session instead of using url parameter -* Update Gitlab webhook -* Do not rewrite remember me cookie for each request -* Set the assignee as organizer for ical events -* Increase date range for ics export -* Reduce spacing on cards -* Move board collapse/expand mode to server side to avoid board flickering -* Use ajax requests for board collapse/expand -* Do not set anchor for the default swimlane on the link back to board -* Replace timeserie axis to category axis for charts -* Hide task age in compact mode -* Improve quick-add subtasks form -* Reduce the size of the filter box for smaller screen -* Added icon to hide/show sidebar -* Update GitLab logo -* Improve Dockerfile - -Translations: - -* Added Czech translation -* Updated Spanish translation -* Updated German Translation - -Bug fixes: - -* Screenshot drop-down: unexpected scroll down on the board view and focus lost when clicking on the drop zone -* No creator when duplicating a task -* Avoid the creation of multiple subtask timer for the same task and user - -Code refactoring: - -* Split task controller into smaller classes -* Remove method Category::getBoardCategories() -* Rewrite movePosition() to improve performances -* Refactoring of Github and Google authentication - -Breaking changes: - -* New OAuth url for Google and Github authentication - -API: - -* Add urls in api response for tasks and projects - -Other: - -* Added automated Docker build -* Remove edit recurrence from the task menu on the board -* Switch to MIT License instead of AGPLv3 - -Version 1.0.0 to 1.0.16 ------------------------ - -* See commit history and website news diff --git a/sources/app/.htaccess b/sources/app/.htaccess deleted file mode 100644 index c47998c..0000000 --- a/sources/app/.htaccess +++ /dev/null @@ -1,7 +0,0 @@ -= 2.3> - Require all denied - - - Order allow,deny - Deny from all - diff --git a/sources/app/Action/Base.php b/sources/app/Action/Base.php deleted file mode 100644 index e5c65a1..0000000 --- a/sources/app/Action/Base.php +++ /dev/null @@ -1,297 +0,0 @@ -params as $key => $value) { - $params[] = $key.'='.var_export($value, true); - } - - return $this->getName().'('.implode('|', $params).')'; - } - - /** - * Set project id - * - * @access public - * @param integer $project_id - * @return Base - */ - public function setProjectId($project_id) - { - $this->projectId = $project_id; - return $this; - } - - /** - * Get project id - * - * @access public - * @return integer - */ - public function getProjectId() - { - return $this->projectId; - } - - /** - * Set an user defined parameter - * - * @access public - * @param string $name Parameter name - * @param mixed $value Value - * @return Base - */ - public function setParam($name, $value) - { - $this->params[$name] = $value; - return $this; - } - - /** - * Get an user defined parameter - * - * @access public - * @param string $name Parameter name - * @param mixed $default Default value - * @return mixed - */ - public function getParam($name, $default = null) - { - return isset($this->params[$name]) ? $this->params[$name] : $default; - } - - /** - * Check if an action is executable (right project and required parameters) - * - * @access public - * @param array $data - * @param string $eventName - * @return bool - */ - public function isExecutable(array $data, $eventName) - { - return $this->hasCompatibleEvent($eventName) && - $this->hasRequiredProject($data) && - $this->hasRequiredParameters($data) && - $this->hasRequiredCondition($data); - } - - /** - * Check if the event is compatible with the action - * - * @access public - * @param string $eventName - * @return bool - */ - public function hasCompatibleEvent($eventName) - { - return in_array($eventName, $this->getEvents()); - } - - /** - * Check if the event data has the required project - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredProject(array $data) - { - return isset($data['project_id']) && $data['project_id'] == $this->getProjectId(); - } - - /** - * Check if the event data has required parameters to execute the action - * - * @access public - * @param array $data Event data dictionary - * @return bool True if all keys are there - */ - public function hasRequiredParameters(array $data) - { - foreach ($this->getEventRequiredParameters() as $parameter) { - if (! isset($data[$parameter])) { - return false; - } - } - - return true; - } - - /** - * Execute the action - * - * @access public - * @param \Kanboard\Event\GenericEvent $event - * @param string $eventName - * @return bool - */ - public function execute(GenericEvent $event, $eventName) - { - // Avoid infinite loop, a listener instance can be called only one time - if ($this->called) { - return false; - } - - $data = $event->getAll(); - $executable = $this->isExecutable($data, $eventName); - $executed = false; - - if ($executable) { - $this->called = true; - $executed = $this->doAction($data); - } - - $this->logger->debug($this.' ['.$eventName.'] => executable='.var_export($executable, true).' exec_success='.var_export($executed, true)); - - return $executed; - } - - /** - * Register a new event for the automatic action - * - * @access public - * @param string $event - * @param string $description - * @return Base - */ - public function addEvent($event, $description = '') - { - if ($description !== '') { - $this->eventManager->register($event, $description); - } - - $this->compatibleEvents[] = $event; - return $this; - } - - /** - * Get all compatible events of an automatic action - * - * @access public - * @return array - */ - public function getEvents() - { - return array_unique(array_merge($this->getCompatibleEvents(), $this->compatibleEvents)); - } -} diff --git a/sources/app/Action/CommentCreation.php b/sources/app/Action/CommentCreation.php deleted file mode 100644 index 60ca24f..0000000 --- a/sources/app/Action/CommentCreation.php +++ /dev/null @@ -1,87 +0,0 @@ -commentModel->create(array( - 'reference' => isset($data['reference']) ? $data['reference'] : '', - 'comment' => $data['comment'], - 'task_id' => $data['task_id'], - 'user_id' => isset($data['user_id']) && $this->projectPermissionModel->isAssignable($this->getProjectId(), $data['user_id']) ? $data['user_id'] : 0, - )); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return ! empty($data['comment']); - } -} diff --git a/sources/app/Action/CommentCreationMoveTaskColumn.php b/sources/app/Action/CommentCreationMoveTaskColumn.php deleted file mode 100644 index 1b16f48..0000000 --- a/sources/app/Action/CommentCreationMoveTaskColumn.php +++ /dev/null @@ -1,94 +0,0 @@ - t('Column')); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array('task_id', 'column_id'); - } - - /** - * Execute the action (append to the task description). - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - if (! $this->userSession->isLogged()) { - return false; - } - - $column = $this->columnModel->getById($data['column_id']); - - return (bool) $this->commentModel->create(array( - 'comment' => t('Moved to column %s', $column['title']), - 'task_id' => $data['task_id'], - 'user_id' => $this->userSession->getId(), - )); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/sources/app/Action/TaskAssignCategoryColor.php b/sources/app/Action/TaskAssignCategoryColor.php deleted file mode 100644 index fc48687..0000000 --- a/sources/app/Action/TaskAssignCategoryColor.php +++ /dev/null @@ -1,95 +0,0 @@ - t('Color'), - 'category_id' => t('Category'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'color_id', - ); - } - - /** - * Execute the action (change the category) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'category_id' => $this->getParam('category_id'), - ); - - return $this->taskModificationModel->update($values); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['color_id'] == $this->getParam('color_id'); - } -} diff --git a/sources/app/Action/TaskAssignCategoryLabel.php b/sources/app/Action/TaskAssignCategoryLabel.php deleted file mode 100644 index 4829901..0000000 --- a/sources/app/Action/TaskAssignCategoryLabel.php +++ /dev/null @@ -1,91 +0,0 @@ - t('Label'), - 'category_id' => t('Category'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'label', - ); - } - - /** - * Execute the action (change the category) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'category_id' => $this->getParam('category_id'), - ); - - return $this->taskModificationModel->update($values); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['label'] == $this->getParam('label') && empty($data['category_id']); - } -} diff --git a/sources/app/Action/TaskAssignCategoryLink.php b/sources/app/Action/TaskAssignCategoryLink.php deleted file mode 100644 index 6937edd..0000000 --- a/sources/app/Action/TaskAssignCategoryLink.php +++ /dev/null @@ -1,101 +0,0 @@ - t('Category'), - 'link_id' => t('Link type'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'link_id', - ); - } - - /** - * Execute the action (change the category) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'category_id' => $this->getParam('category_id'), - ); - - return $this->taskModificationModel->update($values); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - if ($data['link_id'] == $this->getParam('link_id')) { - $task = $this->taskFinderModel->getById($data['task_id']); - return empty($task['category_id']); - } - - return false; - } -} diff --git a/sources/app/Action/TaskAssignColorCategory.php b/sources/app/Action/TaskAssignColorCategory.php deleted file mode 100644 index 284b8f4..0000000 --- a/sources/app/Action/TaskAssignColorCategory.php +++ /dev/null @@ -1,95 +0,0 @@ - t('Color'), - 'category_id' => t('Category'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'category_id', - ); - } - - /** - * Execute the action (change the task color) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'color_id' => $this->getParam('color_id'), - ); - - return $this->taskModificationModel->update($values, false); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['category_id'] == $this->getParam('category_id'); - } -} diff --git a/sources/app/Action/TaskAssignColorColumn.php b/sources/app/Action/TaskAssignColorColumn.php deleted file mode 100644 index 57fd6f4..0000000 --- a/sources/app/Action/TaskAssignColorColumn.php +++ /dev/null @@ -1,96 +0,0 @@ - t('Column'), - 'color_id' => t('Color'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - ); - } - - /** - * Execute the action (set the task color) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'color_id' => $this->getParam('color_id'), - ); - - return $this->taskModificationModel->update($values, false); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/sources/app/Action/TaskAssignColorLink.php b/sources/app/Action/TaskAssignColorLink.php deleted file mode 100644 index 9ab5458..0000000 --- a/sources/app/Action/TaskAssignColorLink.php +++ /dev/null @@ -1,95 +0,0 @@ - t('Color'), - 'link_id' => t('Link type'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'link_id', - ); - } - - /** - * Execute the action (change the task color) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'color_id' => $this->getParam('color_id'), - ); - - return $this->taskModificationModel->update($values, false); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['link_id'] == $this->getParam('link_id'); - } -} diff --git a/sources/app/Action/TaskAssignColorPriority.php b/sources/app/Action/TaskAssignColorPriority.php deleted file mode 100644 index eae1b77..0000000 --- a/sources/app/Action/TaskAssignColorPriority.php +++ /dev/null @@ -1,95 +0,0 @@ - t('Color'), - 'priority' => t('Priority'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'priority', - ); - } - - /** - * Execute the action (change the task color) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'color_id' => $this->getParam('color_id'), - ); - - return $this->taskModificationModel->update($values, false); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['priority'] == $this->getParam('priority'); - } -} diff --git a/sources/app/Action/TaskAssignColorUser.php b/sources/app/Action/TaskAssignColorUser.php deleted file mode 100644 index 4bcf7a5..0000000 --- a/sources/app/Action/TaskAssignColorUser.php +++ /dev/null @@ -1,96 +0,0 @@ - t('Color'), - 'user_id' => t('Assignee'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'owner_id', - ); - } - - /** - * Execute the action (change the task color) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'color_id' => $this->getParam('color_id'), - ); - - return $this->taskModificationModel->update($values, false); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['owner_id'] == $this->getParam('user_id'); - } -} diff --git a/sources/app/Action/TaskAssignCurrentUser.php b/sources/app/Action/TaskAssignCurrentUser.php deleted file mode 100644 index 997aa98..0000000 --- a/sources/app/Action/TaskAssignCurrentUser.php +++ /dev/null @@ -1,95 +0,0 @@ -userSession->isLogged()) { - return false; - } - - $values = array( - 'id' => $data['task_id'], - 'owner_id' => $this->userSession->getId(), - ); - - return $this->taskModificationModel->update($values); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return true; - } -} diff --git a/sources/app/Action/TaskAssignCurrentUserColumn.php b/sources/app/Action/TaskAssignCurrentUserColumn.php deleted file mode 100644 index bc28a90..0000000 --- a/sources/app/Action/TaskAssignCurrentUserColumn.php +++ /dev/null @@ -1,98 +0,0 @@ - t('Column'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - ); - } - - /** - * Execute the action - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - if (! $this->userSession->isLogged()) { - return false; - } - - $values = array( - 'id' => $data['task_id'], - 'owner_id' => $this->userSession->getId(), - ); - - return $this->taskModificationModel->update($values); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/sources/app/Action/TaskAssignSpecificUser.php b/sources/app/Action/TaskAssignSpecificUser.php deleted file mode 100644 index 50a2b2a..0000000 --- a/sources/app/Action/TaskAssignSpecificUser.php +++ /dev/null @@ -1,96 +0,0 @@ - t('Column'), - 'user_id' => t('Assignee'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - ); - } - - /** - * Execute the action (assign the given user) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'owner_id' => $this->getParam('user_id'), - ); - - return $this->taskModificationModel->update($values); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/sources/app/Action/TaskAssignUser.php b/sources/app/Action/TaskAssignUser.php deleted file mode 100644 index 9ea2298..0000000 --- a/sources/app/Action/TaskAssignUser.php +++ /dev/null @@ -1,88 +0,0 @@ - $data['task_id'], - 'owner_id' => $data['owner_id'], - ); - - return $this->taskModificationModel->update($values); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $this->projectPermissionModel->isAssignable($this->getProjectId(), $data['owner_id']); - } -} diff --git a/sources/app/Action/TaskClose.php b/sources/app/Action/TaskClose.php deleted file mode 100644 index 91e8cf4..0000000 --- a/sources/app/Action/TaskClose.php +++ /dev/null @@ -1,80 +0,0 @@ -taskStatusModel->close($data['task_id']); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return true; - } -} diff --git a/sources/app/Action/TaskCloseColumn.php b/sources/app/Action/TaskCloseColumn.php deleted file mode 100644 index 1edce8f..0000000 --- a/sources/app/Action/TaskCloseColumn.php +++ /dev/null @@ -1,84 +0,0 @@ - t('Column')); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array('task_id', 'column_id'); - } - - /** - * Execute the action (close the task) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - return $this->taskStatusModel->close($data['task_id']); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/sources/app/Action/TaskCloseNoActivity.php b/sources/app/Action/TaskCloseNoActivity.php deleted file mode 100644 index 5a10510..0000000 --- a/sources/app/Action/TaskCloseNoActivity.php +++ /dev/null @@ -1,95 +0,0 @@ - t('Duration in days') - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array('tasks'); - } - - /** - * Execute the action (close the task) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $results = array(); - $max = $this->getParam('duration') * 86400; - - foreach ($data['tasks'] as $task) { - $duration = time() - $task['date_modification']; - - if ($duration > $max) { - $results[] = $this->taskStatusModel->close($task['id']); - } - } - - return in_array(true, $results, true); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return count($data['tasks']) > 0; - } -} diff --git a/sources/app/Action/TaskCreation.php b/sources/app/Action/TaskCreation.php deleted file mode 100644 index e9e5c5f..0000000 --- a/sources/app/Action/TaskCreation.php +++ /dev/null @@ -1,88 +0,0 @@ -taskCreationModel->create(array( - 'project_id' => $data['project_id'], - 'title' => $data['title'], - 'reference' => $data['reference'], - 'description' => isset($data['description']) ? $data['description'] : '', - )); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return true; - } -} diff --git a/sources/app/Action/TaskDuplicateAnotherProject.php b/sources/app/Action/TaskDuplicateAnotherProject.php deleted file mode 100644 index d70d2ee..0000000 --- a/sources/app/Action/TaskDuplicateAnotherProject.php +++ /dev/null @@ -1,93 +0,0 @@ - t('Column'), - 'project_id' => t('Project'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - ); - } - - /** - * Execute the action (duplicate the task to another project) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $destination_column_id = $this->columnModel->getFirstColumnId($this->getParam('project_id')); - return (bool) $this->taskProjectDuplicationModel->duplicateToProject($data['task_id'], $this->getParam('project_id'), null, $destination_column_id); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id') && $data['project_id'] != $this->getParam('project_id'); - } -} diff --git a/sources/app/Action/TaskEmail.php b/sources/app/Action/TaskEmail.php deleted file mode 100644 index 7f9ba41..0000000 --- a/sources/app/Action/TaskEmail.php +++ /dev/null @@ -1,107 +0,0 @@ - t('Column'), - 'user_id' => t('User that will receive the email'), - 'subject' => t('Email subject'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - ); - } - - /** - * Execute the action (move the task to another column) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $user = $this->userModel->getById($this->getParam('user_id')); - - if (! empty($user['email'])) { - $task = $this->taskFinderModel->getDetails($data['task_id']); - - $this->emailClient->send( - $user['email'], - $user['name'] ?: $user['username'], - $this->getParam('subject'), - $this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->configModel->get('application_url'))) - ); - - return true; - } - - return false; - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/sources/app/Action/TaskEmailNoActivity.php b/sources/app/Action/TaskEmailNoActivity.php deleted file mode 100644 index c60702f..0000000 --- a/sources/app/Action/TaskEmailNoActivity.php +++ /dev/null @@ -1,124 +0,0 @@ - t('User that will receive the email'), - 'subject' => t('Email subject'), - 'duration' => t('Duration in days'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array('tasks'); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return count($data['tasks']) > 0; - } - - /** - * Execute the action (move the task to another column) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $results = array(); - $max = $this->getParam('duration') * 86400; - $user = $this->userModel->getById($this->getParam('user_id')); - - if (! empty($user['email'])) { - foreach ($data['tasks'] as $task) { - $duration = time() - $task['date_modification']; - - if ($duration > $max) { - $results[] = $this->sendEmail($task['id'], $user); - } - } - } - - return in_array(true, $results, true); - } - - /** - * Send email - * - * @access private - * @param integer $task_id - * @param array $user - * @return boolean - */ - private function sendEmail($task_id, array $user) - { - $task = $this->taskFinderModel->getDetails($task_id); - - $this->emailClient->send( - $user['email'], - $user['name'] ?: $user['username'], - $this->getParam('subject'), - $this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->configModel->get('application_url'))) - ); - - return true; - } -} diff --git a/sources/app/Action/TaskMoveAnotherProject.php b/sources/app/Action/TaskMoveAnotherProject.php deleted file mode 100644 index 66635a6..0000000 --- a/sources/app/Action/TaskMoveAnotherProject.php +++ /dev/null @@ -1,92 +0,0 @@ - t('Column'), - 'project_id' => t('Project'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - 'project_id', - ); - } - - /** - * Execute the action (move the task to another project) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - return $this->taskProjectMoveModel->moveToProject($data['task_id'], $this->getParam('project_id')); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id') && $data['project_id'] != $this->getParam('project_id'); - } -} diff --git a/sources/app/Action/TaskMoveColumnAssigned.php b/sources/app/Action/TaskMoveColumnAssigned.php deleted file mode 100644 index 7e3db9c..0000000 --- a/sources/app/Action/TaskMoveColumnAssigned.php +++ /dev/null @@ -1,101 +0,0 @@ - t('Source column'), - 'dest_column_id' => t('Destination column') - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - 'owner_id' - ); - } - - /** - * Execute the action (move the task to another column) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $original_task = $this->taskFinderModel->getById($data['task_id']); - - return $this->taskPositionModel->movePosition( - $data['project_id'], - $data['task_id'], - $this->getParam('dest_column_id'), - $original_task['position'], - $original_task['swimlane_id'], - false - ); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('src_column_id') && $data['owner_id'] > 0; - } -} diff --git a/sources/app/Action/TaskMoveColumnCategoryChange.php b/sources/app/Action/TaskMoveColumnCategoryChange.php deleted file mode 100644 index e4f8876..0000000 --- a/sources/app/Action/TaskMoveColumnCategoryChange.php +++ /dev/null @@ -1,100 +0,0 @@ - t('Destination column'), - 'category_id' => t('Category'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - 'category_id', - ); - } - - /** - * Execute the action (move the task to another column) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $original_task = $this->taskFinderModel->getById($data['task_id']); - - return $this->taskPositionModel->movePosition( - $data['project_id'], - $data['task_id'], - $this->getParam('dest_column_id'), - $original_task['position'], - $original_task['swimlane_id'], - false - ); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] != $this->getParam('dest_column_id') && $data['category_id'] == $this->getParam('category_id'); - } -} diff --git a/sources/app/Action/TaskMoveColumnUnAssigned.php b/sources/app/Action/TaskMoveColumnUnAssigned.php deleted file mode 100644 index c3ae9e1..0000000 --- a/sources/app/Action/TaskMoveColumnUnAssigned.php +++ /dev/null @@ -1,101 +0,0 @@ - t('Source column'), - 'dest_column_id' => t('Destination column') - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - 'owner_id' - ); - } - - /** - * Execute the action (move the task to another column) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $original_task = $this->taskFinderModel->getById($data['task_id']); - - return $this->taskPositionModel->movePosition( - $data['project_id'], - $data['task_id'], - $this->getParam('dest_column_id'), - $original_task['position'], - $original_task['swimlane_id'], - false - ); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('src_column_id') && $data['owner_id'] == 0; - } -} diff --git a/sources/app/Action/TaskOpen.php b/sources/app/Action/TaskOpen.php deleted file mode 100644 index 8e847b8..0000000 --- a/sources/app/Action/TaskOpen.php +++ /dev/null @@ -1,80 +0,0 @@ -taskStatusModel->open($data['task_id']); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return true; - } -} diff --git a/sources/app/Action/TaskUpdateStartDate.php b/sources/app/Action/TaskUpdateStartDate.php deleted file mode 100644 index e5410a8..0000000 --- a/sources/app/Action/TaskUpdateStartDate.php +++ /dev/null @@ -1,94 +0,0 @@ - t('Column'), - ); - } - - /** - * Get the required parameter for the event - * - * @access public - * @return string[] - */ - public function getEventRequiredParameters() - { - return array( - 'task_id', - 'column_id', - ); - } - - /** - * Execute the action (set the task color) - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function doAction(array $data) - { - $values = array( - 'id' => $data['task_id'], - 'date_started' => time(), - ); - - return $this->taskModificationModel->update($values, false); - } - - /** - * Check if the event data meet the action condition - * - * @access public - * @param array $data Event data dictionary - * @return bool - */ - public function hasRequiredCondition(array $data) - { - return $data['column_id'] == $this->getParam('column_id'); - } -} diff --git a/sources/app/Analytic/AverageLeadCycleTimeAnalytic.php b/sources/app/Analytic/AverageLeadCycleTimeAnalytic.php deleted file mode 100644 index d6cd1f8..0000000 --- a/sources/app/Analytic/AverageLeadCycleTimeAnalytic.php +++ /dev/null @@ -1,116 +0,0 @@ - 0, - 'total_lead_time' => 0, - 'total_cycle_time' => 0, - 'avg_lead_time' => 0, - 'avg_cycle_time' => 0, - ); - - $tasks = $this->getTasks($project_id); - - foreach ($tasks as &$task) { - $stats['count']++; - $stats['total_lead_time'] += $this->calculateLeadTime($task); - $stats['total_cycle_time'] += $this->calculateCycleTime($task); - } - - $stats['avg_lead_time'] = $this->calculateAverage($stats, 'total_lead_time'); - $stats['avg_cycle_time'] = $this->calculateAverage($stats, 'total_cycle_time'); - - return $stats; - } - - /** - * Calculate average - * - * @access private - * @param array &$stats - * @param string $field - * @return float - */ - private function calculateAverage(array &$stats, $field) - { - if ($stats['count'] > 0) { - return (int) ($stats[$field] / $stats['count']); - } - - return 0; - } - - /** - * Calculate lead time - * - * @access private - * @param array &$task - * @return integer - */ - private function calculateLeadTime(array &$task) - { - $end = $task['date_completed'] ?: time(); - $start = $task['date_creation']; - - return $end - $start; - } - - /** - * Calculate cycle time - * - * @access private - * @param array &$task - * @return integer - */ - private function calculateCycleTime(array &$task) - { - $end = (int) $task['date_completed'] ?: time(); - $start = (int) $task['date_started']; - - // Start date can be in the future when defined with the Gantt chart - if ($start > 0 && $end > $start) { - return $end - $start; - } - - return 0; - } - - /** - * Get the 1000 last created tasks - * - * @access private - * @param integer $project_id - * @return array - */ - private function getTasks($project_id) - { - return $this->db - ->table(TaskModel::TABLE) - ->columns('date_completed', 'date_creation', 'date_started') - ->eq('project_id', $project_id) - ->desc('id') - ->limit(1000) - ->findAll(); - } -} diff --git a/sources/app/Analytic/AverageTimeSpentColumnAnalytic.php b/sources/app/Analytic/AverageTimeSpentColumnAnalytic.php deleted file mode 100644 index 3556fb9..0000000 --- a/sources/app/Analytic/AverageTimeSpentColumnAnalytic.php +++ /dev/null @@ -1,154 +0,0 @@ -initialize($project_id); - - $this->processTasks($stats, $project_id); - $this->calculateAverage($stats); - - return $stats; - } - - /** - * Initialize default values for each column - * - * @access private - * @param integer $project_id - * @return array - */ - private function initialize($project_id) - { - $stats = array(); - $columns = $this->columnModel->getList($project_id); - - foreach ($columns as $column_id => $column_title) { - $stats[$column_id] = array( - 'count' => 0, - 'time_spent' => 0, - 'average' => 0, - 'title' => $column_title, - ); - } - - return $stats; - } - - /** - * Calculate time spent for each tasks for each columns - * - * @access private - * @param array $stats - * @param integer $project_id - */ - private function processTasks(array &$stats, $project_id) - { - $tasks = $this->getTasks($project_id); - - foreach ($tasks as &$task) { - foreach ($this->getTaskTimeByColumns($task) as $column_id => $time_spent) { - if (isset($stats[$column_id])) { - $stats[$column_id]['count']++; - $stats[$column_id]['time_spent'] += $time_spent; - } - } - } - } - - /** - * Calculate averages - * - * @access private - * @param array $stats - */ - private function calculateAverage(array &$stats) - { - foreach ($stats as &$column) { - $this->calculateColumnAverage($column); - } - } - - /** - * Calculate column average - * - * @access private - * @param array $column - */ - private function calculateColumnAverage(array &$column) - { - if ($column['count'] > 0) { - $column['average'] = (int) ($column['time_spent'] / $column['count']); - } - } - - /** - * Get time spent for each column for a given task - * - * @access private - * @param array $task - * @return array - */ - private function getTaskTimeByColumns(array &$task) - { - $columns = $this->transitionModel->getTimeSpentByTask($task['id']); - - if (! isset($columns[$task['column_id']])) { - $columns[$task['column_id']] = 0; - } - - $columns[$task['column_id']] += $this->getTaskTimeSpentInCurrentColumn($task); - - return $columns; - } - - /** - * Calculate time spent of a task in the current column - * - * @access private - * @param array $task - * @return integer - */ - private function getTaskTimeSpentInCurrentColumn(array &$task) - { - $end = $task['date_completed'] ?: time(); - return $end - $task['date_moved']; - } - - /** - * Fetch the last 1000 tasks - * - * @access private - * @param integer $project_id - * @return array - */ - private function getTasks($project_id) - { - return $this->db - ->table(TaskModel::TABLE) - ->columns('id', 'date_completed', 'date_moved', 'column_id') - ->eq('project_id', $project_id) - ->desc('id') - ->limit(1000) - ->findAll(); - } -} diff --git a/sources/app/Analytic/EstimatedTimeComparisonAnalytic.php b/sources/app/Analytic/EstimatedTimeComparisonAnalytic.php deleted file mode 100644 index d9aea32..0000000 --- a/sources/app/Analytic/EstimatedTimeComparisonAnalytic.php +++ /dev/null @@ -1,50 +0,0 @@ -db->table(TaskModel::TABLE) - ->columns('SUM(time_estimated) AS time_estimated', 'SUM(time_spent) AS time_spent', 'is_active') - ->eq('project_id', $project_id) - ->groupBy('is_active') - ->findAll(); - - $metrics = array( - 'open' => array( - 'time_spent' => 0, - 'time_estimated' => 0, - ), - 'closed' => array( - 'time_spent' => 0, - 'time_estimated' => 0, - ), - ); - - foreach ($rows as $row) { - $key = $row['is_active'] == TaskModel::STATUS_OPEN ? 'open' : 'closed'; - $metrics[$key]['time_spent'] = $row['time_spent']; - $metrics[$key]['time_estimated'] = $row['time_estimated']; - } - - return $metrics; - } -} diff --git a/sources/app/Analytic/TaskDistributionAnalytic.php b/sources/app/Analytic/TaskDistributionAnalytic.php deleted file mode 100644 index 447d88a..0000000 --- a/sources/app/Analytic/TaskDistributionAnalytic.php +++ /dev/null @@ -1,48 +0,0 @@ -columnModel->getAll($project_id); - - foreach ($columns as $column) { - $nb_tasks = $this->taskFinderModel->countByColumnId($project_id, $column['id']); - $total += $nb_tasks; - - $metrics[] = array( - 'column_title' => $column['title'], - 'nb_tasks' => $nb_tasks, - ); - } - - if ($total === 0) { - return array(); - } - - foreach ($metrics as &$metric) { - $metric['percentage'] = round(($metric['nb_tasks'] * 100) / $total, 2); - } - - return $metrics; - } -} diff --git a/sources/app/Analytic/UserDistributionAnalytic.php b/sources/app/Analytic/UserDistributionAnalytic.php deleted file mode 100644 index 421d424..0000000 --- a/sources/app/Analytic/UserDistributionAnalytic.php +++ /dev/null @@ -1,56 +0,0 @@ -taskFinderModel->getAll($project_id); - $users = $this->projectUserRoleModel->getAssignableUsersList($project_id); - - foreach ($tasks as $task) { - $user = isset($users[$task['owner_id']]) ? $users[$task['owner_id']] : $users[0]; - $total++; - - if (! isset($metrics[$user])) { - $metrics[$user] = array( - 'nb_tasks' => 0, - 'percentage' => 0, - 'user' => $user, - ); - } - - $metrics[$user]['nb_tasks']++; - } - - if ($total === 0) { - return array(); - } - - foreach ($metrics as &$metric) { - $metric['percentage'] = round(($metric['nb_tasks'] * 100) / $total, 2); - } - - ksort($metrics); - - return array_values($metrics); - } -} diff --git a/sources/app/Api/Authorization/ActionAuthorization.php b/sources/app/Api/Authorization/ActionAuthorization.php deleted file mode 100644 index 4b41ad8..0000000 --- a/sources/app/Api/Authorization/ActionAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->actionModel->getProjectId($action_id)); - } - } -} diff --git a/sources/app/Api/Authorization/CategoryAuthorization.php b/sources/app/Api/Authorization/CategoryAuthorization.php deleted file mode 100644 index f17265a..0000000 --- a/sources/app/Api/Authorization/CategoryAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->categoryModel->getProjectId($category_id)); - } - } -} diff --git a/sources/app/Api/Authorization/ColumnAuthorization.php b/sources/app/Api/Authorization/ColumnAuthorization.php deleted file mode 100644 index 37aecda..0000000 --- a/sources/app/Api/Authorization/ColumnAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->columnModel->getProjectId($column_id)); - } - } -} diff --git a/sources/app/Api/Authorization/CommentAuthorization.php b/sources/app/Api/Authorization/CommentAuthorization.php deleted file mode 100644 index ed15512..0000000 --- a/sources/app/Api/Authorization/CommentAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->commentModel->getProjectId($comment_id)); - } - } -} diff --git a/sources/app/Api/Authorization/ProcedureAuthorization.php b/sources/app/Api/Authorization/ProcedureAuthorization.php deleted file mode 100644 index 070a637..0000000 --- a/sources/app/Api/Authorization/ProcedureAuthorization.php +++ /dev/null @@ -1,32 +0,0 @@ -userSession->isLogged() && in_array($procedure, $this->userSpecificProcedures)) { - throw new AccessDeniedException('This procedure is not available with the API credentials'); - } - } -} diff --git a/sources/app/Api/Authorization/ProjectAuthorization.php b/sources/app/Api/Authorization/ProjectAuthorization.php deleted file mode 100644 index 21ecf31..0000000 --- a/sources/app/Api/Authorization/ProjectAuthorization.php +++ /dev/null @@ -1,35 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $project_id); - } - } - - protected function checkProjectPermission($class, $method, $project_id) - { - if (empty($project_id)) { - 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'); - } - } -} diff --git a/sources/app/Api/Authorization/SubtaskAuthorization.php b/sources/app/Api/Authorization/SubtaskAuthorization.php deleted file mode 100644 index fcb5792..0000000 --- a/sources/app/Api/Authorization/SubtaskAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->subtaskModel->getProjectId($subtask_id)); - } - } -} diff --git a/sources/app/Api/Authorization/TaskAuthorization.php b/sources/app/Api/Authorization/TaskAuthorization.php deleted file mode 100644 index db93b76..0000000 --- a/sources/app/Api/Authorization/TaskAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($category_id)); - } - } -} diff --git a/sources/app/Api/Authorization/TaskFileAuthorization.php b/sources/app/Api/Authorization/TaskFileAuthorization.php deleted file mode 100644 index e40783e..0000000 --- a/sources/app/Api/Authorization/TaskFileAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->taskFileModel->getProjectId($file_id)); - } - } -} diff --git a/sources/app/Api/Authorization/TaskLinkAuthorization.php b/sources/app/Api/Authorization/TaskLinkAuthorization.php deleted file mode 100644 index 2f5fc8d..0000000 --- a/sources/app/Api/Authorization/TaskLinkAuthorization.php +++ /dev/null @@ -1,19 +0,0 @@ -userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->taskLinkModel->getProjectId($task_link_id)); - } - } -} diff --git a/sources/app/Api/Authorization/UserAuthorization.php b/sources/app/Api/Authorization/UserAuthorization.php deleted file mode 100644 index 3fd6865..0000000 --- a/sources/app/Api/Authorization/UserAuthorization.php +++ /dev/null @@ -1,22 +0,0 @@ -userSession->isLogged() && ! $this->apiAuthorization->isAllowed($class, $method, $this->userSession->getRole())) { - throw new AccessDeniedException('You are not allowed to access to this resource'); - } - } -} diff --git a/sources/app/Api/Middleware/AuthenticationMiddleware.php b/sources/app/Api/Middleware/AuthenticationMiddleware.php deleted file mode 100644 index 8e30959..0000000 --- a/sources/app/Api/Middleware/AuthenticationMiddleware.php +++ /dev/null @@ -1,82 +0,0 @@ -dispatcher->dispatch('app.bootstrap'); - - if ($this->isUserAuthenticated($username, $password)) { - $this->userSession->initialize($this->userModel->getByUsername($username)); - } elseif (! $this->isAppAuthenticated($username, $password)) { - $this->logger->error('API authentication failure for '.$username); - throw new AuthenticationFailureException('Wrong credentials'); - } - } - - /** - * Check user credentials - * - * @access public - * @param string $username - * @param string $password - * @return boolean - */ - private function isUserAuthenticated($username, $password) - { - return $username !== 'jsonrpc' && - ! $this->userLockingModel->isLocked($username) && - $this->authenticationManager->passwordAuthentication($username, $password); - } - - /** - * Check administrative credentials - * - * @access public - * @param string $username - * @param string $password - * @return boolean - */ - private function isAppAuthenticated($username, $password) - { - return $username === 'jsonrpc' && $password === $this->getApiToken(); - } - - /** - * Get API Token - * - * @access private - * @return string - */ - private function getApiToken() - { - if (defined('API_AUTHENTICATION_TOKEN')) { - return API_AUTHENTICATION_TOKEN; - } - - return $this->configModel->get('api_token'); - } -} diff --git a/sources/app/Api/Procedure/ActionProcedure.php b/sources/app/Api/Procedure/ActionProcedure.php deleted file mode 100644 index 4043dbb..0000000 --- a/sources/app/Api/Procedure/ActionProcedure.php +++ /dev/null @@ -1,91 +0,0 @@ -actionManager->getAvailableActions(); - } - - public function getAvailableActionEvents() - { - return $this->eventManager->getAll(); - } - - public function getCompatibleActionEvents($action_name) - { - return $this->actionManager->getCompatibleEvents($action_name); - } - - public function removeAction($action_id) - { - ActionAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAction', $action_id); - return $this->actionModel->remove($action_id); - } - - public function getActions($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getActions', $project_id); - return $this->actionModel->getAllByProject($project_id); - } - - public function createAction($project_id, $event_name, $action_name, array $params) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createAction', $project_id); - $values = array( - 'project_id' => $project_id, - 'event_name' => $event_name, - 'action_name' => $action_name, - 'params' => $params, - ); - - list($valid, ) = $this->actionValidator->validateCreation($values); - - if (! $valid) { - return false; - } - - // Check if the action exists - $actions = $this->actionManager->getAvailableActions(); - - if (! isset($actions[$action_name])) { - return false; - } - - // Check the event - $action = $this->actionManager->getAction($action_name); - - if (! in_array($event_name, $action->getEvents())) { - return false; - } - - $required_params = $action->getActionRequiredParameters(); - - // Check missing parameters - foreach ($required_params as $param => $value) { - if (! isset($params[$param])) { - return false; - } - } - - // Check extra parameters - foreach ($params as $param => $value) { - if (! isset($required_params[$param])) { - return false; - } - } - - return $this->actionModel->create($values); - } -} diff --git a/sources/app/Api/Procedure/AppProcedure.php b/sources/app/Api/Procedure/AppProcedure.php deleted file mode 100644 index 60af4a6..0000000 --- a/sources/app/Api/Procedure/AppProcedure.php +++ /dev/null @@ -1,47 +0,0 @@ -timezoneModel->getCurrentTimezone(); - } - - public function getVersion() - { - return APP_VERSION; - } - - public function getDefaultTaskColor() - { - return $this->colorModel->getDefaultColor(); - } - - public function getDefaultTaskColors() - { - return $this->colorModel->getDefaultColors(); - } - - public function getColorList() - { - return $this->colorModel->getList(); - } - - public function getApplicationRoles() - { - return $this->role->getApplicationRoles(); - } - - public function getProjectRoles() - { - return $this->role->getProjectRoles(); - } -} diff --git a/sources/app/Api/Procedure/BaseProcedure.php b/sources/app/Api/Procedure/BaseProcedure.php deleted file mode 100644 index e31b302..0000000 --- a/sources/app/Api/Procedure/BaseProcedure.php +++ /dev/null @@ -1,85 +0,0 @@ -container)->check($procedure); - UserAuthorization::getInstance($this->container)->check($this->getClassName(), $procedure); - } - - protected function formatTask($task) - { - if (! empty($task)) { - $task['url'] = $this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), '', true); - $task['color'] = $this->colorModel->getColorProperties($task['color_id']); - } - - return $task; - } - - protected function formatTasks($tasks) - { - if (! empty($tasks)) { - foreach ($tasks as &$task) { - $task = $this->formatTask($task); - } - } - - return $tasks; - } - - protected function formatProject($project) - { - if (! empty($project)) { - $project['url'] = array( - 'board' => $this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id']), '', true), - 'calendar' => $this->helper->url->to('CalendarController', 'show', array('project_id' => $project['id']), '', true), - 'list' => $this->helper->url->to('TaskListController', 'show', array('project_id' => $project['id']), '', true), - ); - } - - return $project; - } - - protected function formatProjects($projects) - { - if (! empty($projects)) { - foreach ($projects as &$project) { - $project = $this->formatProject($project); - } - } - - return $projects; - } - - protected function filterValues(array $values) - { - foreach ($values as $key => $value) { - if (is_null($value)) { - unset($values[$key]); - } - } - - return $values; - } - - protected function getClassName() - { - $reflection = new ReflectionClass(get_called_class()); - return $reflection->getShortName(); - } -} diff --git a/sources/app/Api/Procedure/BoardProcedure.php b/sources/app/Api/Procedure/BoardProcedure.php deleted file mode 100644 index 674b546..0000000 --- a/sources/app/Api/Procedure/BoardProcedure.php +++ /dev/null @@ -1,25 +0,0 @@ -container)->check($this->getClassName(), 'getBoard', $project_id); - - return BoardFormatter::getInstance($this->container) - ->withProjectId($project_id) - ->withQuery($this->taskFinderModel->getExtendedQuery()) - ->format(); - } -} diff --git a/sources/app/Api/Procedure/CategoryProcedure.php b/sources/app/Api/Procedure/CategoryProcedure.php deleted file mode 100644 index 3ebbd90..0000000 --- a/sources/app/Api/Procedure/CategoryProcedure.php +++ /dev/null @@ -1,59 +0,0 @@ -container)->check($this->getClassName(), 'getCategory', $category_id); - return $this->categoryModel->getById($category_id); - } - - public function getAllCategories($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllCategories', $project_id); - return $this->categoryModel->getAll($project_id); - } - - public function removeCategory($category_id) - { - CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeCategory', $category_id); - return $this->categoryModel->remove($category_id); - } - - public function createCategory($project_id, $name) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createCategory', $project_id); - - $values = array( - 'project_id' => $project_id, - 'name' => $name, - ); - - list($valid, ) = $this->categoryValidator->validateCreation($values); - return $valid ? $this->categoryModel->create($values) : false; - } - - public function updateCategory($id, $name) - { - CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateCategory', $id); - - $values = array( - 'id' => $id, - 'name' => $name, - ); - - list($valid, ) = $this->categoryValidator->validateModification($values); - return $valid && $this->categoryModel->update($values); - } -} diff --git a/sources/app/Api/Procedure/ColumnProcedure.php b/sources/app/Api/Procedure/ColumnProcedure.php deleted file mode 100644 index ab9d173..0000000 --- a/sources/app/Api/Procedure/ColumnProcedure.php +++ /dev/null @@ -1,51 +0,0 @@ -container)->check($this->getClassName(), 'getColumns', $project_id); - return $this->columnModel->getAll($project_id); - } - - public function getColumn($column_id) - { - ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'getColumn', $column_id); - return $this->columnModel->getById($column_id); - } - - public function updateColumn($column_id, $title, $task_limit = 0, $description = '') - { - ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateColumn', $column_id); - return $this->columnModel->update($column_id, $title, $task_limit, $description); - } - - public function addColumn($project_id, $title, $task_limit = 0, $description = '') - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addColumn', $project_id); - return $this->columnModel->create($project_id, $title, $task_limit, $description); - } - - public function removeColumn($column_id) - { - ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeColumn', $column_id); - return $this->columnModel->remove($column_id); - } - - public function changeColumnPosition($project_id, $column_id, $position) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeColumnPosition', $project_id); - return $this->columnModel->changePosition($project_id, $column_id, $position); - } -} diff --git a/sources/app/Api/Procedure/CommentProcedure.php b/sources/app/Api/Procedure/CommentProcedure.php deleted file mode 100644 index 019a49b..0000000 --- a/sources/app/Api/Procedure/CommentProcedure.php +++ /dev/null @@ -1,62 +0,0 @@ -container)->check($this->getClassName(), 'getComment', $comment_id); - return $this->commentModel->getById($comment_id); - } - - public function getAllComments($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllComments', $task_id); - return $this->commentModel->getAll($task_id); - } - - public function removeComment($comment_id) - { - CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeComment', $comment_id); - return $this->commentModel->remove($comment_id); - } - - public function createComment($task_id, $user_id, $content, $reference = '') - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createComment', $task_id); - - $values = array( - 'task_id' => $task_id, - 'user_id' => $user_id, - 'comment' => $content, - 'reference' => $reference, - ); - - list($valid, ) = $this->commentValidator->validateCreation($values); - - return $valid ? $this->commentModel->create($values) : false; - } - - public function updateComment($id, $content) - { - CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateComment', $id); - - $values = array( - 'id' => $id, - 'comment' => $content, - ); - - list($valid, ) = $this->commentValidator->validateModification($values); - return $valid && $this->commentModel->update($values); - } -} diff --git a/sources/app/Api/Procedure/GroupMemberProcedure.php b/sources/app/Api/Procedure/GroupMemberProcedure.php deleted file mode 100644 index 081d6ac..0000000 --- a/sources/app/Api/Procedure/GroupMemberProcedure.php +++ /dev/null @@ -1,37 +0,0 @@ -groupMemberModel->getGroups($user_id); - } - - public function getGroupMembers($group_id) - { - return $this->groupMemberModel->getMembers($group_id); - } - - public function addGroupMember($group_id, $user_id) - { - return $this->groupMemberModel->addUser($group_id, $user_id); - } - - public function removeGroupMember($group_id, $user_id) - { - return $this->groupMemberModel->removeUser($group_id, $user_id); - } - - public function isGroupMember($group_id, $user_id) - { - return $this->groupMemberModel->isMember($group_id, $user_id); - } -} diff --git a/sources/app/Api/Procedure/GroupProcedure.php b/sources/app/Api/Procedure/GroupProcedure.php deleted file mode 100644 index 804940a..0000000 --- a/sources/app/Api/Procedure/GroupProcedure.php +++ /dev/null @@ -1,49 +0,0 @@ -groupModel->create($name, $external_id); - } - - public function updateGroup($group_id, $name = null, $external_id = null) - { - $values = array( - 'id' => $group_id, - 'name' => $name, - 'external_id' => $external_id, - ); - - foreach ($values as $key => $value) { - if (is_null($value)) { - unset($values[$key]); - } - } - - return $this->groupModel->update($values); - } - - public function removeGroup($group_id) - { - return $this->groupModel->remove($group_id); - } - - public function getGroup($group_id) - { - return $this->groupModel->getById($group_id); - } - - public function getAllGroups() - { - return $this->groupModel->getAll(); - } -} diff --git a/sources/app/Api/Procedure/LinkProcedure.php b/sources/app/Api/Procedure/LinkProcedure.php deleted file mode 100644 index b4cecf3..0000000 --- a/sources/app/Api/Procedure/LinkProcedure.php +++ /dev/null @@ -1,111 +0,0 @@ -linkModel->getById($link_id); - } - - /** - * Get a link by name - * - * @access public - * @param string $label - * @return array - */ - public function getLinkByLabel($label) - { - return $this->linkModel->getByLabel($label); - } - - /** - * Get the opposite link id - * - * @access public - * @param integer $link_id Link id - * @return integer - */ - public function getOppositeLinkId($link_id) - { - return $this->linkModel->getOppositeLinkId($link_id); - } - - /** - * Get all links - * - * @access public - * @return array - */ - public function getAllLinks() - { - return $this->linkModel->getAll(); - } - - /** - * Create a new link label - * - * @access public - * @param string $label - * @param string $opposite_label - * @return boolean|integer - */ - public function createLink($label, $opposite_label = '') - { - $values = array( - 'label' => $label, - 'opposite_label' => $opposite_label, - ); - - list($valid, ) = $this->linkValidator->validateCreation($values); - return $valid ? $this->linkModel->create($label, $opposite_label) : false; - } - - /** - * Update a link - * - * @access public - * @param integer $link_id - * @param integer $opposite_link_id - * @param string $label - * @return boolean - */ - public function updateLink($link_id, $opposite_link_id, $label) - { - $values = array( - 'id' => $link_id, - 'opposite_id' => $opposite_link_id, - 'label' => $label, - ); - - list($valid, ) = $this->linkValidator->validateModification($values); - return $valid && $this->linkModel->update($values); - } - - /** - * Remove a link a the relation to its opposite - * - * @access public - * @param integer $link_id - * @return boolean - */ - public function removeLink($link_id) - { - return $this->linkModel->remove($link_id); - } -} diff --git a/sources/app/Api/Procedure/MeProcedure.php b/sources/app/Api/Procedure/MeProcedure.php deleted file mode 100644 index e59e652..0000000 --- a/sources/app/Api/Procedure/MeProcedure.php +++ /dev/null @@ -1,72 +0,0 @@ -sessionStorage->user; - } - - public function getMyDashboard() - { - $user_id = $this->userSession->getId(); - $projects = $this->projectModel->getQueryColumnStats($this->projectPermissionModel->getActiveProjectIds($user_id))->findAll(); - $tasks = $this->taskFinderModel->getUserQuery($user_id)->findAll(); - - return array( - 'projects' => $this->formatProjects($projects), - 'tasks' => $this->formatTasks($tasks), - 'subtasks' => $this->subtaskModel->getUserQuery($user_id, array(SubtaskModel::STATUS_TODO, SubtaskModel::STATUS_INPROGRESS))->findAll(), - ); - } - - public function getMyActivityStream() - { - $project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId()); - return $this->helper->projectActivity->getProjectsEvents($project_ids, 100); - } - - public function createMyPrivateProject($name, $description = null) - { - if ($this->configModel->get('disable_private_project', 0) == 1) { - return false; - } - - $values = array( - 'name' => $name, - 'description' => $description, - 'is_private' => 1, - ); - - list($valid, ) = $this->projectValidator->validateCreation($values); - return $valid ? $this->projectModel->create($values, $this->userSession->getId(), true) : false; - } - - public function getMyProjectsList() - { - return $this->projectUserRoleModel->getProjectsByUser($this->userSession->getId()); - } - - public function getMyOverdueTasks() - { - return $this->taskFinderModel->getOverdueTasksByUser($this->userSession->getId()); - } - - public function getMyProjects() - { - $project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId()); - $projects = $this->projectModel->getAllByIds($project_ids); - - return $this->formatProjects($projects); - } -} diff --git a/sources/app/Api/Procedure/ProjectFileProcedure.php b/sources/app/Api/Procedure/ProjectFileProcedure.php deleted file mode 100644 index 48466ce..0000000 --- a/sources/app/Api/Procedure/ProjectFileProcedure.php +++ /dev/null @@ -1,68 +0,0 @@ -container)->check($this->getClassName(), 'getProjectFile', $project_id); - return $this->projectFileModel->getById($file_id); - } - - public function getAllProjectFiles($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllProjectFiles', $project_id); - return $this->projectFileModel->getAll($project_id); - } - - public function downloadProjectFile($project_id, $file_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'downloadProjectFile', $project_id); - - try { - $file = $this->projectFileModel->getById($file_id); - - if (! empty($file)) { - return base64_encode($this->objectStorage->get($file['path'])); - } - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - } - - return ''; - } - - public function createProjectFile($project_id, $filename, $blob) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createProjectFile', $project_id); - - try { - return $this->projectFileModel->uploadContent($project_id, $filename, $blob); - } catch (ObjectStorageException $e) { - $this->logger->error(__METHOD__.': '.$e->getMessage()); - return false; - } - } - - public function removeProjectFile($project_id, $file_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectFile', $project_id); - return $this->projectFileModel->remove($file_id); - } - - public function removeAllProjectFiles($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAllProjectFiles', $project_id); - return $this->projectFileModel->removeAll($project_id); - } -} diff --git a/sources/app/Api/Procedure/ProjectPermissionProcedure.php b/sources/app/Api/Procedure/ProjectPermissionProcedure.php deleted file mode 100644 index e22e1d6..0000000 --- a/sources/app/Api/Procedure/ProjectPermissionProcedure.php +++ /dev/null @@ -1,69 +0,0 @@ -container)->check($this->getClassName(), 'getProjectUsers', $project_id); - return $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); - } - - public function addProjectUser($project_id, $user_id, $role = Role::PROJECT_MEMBER) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addProjectUser', $project_id); - return $this->projectUserRoleModel->addUser($project_id, $user_id, $role); - } - - public function addProjectGroup($project_id, $group_id, $role = Role::PROJECT_MEMBER) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addProjectGroup', $project_id); - return $this->projectGroupRoleModel->addGroup($project_id, $group_id, $role); - } - - public function removeProjectUser($project_id, $user_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectUser', $project_id); - return $this->projectUserRoleModel->removeUser($project_id, $user_id); - } - - public function removeProjectGroup($project_id, $group_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectGroup', $project_id); - return $this->projectGroupRoleModel->removeGroup($project_id, $group_id); - } - - public function changeProjectUserRole($project_id, $user_id, $role) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeProjectUserRole', $project_id); - return $this->projectUserRoleModel->changeUserRole($project_id, $user_id, $role); - } - - public function changeProjectGroupRole($project_id, $group_id, $role) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeProjectGroupRole', $project_id); - return $this->projectGroupRoleModel->changeGroupRole($project_id, $group_id, $role); - } - - public function getProjectUserRole($project_id, $user_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectUserRole', $project_id); - return $this->projectUserRoleModel->getUserRole($project_id, $user_id); - } -} diff --git a/sources/app/Api/Procedure/ProjectProcedure.php b/sources/app/Api/Procedure/ProjectProcedure.php deleted file mode 100644 index a580c8d..0000000 --- a/sources/app/Api/Procedure/ProjectProcedure.php +++ /dev/null @@ -1,113 +0,0 @@ -container)->check($this->getClassName(), 'getProjectById', $project_id); - return $this->formatProject($this->projectModel->getById($project_id)); - } - - public function getProjectByName($name) - { - $project = $this->projectModel->getByName($name); - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByName', $project['id']); - return $this->formatProject($project); - } - - public function getProjectByIdentifier($identifier) - { - $project = $this->formatProject($this->projectModel->getByIdentifier($identifier)); - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByIdentifier', $project['id']); - return $this->formatProject($project); - } - - public function getAllProjects() - { - return $this->formatProjects($this->projectModel->getAll()); - } - - public function removeProject($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProject', $project_id); - return $this->projectModel->remove($project_id); - } - - public function enableProject($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableProject', $project_id); - return $this->projectModel->enable($project_id); - } - - public function disableProject($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableProject', $project_id); - return $this->projectModel->disable($project_id); - } - - public function enableProjectPublicAccess($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableProjectPublicAccess', $project_id); - return $this->projectModel->enablePublicAccess($project_id); - } - - public function disableProjectPublicAccess($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableProjectPublicAccess', $project_id); - return $this->projectModel->disablePublicAccess($project_id); - } - - public function getProjectActivities(array $project_ids) - { - foreach ($project_ids as $project_id) { - ProjectAuthorization::getInstance($this->container) - ->check($this->getClassName(), 'getProjectActivities', $project_id); - } - - return $this->helper->projectActivity->getProjectsEvents($project_ids); - } - - public function getProjectActivity($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectActivity', $project_id); - return $this->helper->projectActivity->getProjectEvents($project_id); - } - - public function createProject($name, $description = null, $owner_id = 0, $identifier = null) - { - $values = $this->filterValues(array( - 'name' => $name, - 'description' => $description, - 'identifier' => $identifier, - )); - - list($valid, ) = $this->projectValidator->validateCreation($values); - return $valid ? $this->projectModel->create($values, $owner_id, $this->userSession->isLogged()) : false; - } - - public function updateProject($project_id, $name = null, $description = null, $owner_id = null, $identifier = null) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateProject', $project_id); - - $values = $this->filterValues(array( - 'id' => $project_id, - 'name' => $name, - 'description' => $description, - 'owner_id' => $owner_id, - 'identifier' => $identifier, - )); - - list($valid, ) = $this->projectValidator->validateModification($values); - return $valid && $this->projectModel->update($values); - } -} diff --git a/sources/app/Api/Procedure/SubtaskProcedure.php b/sources/app/Api/Procedure/SubtaskProcedure.php deleted file mode 100644 index e240091..0000000 --- a/sources/app/Api/Procedure/SubtaskProcedure.php +++ /dev/null @@ -1,74 +0,0 @@ -container)->check($this->getClassName(), 'getSubtask', $subtask_id); - return $this->subtaskModel->getById($subtask_id); - } - - public function getAllSubtasks($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllSubtasks', $task_id); - return $this->subtaskModel->getAll($task_id); - } - - public function removeSubtask($subtask_id) - { - SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeSubtask', $subtask_id); - return $this->subtaskModel->remove($subtask_id); - } - - public function createSubtask($task_id, $title, $user_id = 0, $time_estimated = 0, $time_spent = 0, $status = 0) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createSubtask', $task_id); - - $values = array( - 'title' => $title, - 'task_id' => $task_id, - 'user_id' => $user_id, - 'time_estimated' => $time_estimated, - 'time_spent' => $time_spent, - 'status' => $status, - ); - - list($valid, ) = $this->subtaskValidator->validateCreation($values); - return $valid ? $this->subtaskModel->create($values) : false; - } - - public function updateSubtask($id, $task_id, $title = null, $user_id = null, $time_estimated = null, $time_spent = null, $status = null) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateSubtask', $task_id); - - $values = array( - 'id' => $id, - 'task_id' => $task_id, - 'title' => $title, - 'user_id' => $user_id, - 'time_estimated' => $time_estimated, - 'time_spent' => $time_spent, - 'status' => $status, - ); - - foreach ($values as $key => $value) { - if (is_null($value)) { - unset($values[$key]); - } - } - - list($valid, ) = $this->subtaskValidator->validateApiModification($values); - return $valid && $this->subtaskModel->update($values); - } -} diff --git a/sources/app/Api/Procedure/SubtaskTimeTrackingProcedure.php b/sources/app/Api/Procedure/SubtaskTimeTrackingProcedure.php deleted file mode 100644 index 5ceaa08..0000000 --- a/sources/app/Api/Procedure/SubtaskTimeTrackingProcedure.php +++ /dev/null @@ -1,39 +0,0 @@ -container)->check($this->getClassName(), 'hasSubtaskTimer', $subtask_id); - return $this->subtaskTimeTrackingModel->hasTimer($subtask_id, $user_id); - } - - public function setSubtaskStartTime($subtask_id, $user_id) - { - SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'setSubtaskStartTime', $subtask_id); - return $this->subtaskTimeTrackingModel->logStartTime($subtask_id, $user_id); - } - - public function setSubtaskEndTime($subtask_id, $user_id) - { - SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'setSubtaskEndTime', $subtask_id); - return $this->subtaskTimeTrackingModel->logEndTime($subtask_id, $user_id); - } - - public function getSubtaskTimeSpent($subtask_id, $user_id) - { - SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSubtaskTimeSpent', $subtask_id); - return $this->subtaskTimeTrackingModel->getTimeSpent($subtask_id, $user_id); - } -} diff --git a/sources/app/Api/Procedure/SwimlaneProcedure.php b/sources/app/Api/Procedure/SwimlaneProcedure.php deleted file mode 100644 index 9b7d181..0000000 --- a/sources/app/Api/Procedure/SwimlaneProcedure.php +++ /dev/null @@ -1,91 +0,0 @@ -container)->check($this->getClassName(), 'getActiveSwimlanes', $project_id); - return $this->swimlaneModel->getSwimlanes($project_id); - } - - public function getAllSwimlanes($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllSwimlanes', $project_id); - return $this->swimlaneModel->getAll($project_id); - } - - public function getSwimlaneById($swimlane_id) - { - $swimlane = $this->swimlaneModel->getById($swimlane_id); - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSwimlaneById', $swimlane['project_id']); - return $swimlane; - } - - public function getSwimlaneByName($project_id, $name) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSwimlaneByName', $project_id); - return $this->swimlaneModel->getByName($project_id, $name); - } - - public function getSwimlane($swimlane_id) - { - return $this->swimlaneModel->getById($swimlane_id); - } - - public function getDefaultSwimlane($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getDefaultSwimlane', $project_id); - return $this->swimlaneModel->getDefault($project_id); - } - - public function addSwimlane($project_id, $name, $description = '') - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addSwimlane', $project_id); - return $this->swimlaneModel->create(array('project_id' => $project_id, 'name' => $name, 'description' => $description)); - } - - public function updateSwimlane($swimlane_id, $name, $description = null) - { - $values = array('id' => $swimlane_id, 'name' => $name); - - if (!is_null($description)) { - $values['description'] = $description; - } - - return $this->swimlaneModel->update($values); - } - - public function removeSwimlane($project_id, $swimlane_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeSwimlane', $project_id); - return $this->swimlaneModel->remove($project_id, $swimlane_id); - } - - public function disableSwimlane($project_id, $swimlane_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableSwimlane', $project_id); - return $this->swimlaneModel->disable($project_id, $swimlane_id); - } - - public function enableSwimlane($project_id, $swimlane_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableSwimlane', $project_id); - return $this->swimlaneModel->enable($project_id, $swimlane_id); - } - - public function changeSwimlanePosition($project_id, $swimlane_id, $position) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeSwimlanePosition', $project_id); - return $this->swimlaneModel->changePosition($project_id, $swimlane_id, $position); - } -} diff --git a/sources/app/Api/Procedure/TaskExternalLinkProcedure.php b/sources/app/Api/Procedure/TaskExternalLinkProcedure.php deleted file mode 100644 index 05ec690..0000000 --- a/sources/app/Api/Procedure/TaskExternalLinkProcedure.php +++ /dev/null @@ -1,106 +0,0 @@ -externalLinkManager->getTypes(); - } - - public function getExternalTaskLinkProviderDependencies($providerName) - { - try { - return $this->externalLinkManager->getProvider($providerName)->getDependencies(); - } catch (ExternalLinkProviderNotFound $e) { - $this->logger->error(__METHOD__.': '.$e->getMessage()); - return false; - } - } - - public function getExternalTaskLinkById($task_id, $link_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getExternalTaskLink', $task_id); - return $this->taskExternalLinkModel->getById($link_id); - } - - public function getAllExternalTaskLinks($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getExternalTaskLinks', $task_id); - return $this->taskExternalLinkModel->getAll($task_id); - } - - public function createExternalTaskLink($task_id, $url, $dependency, $type = ExternalLinkManager::TYPE_AUTO, $title = '') - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createExternalTaskLink', $task_id); - - try { - $provider = $this->externalLinkManager - ->setUserInputText($url) - ->setUserInputType($type) - ->find(); - - $link = $provider->getLink(); - - $values = array( - 'task_id' => $task_id, - 'title' => $title ?: $link->getTitle(), - 'url' => $link->getUrl(), - 'link_type' => $provider->getType(), - 'dependency' => $dependency, - ); - - list($valid, $errors) = $this->externalLinkValidator->validateCreation($values); - - if (! $valid) { - $this->logger->error(__METHOD__.': '.var_export($errors)); - return false; - } - - return $this->taskExternalLinkModel->create($values); - } catch (ExternalLinkProviderNotFound $e) { - $this->logger->error(__METHOD__.': '.$e->getMessage()); - } - - return false; - } - - public function updateExternalTaskLink($task_id, $link_id, $title = null, $url = null, $dependency = null) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateExternalTaskLink', $task_id); - - $link = $this->taskExternalLinkModel->getById($link_id); - $values = $this->filterValues(array( - 'title' => $title, - 'url' => $url, - 'dependency' => $dependency, - )); - - $values = array_merge($link, $values); - list($valid, $errors) = $this->externalLinkValidator->validateModification($values); - - if (! $valid) { - $this->logger->error(__METHOD__.': '.var_export($errors)); - return false; - } - - return $this->taskExternalLinkModel->update($values); - } - - public function removeExternalTaskLink($task_id, $link_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeExternalTaskLink', $task_id); - return $this->taskExternalLinkModel->remove($link_id); - } -} diff --git a/sources/app/Api/Procedure/TaskFileProcedure.php b/sources/app/Api/Procedure/TaskFileProcedure.php deleted file mode 100644 index bd00657..0000000 --- a/sources/app/Api/Procedure/TaskFileProcedure.php +++ /dev/null @@ -1,70 +0,0 @@ -container)->check($this->getClassName(), 'getTaskFile', $file_id); - return $this->taskFileModel->getById($file_id); - } - - public function getAllTaskFiles($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTaskFiles', $task_id); - return $this->taskFileModel->getAll($task_id); - } - - public function downloadTaskFile($file_id) - { - TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'downloadTaskFile', $file_id); - - try { - $file = $this->taskFileModel->getById($file_id); - - if (! empty($file)) { - return base64_encode($this->objectStorage->get($file['path'])); - } - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - } - - return ''; - } - - public function createTaskFile($project_id, $task_id, $filename, $blob) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskFile', $project_id); - - try { - return $this->taskFileModel->uploadContent($task_id, $filename, $blob); - } catch (ObjectStorageException $e) { - $this->logger->error(__METHOD__.': '.$e->getMessage()); - return false; - } - } - - public function removeTaskFile($file_id) - { - TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskFile', $file_id); - return $this->taskFileModel->remove($file_id); - } - - public function removeAllTaskFiles($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAllTaskFiles', $task_id); - return $this->taskFileModel->removeAll($task_id); - } -} diff --git a/sources/app/Api/Procedure/TaskLinkProcedure.php b/sources/app/Api/Procedure/TaskLinkProcedure.php deleted file mode 100644 index 375266f..0000000 --- a/sources/app/Api/Procedure/TaskLinkProcedure.php +++ /dev/null @@ -1,85 +0,0 @@ -container)->check($this->getClassName(), 'getTaskLinkById', $task_link_id); - return $this->taskLinkModel->getById($task_link_id); - } - - /** - * Get all links attached to a task - * - * @access public - * @param integer $task_id Task id - * @return array - */ - public function getAllTaskLinks($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTaskLinks', $task_id); - return $this->taskLinkModel->getAll($task_id); - } - - /** - * Create a new link - * - * @access public - * @param integer $task_id Task id - * @param integer $opposite_task_id Opposite task id - * @param integer $link_id Link id - * @return integer Task link id - */ - public function createTaskLink($task_id, $opposite_task_id, $link_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskLink', $task_id); - return $this->taskLinkModel->create($task_id, $opposite_task_id, $link_id); - } - - /** - * Update a task link - * - * @access public - * @param integer $task_link_id Task link id - * @param integer $task_id Task id - * @param integer $opposite_task_id Opposite task id - * @param integer $link_id Link id - * @return boolean - */ - public function updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTaskLink', $task_id); - return $this->taskLinkModel->update($task_link_id, $task_id, $opposite_task_id, $link_id); - } - - /** - * Remove a link between two tasks - * - * @access public - * @param integer $task_link_id - * @return boolean - */ - public function removeTaskLink($task_link_id) - { - TaskLinkAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskLink', $task_link_id); - return $this->taskLinkModel->remove($task_link_id); - } -} diff --git a/sources/app/Api/Procedure/TaskProcedure.php b/sources/app/Api/Procedure/TaskProcedure.php deleted file mode 100644 index 8661dee..0000000 --- a/sources/app/Api/Procedure/TaskProcedure.php +++ /dev/null @@ -1,167 +0,0 @@ -container)->check($this->getClassName(), 'searchTasks', $project_id); - return $this->taskLexer->build($query)->withFilter(new TaskProjectFilter($project_id))->toArray(); - } - - public function getTask($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTask', $task_id); - return $this->formatTask($this->taskFinderModel->getById($task_id)); - } - - public function getTaskByReference($project_id, $reference) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskByReference', $project_id); - return $this->formatTask($this->taskFinderModel->getByReference($project_id, $reference)); - } - - public function getAllTasks($project_id, $status_id = TaskModel::STATUS_OPEN) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTasks', $project_id); - return $this->formatTasks($this->taskFinderModel->getAll($project_id, $status_id)); - } - - public function getOverdueTasks() - { - return $this->taskFinderModel->getOverdueTasks(); - } - - public function getOverdueTasksByProject($project_id) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getOverdueTasksByProject', $project_id); - return $this->taskFinderModel->getOverdueTasksByProject($project_id); - } - - public function openTask($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'openTask', $task_id); - return $this->taskStatusModel->open($task_id); - } - - public function closeTask($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'closeTask', $task_id); - return $this->taskStatusModel->close($task_id); - } - - public function removeTask($task_id) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTask', $task_id); - return $this->taskModel->remove($task_id); - } - - public function moveTaskPosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskPosition', $project_id); - return $this->taskPositionModel->movePosition($project_id, $task_id, $column_id, $position, $swimlane_id); - } - - public function moveTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskToProject', $project_id); - return $this->taskProjectMoveModel->moveToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id); - } - - public function duplicateTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null) - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'duplicateTaskToProject', $project_id); - return $this->taskProjectDuplicationModel->duplicateToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id); - } - - 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 = '') - { - ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTask', $project_id); - - if ($owner_id !== 0 && ! $this->projectPermissionModel->isAssignable($project_id, $owner_id)) { - return false; - } - - if ($this->userSession->isLogged()) { - $creator_id = $this->userSession->getId(); - } - - $values = array( - 'title' => $title, - 'project_id' => $project_id, - 'color_id' => $color_id, - 'column_id' => $column_id, - 'owner_id' => $owner_id, - 'creator_id' => $creator_id, - 'date_due' => $date_due, - 'description' => $description, - 'category_id' => $category_id, - 'score' => $score, - 'swimlane_id' => $swimlane_id, - 'recurrence_status' => $recurrence_status, - 'recurrence_trigger' => $recurrence_trigger, - 'recurrence_factor' => $recurrence_factor, - 'recurrence_timeframe' => $recurrence_timeframe, - 'recurrence_basedate' => $recurrence_basedate, - 'reference' => $reference, - 'priority' => $priority, - ); - - list($valid, ) = $this->taskValidator->validateCreation($values); - - return $valid ? $this->taskCreationModel->create($values) : false; - } - - 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) - { - TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTask', $id); - $project_id = $this->taskFinderModel->getProjectId($id); - - if ($project_id === 0) { - return false; - } - - if ($owner_id !== null && $owner_id != 0 && ! $this->projectPermissionModel->isAssignable($project_id, $owner_id)) { - return false; - } - - $values = $this->filterValues(array( - 'id' => $id, - 'title' => $title, - 'color_id' => $color_id, - 'owner_id' => $owner_id, - 'date_due' => $date_due, - 'description' => $description, - 'category_id' => $category_id, - 'score' => $score, - 'recurrence_status' => $recurrence_status, - 'recurrence_trigger' => $recurrence_trigger, - 'recurrence_factor' => $recurrence_factor, - 'recurrence_timeframe' => $recurrence_timeframe, - 'recurrence_basedate' => $recurrence_basedate, - 'reference' => $reference, - 'priority' => $priority, - )); - - list($valid) = $this->taskValidator->validateApiModification($values); - return $valid && $this->taskModificationModel->update($values); - } -} diff --git a/sources/app/Api/Procedure/UserProcedure.php b/sources/app/Api/Procedure/UserProcedure.php deleted file mode 100644 index 145f85b..0000000 --- a/sources/app/Api/Procedure/UserProcedure.php +++ /dev/null @@ -1,131 +0,0 @@ -userModel->getById($user_id); - } - - public function getUserByName($username) - { - return $this->userModel->getByUsername($username); - } - - public function getAllUsers() - { - return $this->userModel->getAll(); - } - - public function removeUser($user_id) - { - return $this->userModel->remove($user_id); - } - - public function disableUser($user_id) - { - return $this->userModel->disable($user_id); - } - - public function enableUser($user_id) - { - return $this->userModel->enable($user_id); - } - - public function isActiveUser($user_id) - { - return $this->userModel->isActive($user_id); - } - - public function createUser($username, $password, $name = '', $email = '', $role = Role::APP_USER) - { - $values = array( - 'username' => $username, - 'password' => $password, - 'confirmation' => $password, - 'name' => $name, - 'email' => $email, - 'role' => $role, - ); - - list($valid, ) = $this->userValidator->validateCreation($values); - return $valid ? $this->userModel->create($values) : false; - } - - /** - * Create LDAP user in the database - * - * Only "anonymous" and "proxy" LDAP authentication are supported by this method - * - * User information will be fetched from the LDAP server - * - * @access public - * @param string $username - * @return bool|int - */ - public function createLdapUser($username) - { - if (LDAP_BIND_TYPE === 'user') { - $this->logger->error('LDAP authentication "user" is not supported by this API call'); - return false; - } - - try { - - $ldap = LdapClient::connect(); - $ldap->setLogger($this->logger); - $user = LdapUser::getUser($ldap, $username); - - if ($user === null) { - $this->logger->info('User not found in LDAP server'); - return false; - } - - if ($user->getUsername() === '') { - throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME'); - } - - $values = array( - 'username' => $user->getUsername(), - 'name' => $user->getName(), - 'email' => $user->getEmail(), - 'role' => $user->getRole(), - 'is_ldap_user' => 1, - ); - - return $this->userModel->create($values); - - } catch (LdapException $e) { - $this->logger->error($e->getMessage()); - return false; - } - } - - public function updateUser($id, $username = null, $name = null, $email = null, $role = null) - { - $values = $this->filterValues(array( - 'id' => $id, - 'username' => $username, - 'name' => $name, - 'email' => $email, - 'role' => $role, - )); - - list($valid, ) = $this->userValidator->validateApiModification($values); - return $valid && $this->userModel->update($values); - } -} diff --git a/sources/app/Auth/DatabaseAuth.php b/sources/app/Auth/DatabaseAuth.php deleted file mode 100644 index ecb42c1..0000000 --- a/sources/app/Auth/DatabaseAuth.php +++ /dev/null @@ -1,126 +0,0 @@ -db - ->table(UserModel::TABLE) - ->columns('id', 'password') - ->eq('username', $this->username) - ->eq('disable_login_form', 0) - ->eq('is_ldap_user', 0) - ->eq('is_active', 1) - ->findOne(); - - if (! empty($user) && password_verify($this->password, $user['password'])) { - $this->userInfo = $user; - return true; - } - - return false; - } - - /** - * Check if the user session is valid - * - * @access public - * @return boolean - */ - public function isValidSession() - { - return $this->userModel->isActive($this->userSession->getId()); - } - - /** - * 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/sources/app/Auth/LdapAuth.php b/sources/app/Auth/LdapAuth.php deleted file mode 100644 index a8dcfcb..0000000 --- a/sources/app/Auth/LdapAuth.php +++ /dev/null @@ -1,176 +0,0 @@ -getLdapUsername(), $this->getLdapPassword()); - $client->setLogger($this->logger); - - $user = LdapUser::getUser($client, $this->username); - - if ($user === null) { - $this->logger->info('User ('.$this->username.') not found in LDAP server'); - return false; - } - - if ($user->getUsername() === '') { - throw new LogicException('Username not found in LDAP profile, check the parameter LDAP_USER_ATTRIBUTE_USERNAME'); - } - - $this->logger->info('Authenticate this user: '.$user->getDn()); - - if ($client->authenticate($user->getDn(), $this->password)) { - $this->userInfo = $user; - return true; - } - - } catch (LdapException $e) { - $this->logger->error($e->getMessage()); - } - - return false; - } - - /** - * Get user object - * - * @access public - * @return \Kanboard\User\LdapUserProvider - */ - public function getUser() - { - return $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; - } - - /** - * Get LDAP username (proxy auth) - * - * @access public - * @return string - */ - public function getLdapUsername() - { - switch ($this->getLdapBindType()) { - case 'proxy': - return LDAP_USERNAME; - case 'user': - return sprintf(LDAP_USERNAME, $this->username); - default: - return null; - } - } - - /** - * Get LDAP password (proxy auth) - * - * @access public - * @return string - */ - public function getLdapPassword() - { - switch ($this->getLdapBindType()) { - case 'proxy': - return LDAP_PASSWORD; - case 'user': - return $this->password; - default: - return null; - } - } - - /** - * Get LDAP bind type - * - * @access public - * @return integer - */ - public function getLdapBindType() - { - if (LDAP_BIND_TYPE !== 'user' && LDAP_BIND_TYPE !== 'proxy' && LDAP_BIND_TYPE !== 'anonymous') { - throw new LogicException('Wrong value for the parameter LDAP_BIND_TYPE'); - } - - return LDAP_BIND_TYPE; - } -} diff --git a/sources/app/Auth/RememberMeAuth.php b/sources/app/Auth/RememberMeAuth.php deleted file mode 100644 index 5d0a8b2..0000000 --- a/sources/app/Auth/RememberMeAuth.php +++ /dev/null @@ -1,79 +0,0 @@ -rememberMeCookie->read(); - - if ($credentials !== false) { - $session = $this->rememberMeSessionModel->find($credentials['token'], $credentials['sequence']); - - if (! empty($session)) { - $this->rememberMeCookie->write( - $session['token'], - $this->rememberMeSessionModel->updateSequence($session['token']), - $session['expiration'] - ); - - $this->userInfo = $this->userModel->getById($session['user_id']); - - return true; - } - } - - return false; - } - - /** - * Get user object - * - * @access public - * @return DatabaseUserProvider - */ - public function getUser() - { - if (empty($this->userInfo)) { - return null; - } - - return new DatabaseUserProvider($this->userInfo); - } -} diff --git a/sources/app/Auth/ReverseProxyAuth.php b/sources/app/Auth/ReverseProxyAuth.php deleted file mode 100644 index fdf936b..0000000 --- a/sources/app/Auth/ReverseProxyAuth.php +++ /dev/null @@ -1,77 +0,0 @@ -request->getRemoteUser(); - - if (! empty($username)) { - $userProfile = $this->userModel->getByUsername($username); - $this->userInfo = new ReverseProxyUserProvider($username, $userProfile ?: array()); - return true; - } - - return false; - } - - /** - * Check if the user session is valid - * - * @access public - * @return boolean - */ - public function isValidSession() - { - return $this->request->getRemoteUser() === $this->userSession->getUsername(); - } - - /** - * Get user object - * - * @access public - * @return ReverseProxyUserProvider - */ - public function getUser() - { - return $this->userInfo; - } -} diff --git a/sources/app/Auth/TotpAuth.php b/sources/app/Auth/TotpAuth.php deleted file mode 100644 index f430493..0000000 --- a/sources/app/Auth/TotpAuth.php +++ /dev/null @@ -1,144 +0,0 @@ -checkTotp(Base32::decode($this->secret), $this->code); - } - - /** - * Called before to prompt the user - * - * @access public - */ - public function beforeCode() - { - - } - - /** - * Set validation code - * - * @access public - * @param string $code - */ - public function setCode($code) - { - $this->code = $code; - } - - /** - * Generate secret - * - * @access public - * @return string - */ - public function generateSecret() - { - $this->secret = GoogleAuthenticator::generateRandom(); - return $this->secret; - } - - /** - * Set secret token - * - * @access public - * @param string $secret - */ - public function setSecret($secret) - { - $this->secret = $secret; - } - - /** - * Get secret token - * - * @access public - * @return string - */ - public function getSecret() - { - return $this->secret; - } - - /** - * Get QR code url - * - * @access public - * @param string $label - * @return string - */ - public function getQrCodeUrl($label) - { - if (empty($this->secret)) { - return ''; - } - - return GoogleAuthenticator::getQrCodeUrl('totp', $label, $this->secret); - } - - /** - * Get key url (empty if no url can be provided) - * - * @access public - * @param string $label - * @return string - */ - public function getKeyUrl($label) - { - if (empty($this->secret)) { - return ''; - } - - return GoogleAuthenticator::getKeyUri('totp', $label, $this->secret); - } -} diff --git a/sources/app/Console/BaseCommand.php b/sources/app/Console/BaseCommand.php deleted file mode 100644 index 5041707..0000000 --- a/sources/app/Console/BaseCommand.php +++ /dev/null @@ -1,67 +0,0 @@ -container = $container; - } - - /** - * Load automatically models - * - * @access public - * @param string $name Model name - * @return mixed - */ - public function __get($name) - { - return $this->container[$name]; - } -} diff --git a/sources/app/Console/CronjobCommand.php b/sources/app/Console/CronjobCommand.php deleted file mode 100644 index dae13af..0000000 --- a/sources/app/Console/CronjobCommand.php +++ /dev/null @@ -1,32 +0,0 @@ -setName('cronjob') - ->setDescription('Execute daily cronjob'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - foreach ($this->commands as $command) { - $job = $this->getApplication()->find($command); - $job->run(new ArrayInput(array('command' => $command)), new NullOutput()); - } - } -} diff --git a/sources/app/Console/LocaleComparatorCommand.php b/sources/app/Console/LocaleComparatorCommand.php deleted file mode 100644 index de83714..0000000 --- a/sources/app/Console/LocaleComparatorCommand.php +++ /dev/null @@ -1,81 +0,0 @@ -setName('locale:compare') - ->setDescription('Compare application translations with the '.self::REF_LOCALE.' locale'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $strings = array(); - $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('app')); - $it->rewind(); - - while ($it->valid()) { - if (! $it->isDot() && substr($it->key(), -4) === '.php') { - $strings = array_merge($strings, $this->search($it->key())); - } - - $it->next(); - } - - $this->compare(array_unique($strings)); - } - - public function show(array $strings) - { - foreach ($strings as $string) { - echo " '".str_replace("'", "\'", $string)."' => '',".PHP_EOL; - } - } - - public function compare(array $strings) - { - $reference_file = 'app/Locale/'.self::REF_LOCALE.'/translations.php'; - $reference = include $reference_file; - - echo str_repeat('#', 70).PHP_EOL; - echo 'MISSING STRINGS'.PHP_EOL; - echo str_repeat('#', 70).PHP_EOL; - $this->show(array_diff($strings, array_keys($reference))); - - echo str_repeat('#', 70).PHP_EOL; - echo 'USELESS STRINGS'.PHP_EOL; - echo str_repeat('#', 70).PHP_EOL; - $this->show(array_diff(array_keys($reference), $strings)); - } - - public function search($filename) - { - $content = file_get_contents($filename); - $strings = array(); - - if (preg_match_all('/\b[et]\((\'\K.*?\') *[\)\,]/', $content, $matches) && isset($matches[1])) { - $strings = $matches[1]; - } - - if (preg_match_all('/\bdt\((\'\K.*?\') *[\)\,]/', $content, $matches) && isset($matches[1])) { - $strings = array_merge($strings, $matches[1]); - } - - array_walk($strings, function (&$value) { - $value = trim($value, "'"); - $value = str_replace("\'", "'", $value); - }); - - return $strings; - } -} diff --git a/sources/app/Console/LocaleSyncCommand.php b/sources/app/Console/LocaleSyncCommand.php deleted file mode 100644 index 11cfbde..0000000 --- a/sources/app/Console/LocaleSyncCommand.php +++ /dev/null @@ -1,53 +0,0 @@ -setName('locale:sync') - ->setDescription('Synchronize all translations based on the '.self::REF_LOCALE.' locale'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $reference_file = 'app/Locale/'.self::REF_LOCALE.'/translations.php'; - $reference = include $reference_file; - - foreach (new DirectoryIterator('app/Locale') as $fileInfo) { - if (! $fileInfo->isDot() && $fileInfo->isDir() && $fileInfo->getFilename() !== self::REF_LOCALE) { - $filename = 'app/Locale/'.$fileInfo->getFilename().'/translations.php'; - echo $fileInfo->getFilename().' ('.$filename.')'.PHP_EOL; - - file_put_contents($filename, $this->updateFile($reference, $filename)); - } - } - } - - public function updateFile(array $reference, $outdated_file) - { - $outdated = include $outdated_file; - - $output = ' $value) { - if (! empty($outdated[$key])) { - $output .= " '".str_replace("'", "\'", $key)."' => '".str_replace("'", "\'", $outdated[$key])."',\n"; - } else { - $output .= " // '".str_replace("'", "\'", $key)."' => '',\n"; - } - } - - $output .= ");\n"; - return $output; - } -} diff --git a/sources/app/Console/PluginInstallCommand.php b/sources/app/Console/PluginInstallCommand.php deleted file mode 100644 index a82f006..0000000 --- a/sources/app/Console/PluginInstallCommand.php +++ /dev/null @@ -1,36 +0,0 @@ -setName('plugin:install') - ->setDescription('Install a plugin from a remote Zip archive') - ->addArgument('url', InputArgument::REQUIRED, 'Archive URL'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - if (!Installer::isConfigured()) { - throw new LogicException('Kanboard is not configured to install plugins itself'); - } - - try { - $installer = new Installer($this->container); - $installer->install($input->getArgument('url')); - $output->writeln('Plugin installed successfully'); - } catch (PluginInstallerException $e) { - $output->writeln(''.$e->getMessage().''); - } - } -} diff --git a/sources/app/Console/PluginUninstallCommand.php b/sources/app/Console/PluginUninstallCommand.php deleted file mode 100644 index 4872213..0000000 --- a/sources/app/Console/PluginUninstallCommand.php +++ /dev/null @@ -1,36 +0,0 @@ -setName('plugin:uninstall') - ->setDescription('Remove a plugin') - ->addArgument('pluginId', InputArgument::REQUIRED, 'Plugin directory name'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - if (!Installer::isConfigured()) { - throw new LogicException('Kanboard is not configured to install plugins itself'); - } - - try { - $installer = new Installer($this->container); - $installer->uninstall($input->getArgument('pluginId')); - $output->writeln('Plugin removed successfully'); - } catch (PluginInstallerException $e) { - $output->writeln(''.$e->getMessage().''); - } - } -} diff --git a/sources/app/Console/PluginUpgradeCommand.php b/sources/app/Console/PluginUpgradeCommand.php deleted file mode 100644 index 6c66e91..0000000 --- a/sources/app/Console/PluginUpgradeCommand.php +++ /dev/null @@ -1,55 +0,0 @@ -setName('plugin:upgrade') - ->setDescription('Update all installed plugins') - ; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - if (!Installer::isConfigured()) { - throw new LogicException('Kanboard is not configured to install plugins itself'); - } - - $installer = new Installer($this->container); - $availablePlugins = Directory::getInstance($this->container)->getAvailablePlugins(); - - foreach ($this->pluginLoader->getPlugins() as $installedPlugin) { - $pluginDetails = $this->getPluginDetails($availablePlugins, $installedPlugin); - - if ($pluginDetails === null) { - $output->writeln('* Plugin not available in the directory: '.$installedPlugin->getPluginName().''); - } elseif ($pluginDetails['version'] > $installedPlugin->getPluginVersion()) { - $output->writeln('* Updating plugin: '.$installedPlugin->getPluginName().''); - $installer->update($pluginDetails['download']); - } else { - $output->writeln('* Plugin up to date: '.$installedPlugin->getPluginName().''); - } - } - } - - protected function getPluginDetails(array $availablePlugins, BasePlugin $installedPlugin) - { - foreach ($availablePlugins as $availablePlugin) { - if ($availablePlugin['title'] === $installedPlugin->getPluginName()) { - return $availablePlugin; - } - } - - return null; - } -} diff --git a/sources/app/Console/ProjectDailyColumnStatsExportCommand.php b/sources/app/Console/ProjectDailyColumnStatsExportCommand.php deleted file mode 100644 index 1e8af72..0000000 --- a/sources/app/Console/ProjectDailyColumnStatsExportCommand.php +++ /dev/null @@ -1,34 +0,0 @@ -setName('export:daily-project-column-stats') - ->setDescription('Daily project column stats CSV export (number of tasks per column and per day)') - ->addArgument('project_id', InputArgument::REQUIRED, 'Project id') - ->addArgument('start_date', InputArgument::REQUIRED, 'Start date (YYYY-MM-DD)') - ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $data = $this->projectDailyColumnStatsModel->getAggregatedMetrics( - $input->getArgument('project_id'), - $input->getArgument('start_date'), - $input->getArgument('end_date') - ); - - if (is_array($data)) { - Csv::output($data); - } - } -} diff --git a/sources/app/Console/ProjectDailyStatsCalculationCommand.php b/sources/app/Console/ProjectDailyStatsCalculationCommand.php deleted file mode 100644 index 8dde8a7..0000000 --- a/sources/app/Console/ProjectDailyStatsCalculationCommand.php +++ /dev/null @@ -1,28 +0,0 @@ -setName('projects:daily-stats') - ->setDescription('Calculate daily statistics for all projects'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $projects = $this->projectModel->getAllByStatus(ProjectModel::ACTIVE); - - foreach ($projects as $project) { - $output->writeln('Run calculation for '.$project['name']); - $this->projectDailyColumnStatsModel->updateTotals($project['id'], date('Y-m-d')); - $this->projectDailyStatsModel->updateTotals($project['id'], date('Y-m-d')); - } - } -} diff --git a/sources/app/Console/ResetPasswordCommand.php b/sources/app/Console/ResetPasswordCommand.php deleted file mode 100644 index b483f90..0000000 --- a/sources/app/Console/ResetPasswordCommand.php +++ /dev/null @@ -1,79 +0,0 @@ -setName('user:reset-password') - ->setDescription('Change user password') - ->addArgument('username', InputArgument::REQUIRED, 'Username') - ; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $helper = $this->getHelper('question'); - $username = $input->getArgument('username'); - - $passwordQuestion = new Question('What is the new password for '.$username.'? (characters are not printed)'.PHP_EOL); - $passwordQuestion->setHidden(true); - $passwordQuestion->setHiddenFallback(false); - - $password = $helper->ask($input, $output, $passwordQuestion); - - $confirmationQuestion = new Question('Confirmation:'.PHP_EOL); - $confirmationQuestion->setHidden(true); - $confirmationQuestion->setHiddenFallback(false); - - $confirmation = $helper->ask($input, $output, $confirmationQuestion); - - if ($this->validatePassword($output, $password, $confirmation)) { - $this->resetPassword($output, $username, $password); - } - } - - private function validatePassword(OutputInterface $output, $password, $confirmation) - { - list($valid, $errors) = $this->passwordResetValidator->validateModification(array( - 'password' => $password, - 'confirmation' => $confirmation, - )); - - if (!$valid) { - foreach ($errors as $error_list) { - foreach ($error_list as $error) { - $output->writeln(''.$error.''); - } - } - } - - return $valid; - } - - private function resetPassword(OutputInterface $output, $username, $password) - { - $userId = $this->userModel->getIdByUsername($username); - - if (empty($userId)) { - $output->writeln('User not found'); - return false; - } - - if (!$this->userModel->update(array('id' => $userId, 'password' => $password))) { - $output->writeln('Unable to update password'); - return false; - } - - $output->writeln('Password updated successfully'); - - return true; - } -} diff --git a/sources/app/Console/ResetTwoFactorCommand.php b/sources/app/Console/ResetTwoFactorCommand.php deleted file mode 100644 index a64206b..0000000 --- a/sources/app/Console/ResetTwoFactorCommand.php +++ /dev/null @@ -1,38 +0,0 @@ -setName('user:reset-2fa') - ->setDescription('Remove two-factor authentication for a user') - ->addArgument('username', InputArgument::REQUIRED, 'Username'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $username = $input->getArgument('username'); - $userId = $this->userModel->getIdByUsername($username); - - if (empty($userId)) { - $output->writeln('User not found'); - return false; - } - - if (!$this->userModel->update(array('id' => $userId, 'twofactor_activated' => 0, 'twofactor_secret' => ''))) { - $output->writeln('Unable to update user profile'); - return false; - } - - $output->writeln('Two-factor authentication disabled'); - - return true; - } -} diff --git a/sources/app/Console/SubtaskExportCommand.php b/sources/app/Console/SubtaskExportCommand.php deleted file mode 100644 index 986af1a..0000000 --- a/sources/app/Console/SubtaskExportCommand.php +++ /dev/null @@ -1,34 +0,0 @@ -setName('export:subtasks') - ->setDescription('Subtasks CSV export') - ->addArgument('project_id', InputArgument::REQUIRED, 'Project id') - ->addArgument('start_date', InputArgument::REQUIRED, 'Start date (YYYY-MM-DD)') - ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $data = $this->subtaskExport->export( - $input->getArgument('project_id'), - $input->getArgument('start_date'), - $input->getArgument('end_date') - ); - - if (is_array($data)) { - Csv::output($data); - } - } -} diff --git a/sources/app/Console/TaskExportCommand.php b/sources/app/Console/TaskExportCommand.php deleted file mode 100644 index 789245b..0000000 --- a/sources/app/Console/TaskExportCommand.php +++ /dev/null @@ -1,34 +0,0 @@ -setName('export:tasks') - ->setDescription('Tasks CSV export') - ->addArgument('project_id', InputArgument::REQUIRED, 'Project id') - ->addArgument('start_date', InputArgument::REQUIRED, 'Start date (YYYY-MM-DD)') - ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $data = $this->taskExport->export( - $input->getArgument('project_id'), - $input->getArgument('start_date'), - $input->getArgument('end_date') - ); - - if (is_array($data)) { - Csv::output($data); - } - } -} diff --git a/sources/app/Console/TaskOverdueNotificationCommand.php b/sources/app/Console/TaskOverdueNotificationCommand.php deleted file mode 100644 index 3627661..0000000 --- a/sources/app/Console/TaskOverdueNotificationCommand.php +++ /dev/null @@ -1,191 +0,0 @@ -setName('notification:overdue-tasks') - ->setDescription('Send notifications for overdue tasks') - ->addOption('show', null, InputOption::VALUE_NONE, 'Show sent overdue tasks') - ->addOption('group', null, InputOption::VALUE_NONE, 'Group all overdue tasks for one user (from all projects) in one email') - ->addOption('manager', null, InputOption::VALUE_NONE, 'Send all overdue tasks to project manager(s) in one email'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - if ($input->getOption('group')) { - $tasks = $this->sendGroupOverdueTaskNotifications(); - } elseif ($input->getOption('manager')) { - $tasks = $this->sendOverdueTaskNotificationsToManagers(); - } else { - $tasks = $this->sendOverdueTaskNotifications(); - } - - if ($input->getOption('show')) { - $this->showTable($output, $tasks); - } - } - - public function showTable(OutputInterface $output, array $tasks) - { - $rows = array(); - - foreach ($tasks as $task) { - $rows[] = array( - $task['id'], - $task['title'], - date('Y-m-d', $task['date_due']), - $task['project_id'], - $task['project_name'], - $task['assignee_name'] ?: $task['assignee_username'], - ); - } - - $table = new Table($output); - $table - ->setHeaders(array('Id', 'Title', 'Due date', 'Project Id', 'Project name', 'Assignee')) - ->setRows($rows) - ->render(); - } - - /** - * Send all overdue tasks for one user in one email - * - * @access public - */ - public function sendGroupOverdueTaskNotifications() - { - $tasks = $this->taskFinderModel->getOverdueTasks(); - - foreach ($this->groupByColumn($tasks, 'owner_id') as $user_tasks) { - $users = $this->userNotificationModel->getUsersWithNotificationEnabled($user_tasks[0]['project_id']); - - foreach ($users as $user) { - $this->sendUserOverdueTaskNotifications($user, $user_tasks); - } - } - - return $tasks; - } - - /** - * Send all overdue tasks in one email to project manager(s) - * - * @access public - */ - public function sendOverdueTaskNotificationsToManagers() - { - $tasks = $this->taskFinderModel->getOverdueTasks(); - - foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) { - $users = $this->userNotificationModel->getUsersWithNotificationEnabled($project_id); - $managers = array(); - - foreach ($users as $user) { - $role = $this->projectUserRoleModel->getUserRole($project_id, $user['id']); - if($role == Role::PROJECT_MANAGER) { - $managers[] = $user; - } - } - - foreach ($managers as $manager) { - $this->sendUserOverdueTaskNotificationsToManagers($manager, $project_tasks); - } - } - - return $tasks; - } - - /** - * Send overdue tasks - * - * @access public - */ - public function sendOverdueTaskNotifications() - { - $tasks = $this->taskFinderModel->getOverdueTasks(); - - foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) { - $users = $this->userNotificationModel->getUsersWithNotificationEnabled($project_id); - - foreach ($users as $user) { - $this->sendUserOverdueTaskNotifications($user, $project_tasks); - } - } - - return $tasks; - } - - /** - * Send overdue tasks for a given user - * - * @access public - * @param array $user - * @param array $tasks - */ - public function sendUserOverdueTaskNotifications(array $user, array $tasks) - { - $user_tasks = array(); - $project_names = array(); - - foreach ($tasks as $task) { - if ($this->userNotificationFilterModel->shouldReceiveNotification($user, array('task' => $task))) { - $user_tasks[] = $task; - $project_names[$task['project_id']] = $task['project_name']; - } - } - - if (! empty($user_tasks)) { - $this->userNotificationModel->sendUserNotification( - $user, - TaskModel::EVENT_OVERDUE, - array('tasks' => $user_tasks, 'project_name' => implode(', ', $project_names)) - ); - } - } - - /** - * Send overdue tasks for a project manager(s) - * - * @access public - * @param array $manager - * @param array $tasks - */ - public function sendUserOverdueTaskNotificationsToManagers(array $manager, array $tasks) - { - $this->userNotificationModel->sendUserNotification( - $manager, - TaskModel::EVENT_OVERDUE, - array('tasks' => $tasks, 'project_name' => $tasks[0]['project_name']) - ); - } - - /** - * Group a collection of records by a column - * - * @access public - * @param array $collection - * @param string $column - * @return array - */ - public function groupByColumn(array $collection, $column) - { - $result = array(); - - foreach ($collection as $item) { - $result[$item[$column]][] = $item; - } - - return $result; - } -} diff --git a/sources/app/Console/TaskTriggerCommand.php b/sources/app/Console/TaskTriggerCommand.php deleted file mode 100644 index a1f4dcc..0000000 --- a/sources/app/Console/TaskTriggerCommand.php +++ /dev/null @@ -1,51 +0,0 @@ -setName('trigger:tasks') - ->setDescription('Trigger scheduler event for all tasks'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - foreach ($this->getProjectIds() as $project_id) { - $tasks = $this->taskFinderModel->getAll($project_id); - $nb_tasks = count($tasks); - - if ($nb_tasks > 0) { - $output->writeln('Trigger task event: project_id='.$project_id.', nb_tasks='.$nb_tasks); - $this->sendEvent($tasks, $project_id); - } - } - } - - private function getProjectIds() - { - $listeners = $this->dispatcher->getListeners(TaskModel::EVENT_DAILY_CRONJOB); - $project_ids = array(); - - foreach ($listeners as $listener) { - $project_ids[] = $listener[0]->getProjectId(); - } - - return array_unique($project_ids); - } - - private function sendEvent(array &$tasks, $project_id) - { - $event = new TaskListEvent(array('project_id' => $project_id)); - $event->setTasks($tasks); - - $this->dispatcher->dispatch(TaskModel::EVENT_DAILY_CRONJOB, $event); - } -} diff --git a/sources/app/Console/TransitionExportCommand.php b/sources/app/Console/TransitionExportCommand.php deleted file mode 100644 index 265757b..0000000 --- a/sources/app/Console/TransitionExportCommand.php +++ /dev/null @@ -1,34 +0,0 @@ -setName('export:transitions') - ->setDescription('Task transitions CSV export') - ->addArgument('project_id', InputArgument::REQUIRED, 'Project id') - ->addArgument('start_date', InputArgument::REQUIRED, 'Start date (YYYY-MM-DD)') - ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $data = $this->transitionExport->export( - $input->getArgument('project_id'), - $input->getArgument('start_date'), - $input->getArgument('end_date') - ); - - if (is_array($data)) { - Csv::output($data); - } - } -} diff --git a/sources/app/Console/WorkerCommand.php b/sources/app/Console/WorkerCommand.php deleted file mode 100644 index e332624..0000000 --- a/sources/app/Console/WorkerCommand.php +++ /dev/null @@ -1,28 +0,0 @@ -setName('worker') - ->setDescription('Execute queue worker') - ; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->queueManager->listen(); - } -} diff --git a/sources/app/Controller/ActionController.php b/sources/app/Controller/ActionController.php deleted file mode 100644 index 097640f..0000000 --- a/sources/app/Controller/ActionController.php +++ /dev/null @@ -1,77 +0,0 @@ -getProject(); - $actions = $this->actionModel->getAllByProject($project['id']); - - $this->response->html($this->helper->layout->project('action/index', array( - 'values' => array('project_id' => $project['id']), - 'project' => $project, - 'actions' => $actions, - 'available_actions' => $this->actionManager->getAvailableActions(), - 'available_events' => $this->eventManager->getAll(), - 'available_params' => $this->actionManager->getAvailableParameters($actions), - 'columns_list' => $this->columnModel->getList($project['id']), - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id']), - 'projects_list' => $this->projectUserRoleModel->getProjectsByUser($this->userSession->getId()), - 'colors_list' => $this->colorModel->getList(), - 'categories_list' => $this->categoryModel->getList($project['id']), - 'links_list' => $this->linkModel->getList(0, false), - 'title' => t('Automatic actions') - ))); - } - - /** - * Confirmation dialog before removing an action - * - * @access public - */ - public function confirm() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('action/remove', array( - 'action' => $this->actionModel->getById($this->request->getIntegerParam('action_id')), - 'available_events' => $this->eventManager->getAll(), - 'available_actions' => $this->actionManager->getAvailableActions(), - 'project' => $project, - 'title' => t('Remove an action') - ))); - } - - /** - * Remove an action - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $action = $this->actionModel->getById($this->request->getIntegerParam('action_id')); - - if (! empty($action) && $this->actionModel->remove($action['id'])) { - $this->flash->success(t('Action removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this action.')); - } - - $this->response->redirect($this->helper->url->to('ActionController', 'index', array('project_id' => $project['id']))); - } -} diff --git a/sources/app/Controller/ActionCreationController.php b/sources/app/Controller/ActionCreationController.php deleted file mode 100644 index 9b228f2..0000000 --- a/sources/app/Controller/ActionCreationController.php +++ /dev/null @@ -1,122 +0,0 @@ -getProject(); - - $this->response->html($this->template->render('action_creation/create', array( - 'project' => $project, - 'values' => array('project_id' => $project['id']), - 'available_actions' => $this->actionManager->getAvailableActions(), - ))); - } - - /** - * Choose the event according to the action (step 2) - * - * @access public - */ - public function event() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - if (empty($values['action_name']) || empty($values['project_id'])) { - return $this->create(); - } - - return $this->response->html($this->template->render('action_creation/event', array( - 'values' => $values, - 'project' => $project, - 'available_actions' => $this->actionManager->getAvailableActions(), - 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), - ))); - } - - /** - * Define action parameters (step 3) - * - * @access public - */ - public function params() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) { - return $this->create(); - } - - $action = $this->actionManager->getAction($values['action_name']); - $action_params = $action->getActionRequiredParameters(); - - if (empty($action_params)) { - $this->doCreation($project, $values + array('params' => array())); - } - - $projects_list = $this->projectUserRoleModel->getActiveProjectsByUser($this->userSession->getId()); - unset($projects_list[$project['id']]); - - return $this->response->html($this->template->render('action_creation/params', array( - 'values' => $values, - 'action_params' => $action_params, - 'columns_list' => $this->columnModel->getList($project['id']), - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id']), - 'projects_list' => $projects_list, - 'colors_list' => $this->colorModel->getList(), - 'categories_list' => $this->categoryModel->getList($project['id']), - 'links_list' => $this->linkModel->getList(0, false), - 'priorities_list' => $this->projectTaskPriorityModel->getPriorities($project), - 'project' => $project, - 'available_actions' => $this->actionManager->getAvailableActions(), - 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), - ))); - } - - /** - * Save the action (last step) - * - * @access public - */ - public function save() - { - $this->doCreation($this->getProject(), $this->request->getValues()); - } - - /** - * Common method to save the action - * - * @access private - * @param array $project Project properties - * @param array $values Form values - */ - private function doCreation(array $project, array $values) - { - list($valid, ) = $this->actionValidator->validateCreation($values); - - if ($valid) { - if ($this->actionModel->create($values) !== false) { - $this->flash->success(t('Your automatic action have been created successfully.')); - } else { - $this->flash->failure(t('Unable to create your automatic action.')); - } - } - - $this->response->redirect($this->helper->url->to('ActionController', 'index', array('project_id' => $project['id']))); - } -} diff --git a/sources/app/Controller/ActivityController.php b/sources/app/Controller/ActivityController.php deleted file mode 100644 index 9f9841a..0000000 --- a/sources/app/Controller/ActivityController.php +++ /dev/null @@ -1,45 +0,0 @@ -getProject(); - - $this->response->html($this->helper->layout->app('activity/project', array( - 'events' => $this->helper->projectActivity->getProjectEvents($project['id']), - 'project' => $project, - 'title' => t('%s\'s activity', $project['name']) - ))); - } - - /** - * Display task activities - * - * @access public - */ - public function task() - { - $task = $this->getTask(); - - $this->response->html($this->helper->layout->task('activity/task', array( - 'title' => $task['title'], - 'task' => $task, - 'project' => $this->projectModel->getById($task['project_id']), - 'events' => $this->helper->projectActivity->getTaskEvents($task['id']), - ))); - } -} diff --git a/sources/app/Controller/AnalyticController.php b/sources/app/Controller/AnalyticController.php deleted file mode 100644 index cf3ba03..0000000 --- a/sources/app/Controller/AnalyticController.php +++ /dev/null @@ -1,178 +0,0 @@ -getProject(); - list($from, $to) = $this->getDates(); - - $this->response->html($this->helper->layout->analytic('analytic/lead_cycle_time', array( - 'values' => array( - 'from' => $from, - 'to' => $to, - ), - 'project' => $project, - 'average' => $this->averageLeadCycleTimeAnalytic->build($project['id']), - 'metrics' => $this->projectDailyStatsModel->getRawMetrics($project['id'], $from, $to), - 'date_format' => $this->configModel->get('application_date_format'), - 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()), - 'title' => t('Lead and Cycle time for "%s"', $project['name']), - ))); - } - - /** - * Show comparison between actual and estimated hours chart - * - * @access public - */ - public function compareHours() - { - $project = $this->getProject(); - - $paginator = $this->paginator - ->setUrl('AnalyticController', 'compareHours', array('project_id' => $project['id'])) - ->setMax(30) - ->setOrder(TaskModel::TABLE.'.id') - ->setQuery($this->taskQuery - ->withFilter(new TaskProjectFilter($project['id'])) - ->getQuery() - ) - ->calculate(); - - $this->response->html($this->helper->layout->analytic('analytic/compare_hours', array( - 'project' => $project, - 'paginator' => $paginator, - 'metrics' => $this->estimatedTimeComparisonAnalytic->build($project['id']), - 'title' => t('Compare hours for "%s"', $project['name']), - ))); - } - - /** - * Show average time spent by column - * - * @access public - */ - public function averageTimeByColumn() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->analytic('analytic/avg_time_columns', array( - 'project' => $project, - 'metrics' => $this->averageTimeSpentColumnAnalytic->build($project['id']), - 'title' => t('Average time spent into each column for "%s"', $project['name']), - ))); - } - - /** - * Show tasks distribution graph - * - * @access public - */ - public function tasks() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->analytic('analytic/tasks', array( - 'project' => $project, - 'metrics' => $this->taskDistributionAnalytic->build($project['id']), - 'title' => t('Task repartition for "%s"', $project['name']), - ))); - } - - /** - * Show users repartition - * - * @access public - */ - public function users() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->analytic('analytic/users', array( - 'project' => $project, - 'metrics' => $this->userDistributionAnalytic->build($project['id']), - 'title' => t('User repartition for "%s"', $project['name']), - ))); - } - - /** - * Show cumulative flow diagram - * - * @access public - */ - public function cfd() - { - $this->commonAggregateMetrics('analytic/cfd', 'total', 'Cumulative flow diagram for "%s"'); - } - - /** - * Show burndown chart - * - * @access public - */ - public function burndown() - { - $this->commonAggregateMetrics('analytic/burndown', 'score', 'Burndown chart for "%s"'); - } - - /** - * Common method for CFD and Burdown chart - * - * @access private - * @param string $template - * @param string $column - * @param string $title - */ - private function commonAggregateMetrics($template, $column, $title) - { - $project = $this->getProject(); - list($from, $to) = $this->getDates(); - - $display_graph = $this->projectDailyColumnStatsModel->countDays($project['id'], $from, $to) >= 2; - - $this->response->html($this->helper->layout->analytic($template, array( - 'values' => array( - 'from' => $from, - 'to' => $to, - ), - 'display_graph' => $display_graph, - 'metrics' => $display_graph ? $this->projectDailyColumnStatsModel->getAggregatedMetrics($project['id'], $from, $to, $column) : array(), - 'project' => $project, - 'date_format' => $this->configModel->get('application_date_format'), - 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()), - 'title' => t($title, $project['name']), - ))); - } - - private function getDates() - { - $values = $this->request->getValues(); - - $from = $this->request->getStringParam('from', date('Y-m-d', strtotime('-1week'))); - $to = $this->request->getStringParam('to', date('Y-m-d')); - - if (! empty($values)) { - $from = $values['from']; - $to = $values['to']; - } - - return array($from, $to); - } -} diff --git a/sources/app/Controller/AppController.php b/sources/app/Controller/AppController.php deleted file mode 100644 index 45cf39a..0000000 --- a/sources/app/Controller/AppController.php +++ /dev/null @@ -1,46 +0,0 @@ -request->isAjax()) { - $this->response->json(array('message' => 'Access Forbidden'), 403); - } - - $this->response->html($this->helper->layout->app('app/forbidden', array( - 'title' => t('Access Forbidden'), - 'no_layout' => $withoutLayout, - ))); - } - - /** - * Page not found - * - * @access public - * @param boolean $withoutLayout - */ - public function notFound($withoutLayout = false) - { - $this->response->html($this->helper->layout->app('app/notfound', array( - 'title' => t('Page not found'), - 'no_layout' => $withoutLayout, - ))); - } -} diff --git a/sources/app/Controller/AuthController.php b/sources/app/Controller/AuthController.php deleted file mode 100644 index d1fba92..0000000 --- a/sources/app/Controller/AuthController.php +++ /dev/null @@ -1,83 +0,0 @@ -userSession->isLogged()) { - $this->response->redirect($this->helper->url->to('DashboardController', 'show')); - } else { - $this->response->html($this->helper->layout->app('auth/index', array( - 'captcha' => ! empty($values['username']) && $this->userLockingModel->hasCaptcha($values['username']), - 'errors' => $errors, - 'values' => $values, - 'no_layout' => true, - 'title' => t('Login') - ))); - } - } - - /** - * Check credentials - * - * @access public - */ - public function check() - { - $values = $this->request->getValues(); - $this->sessionStorage->hasRememberMe = ! empty($values['remember_me']); - list($valid, $errors) = $this->authValidator->validateForm($values); - - if ($valid) { - $this->redirectAfterLogin(); - } else { - $this->login($values, $errors); - } - } - - /** - * Logout and destroy session - * - * @access public - */ - public function logout() - { - if (! DISABLE_LOGOUT) { - $this->sessionManager->close(); - $this->response->redirect($this->helper->url->to('AuthController', 'login')); - } else { - $this->response->redirect($this->helper->url->to('DashboardController', 'show')); - } - } - - /** - * Redirect the user after the authentication - * - * @access private - */ - private function redirectAfterLogin() - { - if (isset($this->sessionStorage->redirectAfterLogin) && ! empty($this->sessionStorage->redirectAfterLogin) && ! filter_var($this->sessionStorage->redirectAfterLogin, FILTER_VALIDATE_URL)) { - $redirect = $this->sessionStorage->redirectAfterLogin; - unset($this->sessionStorage->redirectAfterLogin); - $this->response->redirect($redirect); - } else { - $this->response->redirect($this->helper->url->to('DashboardController', 'show')); - } - } -} diff --git a/sources/app/Controller/AvatarFileController.php b/sources/app/Controller/AvatarFileController.php deleted file mode 100644 index 6879c57..0000000 --- a/sources/app/Controller/AvatarFileController.php +++ /dev/null @@ -1,94 +0,0 @@ -getUser(); - - $this->response->html($this->helper->layout->user('avatar_file/show', array( - 'user' => $user, - ))); - } - - /** - * Upload Avatar - */ - public function upload() - { - $user = $this->getUser(); - - if (! $this->avatarFileModel->uploadImageFile($user['id'], $this->request->getFileInfo('avatar'))) { - $this->flash->failure(t('Unable to upload the file.')); - } - - $this->response->redirect($this->helper->url->to('AvatarFileController', 'show', array('user_id' => $user['id']))); - } - - /** - * Remove Avatar image - */ - public function remove() - { - $this->checkCSRFParam(); - $user = $this->getUser(); - $this->avatarFileModel->remove($user['id']); - $this->userSession->refresh($user['id']); - $this->response->redirect($this->helper->url->to('AvatarFileController', 'show', array('user_id' => $user['id']))); - } - - /** - * Show Avatar image (public) - */ - public function image() - { - $user_id = $this->request->getIntegerParam('user_id'); - $size = $this->request->getStringParam('size', 48); - $filename = $this->avatarFileModel->getFilename($user_id); - $etag = md5($filename.$size); - - $this->response->withCache(365 * 86400, $etag); - $this->response->withContentType('image/jpeg'); - - if ($this->request->getHeader('If-None-Match') !== '"'.$etag.'"') { - $this->response->send(); - $this->render($filename, $size); - } else { - $this->response->status(304); - } - } - - /** - * Render thumbnail from object storage - * - * @access private - * @param string $filename - * @param integer $size - */ - private function render($filename, $size) - { - try { - $blob = $this->objectStorage->get($filename); - - Thumbnail::createFromString($blob) - ->resize($size, $size) - ->toOutput(); - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - } - } -} diff --git a/sources/app/Controller/BaseController.php b/sources/app/Controller/BaseController.php deleted file mode 100644 index 5233e27..0000000 --- a/sources/app/Controller/BaseController.php +++ /dev/null @@ -1,158 +0,0 @@ -token->validateCSRFToken($this->request->getStringParam('csrf_token'))) { - throw new AccessForbiddenException(); - } - } - - /** - * Check webhook token - * - * @access protected - */ - protected function checkWebhookToken() - { - if ($this->configModel->get('webhook_token') !== $this->request->getStringParam('token')) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - } - - /** - * Common method to get a task for task views - * - * @access protected - * @return array - * @throws PageNotFoundException - * @throws AccessForbiddenException - */ - protected function getTask() - { - $project_id = $this->request->getIntegerParam('project_id'); - $task = $this->taskFinderModel->getDetails($this->request->getIntegerParam('task_id')); - - if (empty($task)) { - throw new PageNotFoundException(); - } - - if ($project_id !== 0 && $project_id != $task['project_id']) { - throw new AccessForbiddenException(); - } - - return $task; - } - - /** - * Get Task or Project file - * - * @access protected - * @return array - * @throws PageNotFoundException - * @throws AccessForbiddenException - */ - protected function getFile() - { - $task_id = $this->request->getIntegerParam('task_id'); - $file_id = $this->request->getIntegerParam('file_id'); - $model = 'projectFileModel'; - - if ($task_id > 0) { - $model = 'taskFileModel'; - $project_id = $this->taskFinderModel->getProjectId($task_id); - - if ($project_id !== $this->request->getIntegerParam('project_id')) { - throw new AccessForbiddenException(); - } - } - - $file = $this->$model->getById($file_id); - - if (empty($file)) { - throw new PageNotFoundException(); - } - - $file['model'] = $model; - return $file; - } - - /** - * Common method to get a project - * - * @access protected - * @param integer $project_id Default project id - * @return array - * @throws PageNotFoundException - */ - protected function getProject($project_id = 0) - { - $project_id = $this->request->getIntegerParam('project_id', $project_id); - $project = $this->projectModel->getByIdWithOwner($project_id); - - if (empty($project)) { - throw new PageNotFoundException(); - } - - return $project; - } - - /** - * Common method to get the user - * - * @access protected - * @return array - * @throws PageNotFoundException - * @throws AccessForbiddenException - */ - protected function getUser() - { - $user = $this->userModel->getById($this->request->getIntegerParam('user_id', $this->userSession->getId())); - - if (empty($user)) { - throw new PageNotFoundException(); - } - - if (! $this->userSession->isAdmin() && $this->userSession->getId() != $user['id']) { - throw new AccessForbiddenException(); - } - - return $user; - } - - /** - * Get the current subtask - * - * @access protected - * @return array - * @throws PageNotFoundException - */ - protected function getSubtask() - { - $subtask = $this->subtaskModel->getById($this->request->getIntegerParam('subtask_id')); - - if (empty($subtask)) { - throw new PageNotFoundException(); - } - - return $subtask; - } -} diff --git a/sources/app/Controller/BoardAjaxController.php b/sources/app/Controller/BoardAjaxController.php deleted file mode 100644 index 9b721f0..0000000 --- a/sources/app/Controller/BoardAjaxController.php +++ /dev/null @@ -1,140 +0,0 @@ -request->getIntegerParam('project_id'); - - if (! $project_id || ! $this->request->isAjax()) { - throw new AccessForbiddenException(); - } - - $values = $this->request->getJson(); - - $result =$this->taskPositionModel->movePosition( - $project_id, - $values['task_id'], - $values['column_id'], - $values['position'], - $values['swimlane_id'] - ); - - if (! $result) { - $this->response->status(400); - } else { - $this->response->html($this->renderBoard($project_id), 201); - } - } - - /** - * Check if the board have been changed - * - * @access public - */ - public function check() - { - $project_id = $this->request->getIntegerParam('project_id'); - $timestamp = $this->request->getIntegerParam('timestamp'); - - if (! $project_id || ! $this->request->isAjax()) { - throw new AccessForbiddenException(); - } elseif (! $this->projectModel->isModifiedSince($project_id, $timestamp)) { - $this->response->status(304); - } else { - $this->response->html($this->renderBoard($project_id)); - } - } - - /** - * Reload the board with new filters - * - * @access public - */ - public function reload() - { - $project_id = $this->request->getIntegerParam('project_id'); - - if (! $project_id || ! $this->request->isAjax()) { - throw new AccessForbiddenException(); - } - - $values = $this->request->getJson(); - $this->userSession->setFilters($project_id, empty($values['search']) ? '' : $values['search']); - - $this->response->html($this->renderBoard($project_id)); - } - - /** - * Enable collapsed mode - * - * @access public - */ - public function collapse() - { - $this->changeDisplayMode(true); - } - - /** - * Enable expanded mode - * - * @access public - */ - public function expand() - { - $this->changeDisplayMode(false); - } - - /** - * Change display mode - * - * @access private - * @param boolean $mode - */ - private function changeDisplayMode($mode) - { - $project_id = $this->request->getIntegerParam('project_id'); - $this->userSession->setBoardDisplayMode($project_id, $mode); - - if ($this->request->isAjax()) { - $this->response->html($this->renderBoard($project_id)); - } else { - $this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project_id))); - } - } - - /** - * Render board - * - * @access protected - * @param integer $project_id - * @return string - */ - protected function renderBoard($project_id) - { - return $this->template->render('board/table_container', array( - 'project' => $this->projectModel->getById($project_id), - 'board_private_refresh_interval' => $this->configModel->get('board_private_refresh_interval'), - '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)) - )); - } -} diff --git a/sources/app/Controller/BoardPopoverController.php b/sources/app/Controller/BoardPopoverController.php deleted file mode 100644 index a0f5ae1..0000000 --- a/sources/app/Controller/BoardPopoverController.php +++ /dev/null @@ -1,47 +0,0 @@ -getProject(); - $column_id = $this->request->getIntegerParam('column_id'); - $swimlane_id = $this->request->getIntegerParam('swimlane_id'); - - $this->response->html($this->template->render('board_popover/close_all_tasks_column', array( - 'project' => $project, - 'nb_tasks' => $this->taskFinderModel->countByColumnAndSwimlaneId($project['id'], $column_id, $swimlane_id), - 'column' => $this->columnModel->getColumnTitleById($column_id), - 'swimlane' => $this->swimlaneModel->getNameById($swimlane_id) ?: t($project['default_swimlane']), - 'values' => array('column_id' => $column_id, 'swimlane_id' => $swimlane_id), - ))); - } - - /** - * Close all column tasks - * - * @access public - */ - public function closeColumnTasks() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - $this->taskStatusModel->closeTasksBySwimlaneAndColumn($values['swimlane_id'], $values['column_id']); - $this->flash->success(t('All tasks of the column "%s" and the swimlane "%s" have been closed successfully.', $this->columnModel->getColumnTitleById($values['column_id']), $this->swimlaneModel->getNameById($values['swimlane_id']) ?: t($project['default_swimlane']))); - $this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id']))); - } -} diff --git a/sources/app/Controller/BoardTooltipController.php b/sources/app/Controller/BoardTooltipController.php deleted file mode 100644 index 134d728..0000000 --- a/sources/app/Controller/BoardTooltipController.php +++ /dev/null @@ -1,127 +0,0 @@ -getTask(); - $this->response->html($this->template->render('board/tooltip_tasklinks', array( - 'links' => $this->taskLinkModel->getAllGroupedByLabel($task['id']), - 'task' => $task, - ))); - } - - /** - * Get links on mouseover - * - * @access public - */ - public function externallinks() - { - $task = $this->getTask(); - $this->response->html($this->template->render('board/tooltip_external_links', array( - 'links' => $this->taskExternalLinkModel->getAll($task['id']), - 'task' => $task, - ))); - } - - /** - * Get subtasks on mouseover - * - * @access public - */ - public function subtasks() - { - $task = $this->getTask(); - $this->response->html($this->template->render('board/tooltip_subtasks', array( - 'subtasks' => $this->subtaskModel->getAll($task['id']), - 'task' => $task, - ))); - } - - /** - * Display all attachments during the task mouseover - * - * @access public - */ - public function attachments() - { - $task = $this->getTask(); - - $this->response->html($this->template->render('board/tooltip_files', array( - 'files' => $this->taskFileModel->getAll($task['id']), - 'task' => $task, - ))); - } - - /** - * Display comments during a task mouseover - * - * @access public - */ - public function comments() - { - $task = $this->getTask(); - - $this->response->html($this->template->render('board/tooltip_comments', array( - 'task' => $task, - 'comments' => $this->commentModel->getAll($task['id'], $this->userSession->getCommentSorting()) - ))); - } - - /** - * Display task description - * - * @access public - */ - public function description() - { - $task = $this->getTask(); - - $this->response->html($this->template->render('board/tooltip_description', array( - 'task' => $task - ))); - } - - /** - * Get recurrence information on mouseover - * - * @access public - */ - public function recurrence() - { - $task = $this->getTask(); - - $this->response->html($this->template->render('task_recurrence/info', array( - 'task' => $task, - 'recurrence_trigger_list' => $this->taskRecurrenceModel->getRecurrenceTriggerList(), - 'recurrence_timeframe_list' => $this->taskRecurrenceModel->getRecurrenceTimeframeList(), - 'recurrence_basedate_list' => $this->taskRecurrenceModel->getRecurrenceBasedateList(), - ))); - } - - /** - * Display swimlane description in tooltip - * - * @access public - */ - public function swimlane() - { - $this->getProject(); - $swimlane = $this->swimlaneModel->getById($this->request->getIntegerParam('swimlane_id')); - $this->response->html($this->template->render('board/tooltip_description', array('task' => $swimlane))); - } -} diff --git a/sources/app/Controller/BoardViewController.php b/sources/app/Controller/BoardViewController.php deleted file mode 100644 index 97c99d1..0000000 --- a/sources/app/Controller/BoardViewController.php +++ /dev/null @@ -1,69 +0,0 @@ -request->getStringParam('token'); - $project = $this->projectModel->getByToken($token); - - if (empty($project)) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - $this->response->html($this->helper->layout->app('board/view_public', array( - 'project' => $project, - 'swimlanes' => BoardFormatter::getInstance($this->container) - ->withProjectId($project['id']) - ->withQuery($this->taskFinderModel->getExtendedQuery()) - ->format() - , - 'title' => $project['name'], - 'description' => $project['description'], - 'no_layout' => true, - 'not_editable' => true, - 'board_public_refresh_interval' => $this->configModel->get('board_public_refresh_interval'), - 'board_private_refresh_interval' => $this->configModel->get('board_private_refresh_interval'), - 'board_highlight_period' => $this->configModel->get('board_highlight_period'), - ))); - } - - /** - * Show a board for a given project - * - * @access public - */ - public function show() - { - $project = $this->getProject(); - $search = $this->helper->projectHeader->getSearchQuery($project); - - $this->response->html($this->helper->layout->app('board/view_private', array( - 'project' => $project, - 'title' => $project['name'], - 'description' => $this->helper->projectHeader->getDescription($project), - 'board_private_refresh_interval' => $this->configModel->get('board_private_refresh_interval'), - 'board_highlight_period' => $this->configModel->get('board_highlight_period'), - 'swimlanes' => $this->taskLexer - ->build($search) - ->format(BoardFormatter::getInstance($this->container)->withProjectId($project['id'])) - ))); - } -} diff --git a/sources/app/Controller/CalendarController.php b/sources/app/Controller/CalendarController.php deleted file mode 100644 index e5114f0..0000000 --- a/sources/app/Controller/CalendarController.php +++ /dev/null @@ -1,107 +0,0 @@ -getProject(); - - $this->response->html($this->helper->layout->app('calendar/show', array( - 'project' => $project, - 'title' => $project['name'], - 'description' => $this->helper->projectHeader->getDescription($project), - 'check_interval' => $this->configModel->get('board_private_refresh_interval'), - ))); - } - - /** - * Get tasks to display on the calendar (project view) - * - * @access public - */ - public function project() - { - $project_id = $this->request->getIntegerParam('project_id'); - $start = $this->request->getStringParam('start'); - $end = $this->request->getStringParam('end'); - $search = $this->userSession->getFilters($project_id); - $queryBuilder = $this->taskLexer->build($search)->withFilter(new TaskProjectFilter($project_id)); - - $events = $this->helper->calendar->getTaskDateDueEvents(clone($queryBuilder), $start, $end); - $events = array_merge($events, $this->helper->calendar->getTaskEvents(clone($queryBuilder), $start, $end)); - - $events = $this->hook->merge('controller:calendar:project:events', $events, array( - 'project_id' => $project_id, - 'start' => $start, - 'end' => $end, - )); - - $this->response->json($events); - } - - /** - * Get tasks to display on the calendar (user view) - * - * @access public - */ - public function user() - { - $user_id = $this->request->getIntegerParam('user_id'); - $start = $this->request->getStringParam('start'); - $end = $this->request->getStringParam('end'); - $queryBuilder = $this->taskQuery - ->withFilter(new TaskAssigneeFilter($user_id)) - ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN)); - - $events = $this->helper->calendar->getTaskDateDueEvents(clone($queryBuilder), $start, $end); - $events = array_merge($events, $this->helper->calendar->getTaskEvents(clone($queryBuilder), $start, $end)); - - if ($this->configModel->get('calendar_user_subtasks_time_tracking') == 1) { - $events = array_merge($events, $this->helper->calendar->getSubtaskTimeTrackingEvents($user_id, $start, $end)); - } - - $events = $this->hook->merge('controller:calendar:user:events', $events, array( - 'user_id' => $user_id, - 'start' => $start, - 'end' => $end, - )); - - $this->response->json($events); - } - - /** - * Update task due date - * - * @access public - */ - public function save() - { - if ($this->request->isAjax() && $this->request->isPost()) { - $values = $this->request->getJson(); - - $this->taskModificationModel->update(array( - 'id' => $values['task_id'], - 'date_due' => substr($values['date_due'], 0, 10), - )); - } - } -} diff --git a/sources/app/Controller/CaptchaController.php b/sources/app/Controller/CaptchaController.php deleted file mode 100644 index 43b2f82..0000000 --- a/sources/app/Controller/CaptchaController.php +++ /dev/null @@ -1,29 +0,0 @@ -response->withContentType('image/jpeg')->send(); - - $builder = new CaptchaBuilder; - $builder->build(); - $this->sessionStorage->captcha = $builder->getPhrase(); - $builder->output(); - } -} diff --git a/sources/app/Controller/CategoryController.php b/sources/app/Controller/CategoryController.php deleted file mode 100644 index dd6e1c3..0000000 --- a/sources/app/Controller/CategoryController.php +++ /dev/null @@ -1,159 +0,0 @@ -categoryModel->getById($this->request->getIntegerParam('category_id')); - - if (empty($category)) { - throw new PageNotFoundException(); - } - - return $category; - } - - /** - * List of categories for a given project - * - * @access public - * @param array $values - * @param array $errors - * @throws PageNotFoundException - */ - public function index(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('category/index', array( - 'categories' => $this->categoryModel->getList($project['id'], false), - 'values' => $values + array('project_id' => $project['id']), - 'errors' => $errors, - 'project' => $project, - 'title' => t('Categories') - ))); - } - - /** - * Validate and save a new category - * - * @access public - */ - public function save() - { - $project = $this->getProject(); - - $values = $this->request->getValues(); - list($valid, $errors) = $this->categoryValidator->validateCreation($values); - - if ($valid) { - if ($this->categoryModel->create($values) !== false) { - $this->flash->success(t('Your category have been created successfully.')); - return $this->response->redirect($this->helper->url->to('CategoryController', 'index', array('project_id' => $project['id']))); - } else { - $this->flash->failure(t('Unable to create your category.')); - } - } - - return $this->index($values, $errors); - } - - /** - * Edit a category (display the form) - * - * @access public - * @param array $values - * @param array $errors - * @throws PageNotFoundException - */ - public function edit(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - $category = $this->getCategory(); - - $this->response->html($this->helper->layout->project('category/edit', array( - 'values' => empty($values) ? $category : $values, - 'errors' => $errors, - 'project' => $project, - 'title' => t('Categories') - ))); - } - - /** - * Edit a category (validate the form and update the database) - * - * @access public - */ - public function update() - { - $project = $this->getProject(); - - $values = $this->request->getValues(); - list($valid, $errors) = $this->categoryValidator->validateModification($values); - - if ($valid) { - if ($this->categoryModel->update($values)) { - $this->flash->success(t('Your category have been updated successfully.')); - return $this->response->redirect($this->helper->url->to('CategoryController', 'index', array('project_id' => $project['id']))); - } else { - $this->flash->failure(t('Unable to update your category.')); - } - } - - return $this->edit($values, $errors); - } - - /** - * Confirmation dialog before removing a category - * - * @access public - */ - public function confirm() - { - $project = $this->getProject(); - $category = $this->getCategory(); - - $this->response->html($this->helper->layout->project('category/remove', array( - 'project' => $project, - 'category' => $category, - 'title' => t('Remove a category') - ))); - } - - /** - * Remove a category - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $category = $this->getCategory(); - - if ($this->categoryModel->remove($category['id'])) { - $this->flash->success(t('Category removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this category.')); - } - - $this->response->redirect($this->helper->url->to('CategoryController', 'index', array('project_id' => $project['id']))); - } -} diff --git a/sources/app/Controller/ColumnController.php b/sources/app/Controller/ColumnController.php deleted file mode 100644 index 95fbcaa..0000000 --- a/sources/app/Controller/ColumnController.php +++ /dev/null @@ -1,178 +0,0 @@ -getProject(); - $columns = $this->columnModel->getAll($project['id']); - - $this->response->html($this->helper->layout->project('column/index', array( - 'columns' => $columns, - 'project' => $project, - 'title' => t('Edit board') - ))); - } - - /** - * Show form to create a new column - * - * @access public - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function create(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - - if (empty($values)) { - $values = array('project_id' => $project['id']); - } - - $this->response->html($this->template->render('column/create', array( - 'values' => $values, - 'errors' => $errors, - 'project' => $project, - 'title' => t('Add a new column') - ))); - } - - /** - * Validate and add a new column - * - * @access public - */ - public function save() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->columnValidator->validateCreation($values); - - if ($valid) { - if ($this->columnModel->create($project['id'], $values['title'], $values['task_limit'], $values['description']) !== false) { - $this->flash->success(t('Column created successfully.')); - return $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])), true); - } else { - $errors['title'] = array(t('Another column with the same name exists in the project')); - } - } - - return $this->create($values, $errors); - } - - /** - * Display a form to edit a column - * - * @access public - * @param array $values - * @param array $errors - */ - public function edit(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - $column = $this->columnModel->getById($this->request->getIntegerParam('column_id')); - - $this->response->html($this->helper->layout->project('column/edit', array( - 'errors' => $errors, - 'values' => $values ?: $column, - 'project' => $project, - 'column' => $column, - 'title' => t('Edit column "%s"', $column['title']) - ))); - } - - /** - * Validate and update a column - * - * @access public - */ - public function update() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->columnValidator->validateModification($values); - - if ($valid) { - if ($this->columnModel->update($values['id'], $values['title'], $values['task_limit'], $values['description'])) { - $this->flash->success(t('Board updated successfully.')); - return $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id']))); - } else { - $this->flash->failure(t('Unable to update this board.')); - } - } - - return $this->edit($values, $errors); - } - - /** - * Move column position - * - * @access public - */ - public function move() - { - $project = $this->getProject(); - $values = $this->request->getJson(); - - if (! empty($values) && isset($values['column_id']) && isset($values['position'])) { - $result = $this->columnModel->changePosition($project['id'], $values['column_id'], $values['position']); - $this->response->json(array('result' => $result)); - } else { - throw new AccessForbiddenException(); - } - } - - /** - * Confirm column suppression - * - * @access public - */ - public function confirm() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('column/remove', array( - 'column' => $this->columnModel->getById($this->request->getIntegerParam('column_id')), - 'project' => $project, - 'title' => t('Remove a column from a board') - ))); - } - - /** - * Remove a column - * - * @access public - */ - public function remove() - { - $project = $this->getProject(); - $this->checkCSRFParam(); - $column_id = $this->request->getIntegerParam('column_id'); - - if ($this->columnModel->remove($column_id)) { - $this->flash->success(t('Column removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this column.')); - } - - $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id']))); - } -} diff --git a/sources/app/Controller/CommentController.php b/sources/app/Controller/CommentController.php deleted file mode 100644 index 2a8c258..0000000 --- a/sources/app/Controller/CommentController.php +++ /dev/null @@ -1,191 +0,0 @@ -commentModel->getById($this->request->getIntegerParam('comment_id')); - - if (empty($comment)) { - throw new PageNotFoundException(); - } - - if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) { - throw new AccessForbiddenException(); - } - - return $comment; - } - - /** - * Add comment form - * - * @access public - * @param array $values - * @param array $errors - * @throws AccessForbiddenException - * @throws PageNotFoundException - */ - public function create(array $values = array(), array $errors = array()) - { - $task = $this->getTask(); - - if (empty($values)) { - $values = array( - 'user_id' => $this->userSession->getId(), - 'task_id' => $task['id'], - ); - } - - $this->response->html($this->template->render('comment/create', array( - 'values' => $values, - 'errors' => $errors, - 'task' => $task, - ))); - } - - /** - * Add a comment - * - * @access public - */ - public function save() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->commentValidator->validateCreation($values); - - if ($valid) { - if ($this->commentModel->create($values) !== false) { - $this->flash->success(t('Comment added successfully.')); - } else { - $this->flash->failure(t('Unable to create your comment.')); - } - - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'), true); - } - - return $this->create($values, $errors); - } - - /** - * Edit a comment - * - * @access public - * @param array $values - * @param array $errors - * @throws AccessForbiddenException - * @throws PageNotFoundException - */ - public function edit(array $values = array(), array $errors = array()) - { - $task = $this->getTask(); - $comment = $this->getComment(); - - $this->response->html($this->template->render('comment/edit', array( - 'values' => empty($values) ? $comment : $values, - 'errors' => $errors, - 'comment' => $comment, - 'task' => $task, - 'title' => t('Edit a comment') - ))); - } - - /** - * Update and validate a comment - * - * @access public - */ - public function update() - { - $task = $this->getTask(); - $this->getComment(); - - $values = $this->request->getValues(); - list($valid, $errors) = $this->commentValidator->validateModification($values); - - if ($valid) { - if ($this->commentModel->update($values)) { - $this->flash->success(t('Comment updated successfully.')); - } else { - $this->flash->failure(t('Unable to update your comment.')); - } - - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), false); - } - - return $this->edit($values, $errors); - } - - /** - * Confirmation dialog before removing a comment - * - * @access public - */ - public function confirm() - { - $task = $this->getTask(); - $comment = $this->getComment(); - - $this->response->html($this->template->render('comment/remove', array( - 'comment' => $comment, - 'task' => $task, - 'title' => t('Remove a comment') - ))); - } - - /** - * Remove a comment - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $task = $this->getTask(); - $comment = $this->getComment(); - - if ($this->commentModel->remove($comment['id'])) { - $this->flash->success(t('Comment removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this comment.')); - } - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments')); - } - - /** - * Toggle comment sorting - * - * @access public - */ - public function toggleSorting() - { - $task = $this->getTask(); - - $order = $this->userSession->getCommentSorting() === 'ASC' ? 'DESC' : 'ASC'; - $this->userSession->setCommentSorting($order); - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments')); - } -} diff --git a/sources/app/Controller/ConfigController.php b/sources/app/Controller/ConfigController.php deleted file mode 100644 index 8285ee1..0000000 --- a/sources/app/Controller/ConfigController.php +++ /dev/null @@ -1,219 +0,0 @@ -response->html($this->helper->layout->config('config/about', array( - 'db_size' => $this->configModel->getDatabaseSize(), - 'db_version' => $this->db->getDriver()->getDatabaseVersion(), - 'user_agent' => $this->request->getServerVariable('HTTP_USER_AGENT'), - 'title' => t('Settings').' > '.t('About'), - ))); - } - - /** - * Save settings - * - */ - public function save() - { - $values = $this->request->getValues(); - $redirect = $this->request->getStringParam('redirect', 'application'); - - switch ($redirect) { - case 'application': - $values += array('password_reset' => 0); - break; - case 'project': - $values += array( - 'subtask_restriction' => 0, - 'subtask_time_tracking' => 0, - 'cfd_include_closed_tasks' => 0, - 'disable_private_project' => 0, - ); - break; - case 'integrations': - $values += array('integration_gravatar' => 0); - break; - case 'calendar': - $values += array('calendar_user_subtasks_time_tracking' => 0); - break; - } - - if ($this->configModel->save($values)) { - $this->languageModel->loadCurrentLanguage(); - $this->flash->success(t('Settings saved successfully.')); - } else { - $this->flash->failure(t('Unable to save your settings.')); - } - - $this->response->redirect($this->helper->url->to('ConfigController', $redirect)); - } - - /** - * Display the application settings page - * - * @access public - */ - public function application() - { - $this->response->html($this->helper->layout->config('config/application', array( - 'mail_transports' => $this->emailClient->getAvailableTransports(), - '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').' > '.t('Application settings'), - ))); - } - - /** - * Display the email settings page - * - * @access public - */ - public function email() - { - $values = $this->configModel->getAll(); - - if (empty($values['mail_transport'])) { - $values['mail_transport'] = MAIL_TRANSPORT; - } - - $this->response->html($this->helper->layout->config('config/email', array( - 'values' => $values, - 'mail_transports' => $this->emailClient->getAvailableTransports(), - 'title' => t('Settings').' > '.t('Email settings'), - ))); - } - - /** - * Display the project settings page - * - * @access public - */ - public function project() - { - $this->response->html($this->helper->layout->config('config/project', array( - 'colors' => $this->colorModel->getList(), - 'default_columns' => implode(', ', $this->boardModel->getDefaultColumns()), - 'title' => t('Settings').' > '.t('Project settings'), - ))); - } - - /** - * Display the board settings page - * - * @access public - */ - public function board() - { - $this->response->html($this->helper->layout->config('config/board', array( - 'title' => t('Settings').' > '.t('Board settings'), - ))); - } - - /** - * Display the calendar settings page - * - * @access public - */ - public function calendar() - { - $this->response->html($this->helper->layout->config('config/calendar', array( - 'title' => t('Settings').' > '.t('Calendar settings'), - ))); - } - - /** - * Display the integration settings page - * - * @access public - */ - public function integrations() - { - $this->response->html($this->helper->layout->config('config/integrations', array( - 'title' => t('Settings').' > '.t('Integrations'), - ))); - } - - /** - * Display the webhook settings page - * - * @access public - */ - public function webhook() - { - $this->response->html($this->helper->layout->config('config/webhook', array( - 'title' => t('Settings').' > '.t('Webhook settings'), - ))); - } - - /** - * Display the api settings page - * - * @access public - */ - public function api() - { - $this->response->html($this->helper->layout->config('config/api', array( - 'title' => t('Settings').' > '.t('API'), - ))); - } - - /** - * Download the Sqlite database - * - * @access public - */ - public function downloadDb() - { - $this->checkCSRFParam(); - $this->response->withFileDownload('db.sqlite.gz'); - $this->response->binary($this->configModel->downloadDatabase()); - } - - /** - * Optimize the Sqlite database - * - * @access public - */ - public function optimizeDb() - { - $this->checkCSRFParam(); - $this->configModel->optimizeDatabase(); - $this->flash->success(t('Database optimization done.')); - $this->response->redirect($this->helper->url->to('ConfigController', 'index')); - } - - /** - * Regenerate webhook token - * - * @access public - */ - public function token() - { - $type = $this->request->getStringParam('type'); - - $this->checkCSRFParam(); - $this->configModel->regenerateToken($type.'_token'); - - $this->flash->success(t('Token regenerated.')); - $this->response->redirect($this->helper->url->to('ConfigController', $type)); - } -} diff --git a/sources/app/Controller/CurrencyController.php b/sources/app/Controller/CurrencyController.php deleted file mode 100644 index ad59003..0000000 --- a/sources/app/Controller/CurrencyController.php +++ /dev/null @@ -1,71 +0,0 @@ -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(), - 'currencies' => $this->currencyModel->getCurrencies(), - 'title' => t('Settings').' > '.t('Currency rates'), - ))); - } - - /** - * Validate and save a new currency rate - * - * @access public - */ - public function create() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->currencyValidator->validateCreation($values); - - 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')); - } else { - $this->flash->failure(t('Unable to add this currency rate.')); - } - } - - return $this->index($values, $errors); - } - - /** - * Save reference currency - * - * @access public - */ - public function reference() - { - $values = $this->request->getValues(); - - if ($this->configModel->save($values)) { - $this->flash->success(t('Settings saved successfully.')); - } else { - $this->flash->failure(t('Unable to save your settings.')); - } - - $this->response->redirect($this->helper->url->to('CurrencyController', 'index')); - } -} diff --git a/sources/app/Controller/CustomFilterController.php b/sources/app/Controller/CustomFilterController.php deleted file mode 100644 index e5f674c..0000000 --- a/sources/app/Controller/CustomFilterController.php +++ /dev/null @@ -1,172 +0,0 @@ -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'), - ))); - } - - /** - * Save a new custom filter - * - * @access public - */ - public function save() - { - $project = $this->getProject(); - - $values = $this->request->getValues(); - $values['user_id'] = $this->userSession->getId(); - - list($valid, $errors) = $this->customFilterValidator->validateCreation($values); - - 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']))); - } else { - $this->flash->failure(t('Unable to create your custom filter.')); - } - } - - return $this->index($values, $errors); - } - - /** - * Confirmation dialog before removing a custom filter - * - * @access public - */ - public function confirm() - { - $project = $this->getProject(); - $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id')); - - $this->response->html($this->helper->layout->project('custom_filter/remove', array( - 'project' => $project, - 'filter' => $filter, - 'title' => t('Remove a custom filter') - ))); - } - - /** - * Remove a custom filter - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id')); - - $this->checkPermission($project, $filter); - - if ($this->customFilterModel->remove($filter['id'])) { - $this->flash->success(t('Custom filter removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this custom filter.')); - } - - $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id']))); - } - - /** - * Edit a custom filter (display the form) - * - * @access public - * @param array $values - * @param array $errors - * @throws AccessForbiddenException - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function edit(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id')); - - $this->checkPermission($project, $filter); - - $this->response->html($this->helper->layout->project('custom_filter/edit', array( - 'values' => empty($values) ? $filter : $values, - 'errors' => $errors, - 'project' => $project, - 'filter' => $filter, - 'title' => t('Edit custom filter') - ))); - } - - /** - * Edit a custom filter (validate the form and update the database) - * - * @access public - */ - public function update() - { - $project = $this->getProject(); - $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id')); - - $this->checkPermission($project, $filter); - - $values = $this->request->getValues(); - - if (! isset($values['is_shared'])) { - $values += array('is_shared' => 0); - } - - if (! isset($values['append'])) { - $values += array('append' => 0); - } - - list($valid, $errors) = $this->customFilterValidator->validateModification($values); - - 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']))); - } else { - $this->flash->failure(t('Unable to update custom filter.')); - } - } - - return $this->edit($values, $errors); - } - - private function checkPermission(array $project, array $filter) - { - $user_id = $this->userSession->getId(); - - if ($filter['user_id'] != $user_id && ($this->projectUserRoleModel->getUserRole($project['id'], $user_id) === Role::PROJECT_MANAGER || ! $this->userSession->isAdmin())) { - throw new AccessForbiddenException(); - } - } -} diff --git a/sources/app/Controller/DashboardController.php b/sources/app/Controller/DashboardController.php deleted file mode 100644 index 4487454..0000000 --- a/sources/app/Controller/DashboardController.php +++ /dev/null @@ -1,183 +0,0 @@ -paginator - ->setUrl('DashboardController', $action, array('pagination' => 'projects', 'user_id' => $user_id)) - ->setMax($max) - ->setOrder(ProjectModel::TABLE.'.name') - ->setQuery($this->projectModel->getQueryColumnStats($this->projectPermissionModel->getActiveProjectIds($user_id))) - ->calculateOnlyIf($this->request->getStringParam('pagination') === 'projects'); - } - - /** - * Get task pagination - * - * @access private - * @param integer $user_id - * @param string $action - * @param integer $max - * @return \Kanboard\Core\Paginator - */ - private function getTaskPaginator($user_id, $action, $max) - { - return $this->paginator - ->setUrl('DashboardController', $action, array('pagination' => 'tasks', 'user_id' => $user_id)) - ->setMax($max) - ->setOrder('tasks.id') - ->setQuery($this->taskFinderModel->getUserQuery($user_id)) - ->calculateOnlyIf($this->request->getStringParam('pagination') === 'tasks'); - } - - /** - * Get subtask pagination - * - * @access private - * @param integer $user_id - * @param string $action - * @param integer $max - * @return \Kanboard\Core\Paginator - */ - private function getSubtaskPaginator($user_id, $action, $max) - { - return $this->paginator - ->setUrl('DashboardController', $action, array('pagination' => 'subtasks', 'user_id' => $user_id)) - ->setMax($max) - ->setOrder('tasks.id') - ->setQuery($this->subtaskModel->getUserQuery($user_id, array(SubTaskModel::STATUS_TODO, SubtaskModel::STATUS_INPROGRESS))) - ->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks'); - } - - /** - * Dashboard overview - * - * @access public - */ - public function show() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->dashboard('dashboard/show', array( - 'title' => t('Dashboard'), - 'project_paginator' => $this->getProjectPaginator($user['id'], 'show', 10), - 'task_paginator' => $this->getTaskPaginator($user['id'], 'show', 10), - 'subtask_paginator' => $this->getSubtaskPaginator($user['id'], 'show', 10), - 'user' => $user, - ))); - } - - /** - * My tasks - * - * @access public - */ - public function tasks() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->dashboard('dashboard/tasks', array( - 'title' => t('My tasks'), - 'paginator' => $this->getTaskPaginator($user['id'], 'tasks', 50), - 'user' => $user, - ))); - } - - /** - * My subtasks - * - * @access public - */ - public function subtasks() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->dashboard('dashboard/subtasks', array( - 'title' => t('My subtasks'), - 'paginator' => $this->getSubtaskPaginator($user['id'], 'subtasks', 50), - 'user' => $user, - ))); - } - - /** - * My projects - * - * @access public - */ - public function projects() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->dashboard('dashboard/projects', array( - 'title' => t('My projects'), - 'paginator' => $this->getProjectPaginator($user['id'], 'projects', 25), - 'user' => $user, - ))); - } - - /** - * My activity stream - * - * @access public - */ - public function activity() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->dashboard('dashboard/activity', array( - 'title' => t('My activity stream'), - 'events' => $this->helper->projectActivity->getProjectsEvents($this->projectPermissionModel->getActiveProjectIds($user['id']), 100), - 'user' => $user, - ))); - } - - /** - * My calendar - * - * @access public - */ - public function calendar() - { - $this->response->html($this->helper->layout->dashboard('dashboard/calendar', array( - 'title' => t('My calendar'), - 'user' => $this->getUser(), - ))); - } - - /** - * My notifications - * - * @access public - */ - public function notifications() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->dashboard('dashboard/notifications', array( - 'title' => t('My notifications'), - 'notifications' => $this->userUnreadNotificationModel->getAll($user['id']), - 'user' => $user, - ))); - } -} diff --git a/sources/app/Controller/DocumentationController.php b/sources/app/Controller/DocumentationController.php deleted file mode 100644 index 0d02ebd..0000000 --- a/sources/app/Controller/DocumentationController.php +++ /dev/null @@ -1,136 +0,0 @@ -request->getStringParam('file', 'index'); - - if (!preg_match('/^[a-z0-9\-]+/', $page)) { - $page = 'index'; - } - - $filename = $this->getPageFilename($page); - $this->response->html($this->helper->layout->app('doc/show', $this->render($filename))); - } - - /** - * Display keyboard shortcut - */ - public function shortcuts() - { - $this->response->html($this->template->render('config/keyboard_shortcuts')); - } - - /** - * Prepare Markdown file - * - * @access private - * @param string $filename - * @return array - */ - private function render($filename) - { - $data = file_get_contents($filename); - $content = preg_replace_callback('/\((.*.markdown)\)/', array($this, 'replaceMarkdownUrl'), $data); - $content = preg_replace_callback('/\((screenshots.*\.png)\)/', array($this, 'replaceImageUrl'), $content); - - list($title, ) = explode("\n", $data, 2); - - return array( - 'content' => Parsedown::instance()->text($content), - 'title' => $title !== 'Documentation' ? t('Documentation: %s', $title) : $title, - ); - } - - /** - * Regex callback to replace Markdown links - * - * @access public - * @param array $matches - * @return string - */ - public function replaceMarkdownUrl(array $matches) - { - return '('.$this->helper->url->to('DocumentationController', 'show', array('file' => str_replace('.markdown', '', $matches[1]))).')'; - } - - /** - * Regex callback to replace image links - * - * @access public - * @param array $matches - * @return string - */ - public function replaceImageUrl(array $matches) - { - return '('.$this->getFileBaseUrl($matches[1]).')'; - } - - /** - * Get Markdown file according to the current language - * - * @access private - * @param string $page - * @return string - */ - private function getPageFilename($page) - { - return $this->getFileLocation($page . '.markdown') ?: - implode(DIRECTORY_SEPARATOR, array(ROOT_DIR, 'doc', 'index.markdown')); - } - - /** - * Get base URL for Markdown links - * - * @access private - * @param string $filename - * @return string - */ - private function getFileBaseUrl($filename) - { - $language = $this->languageModel->getCurrentLanguage(); - $path = $this->getFileLocation($filename); - - if (strpos($path, $language) !== false) { - $url = implode('/', array('doc', $language, $filename)); - } else { - $url = implode('/', array('doc', $filename)); - } - - return $this->helper->url->base().$url; - } - - /** - * Get file location according to the current language - * - * @access private - * @param string $filename - * @return string - */ - private function getFileLocation($filename) - { - $files = array( - implode(DIRECTORY_SEPARATOR, array(ROOT_DIR, 'doc', $this->languageModel->getCurrentLanguage(), $filename)), - implode(DIRECTORY_SEPARATOR, array(ROOT_DIR, 'doc', $filename)), - ); - - foreach ($files as $filename) { - if (file_exists($filename)) { - return $filename; - } - } - - return ''; - } -} diff --git a/sources/app/Controller/ExportController.php b/sources/app/Controller/ExportController.php deleted file mode 100644 index 27046c7..0000000 --- a/sources/app/Controller/ExportController.php +++ /dev/null @@ -1,92 +0,0 @@ -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 { - - $this->response->html($this->helper->layout->project('export/'.$action, array( - 'values' => array( - 'controller' => 'ExportController', - 'action' => $action, - 'project_id' => $project['id'], - 'from' => $from, - 'to' => $to, - ), - 'errors' => array(), - 'date_format' => $this->configModel->get('application_date_format'), - 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()), - 'project' => $project, - 'title' => $page_title, - ), 'export/sidebar')); - } - } - - /** - * Task export - * - * @access public - */ - public function tasks() - { - $this->common('taskExport', 'export', t('Tasks'), 'tasks', t('Tasks Export')); - } - - /** - * Subtask export - * - * @access public - */ - public function subtasks() - { - $this->common('subtaskExport', 'export', t('Subtasks'), 'subtasks', t('Subtasks Export')); - } - - /** - * Daily project summary export - * - * @access public - */ - public function summary() - { - $this->common('projectDailyColumnStatsModel', 'getAggregatedMetrics', t('Summary'), 'summary', t('Daily project summary export')); - } - - /** - * Transition export - * - * @access public - */ - public function transitions() - { - $this->common('transitionExport', 'export', t('Transitions'), 'transitions', t('Task transitions export')); - } -} diff --git a/sources/app/Controller/FeedController.php b/sources/app/Controller/FeedController.php deleted file mode 100644 index cf2b108..0000000 --- a/sources/app/Controller/FeedController.php +++ /dev/null @@ -1,55 +0,0 @@ -request->getStringParam('token'); - $user = $this->userModel->getByToken($token); - - // Token verification - if (empty($user)) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - $this->response->xml($this->template->render('feed/user', array( - 'events' => $this->helper->projectActivity->getProjectsEvents($this->projectPermissionModel->getActiveProjectIds($user['id'])), - 'user' => $user, - ))); - } - - /** - * RSS feed for a project - * - * @access public - */ - public function project() - { - $token = $this->request->getStringParam('token'); - $project = $this->projectModel->getByToken($token); - - if (empty($project)) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - $this->response->xml($this->template->render('feed/project', array( - 'events' => $this->helper->projectActivity->getProjectEvents($project['id']), - 'project' => $project, - ))); - } -} diff --git a/sources/app/Controller/FileViewerController.php b/sources/app/Controller/FileViewerController.php deleted file mode 100644 index 518f5b0..0000000 --- a/sources/app/Controller/FileViewerController.php +++ /dev/null @@ -1,136 +0,0 @@ -objectStorage->get($file['path']); - } - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - } - - return $content; - } - - /** - * Show file content in a popover - * - * @access public - */ - public function show() - { - $file = $this->getFile(); - $type = $this->helper->file->getPreviewType($file['name']); - $params = array('file_id' => $file['id'], 'project_id' => $this->request->getIntegerParam('project_id')); - - if ($file['model'] === 'taskFileModel') { - $params['task_id'] = $file['task_id']; - } - - $this->response->html($this->template->render('file_viewer/show', array( - 'file' => $file, - 'params' => $params, - 'type' => $type, - 'content' => $this->getFileContent($file), - ))); - } - - /** - * Display image - * - * @access public - */ - 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 { - - try { - $this->response->send(); - $this->objectStorage->output($file['path']); - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - } - } - } - - /** - * Display image thumbnail - * - * @access public - */ - public function thumbnail() - { - $file = $this->getFile(); - $model = $file['model']; - $filename = $this->$model->getThumbnailPath($file['path']); - $etag = md5($filename); - - $this->response->withCache(5 * 86400, $etag); - $this->response->withContentType('image/jpeg'); - - if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { - $this->response->status(304); - } else { - - $this->response->send(); - - try { - - $this->objectStorage->output($filename); - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - - // Try to generate thumbnail on the fly for images uploaded before Kanboard < 1.0.19 - $data = $this->objectStorage->get($file['path']); - $this->$model->generateThumbnailFromData($file['path'], $data); - $this->objectStorage->output($this->$model->getThumbnailPath($file['path'])); - } - } - } - - /** - * File download - * - * @access public - */ - public function download() - { - try { - $file = $this->getFile(); - $this->response->withFileDownload($file['name']); - $this->response->send(); - $this->objectStorage->output($file['path']); - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - } - } -} diff --git a/sources/app/Controller/GroupAjaxController.php b/sources/app/Controller/GroupAjaxController.php deleted file mode 100644 index 496e9ef..0000000 --- a/sources/app/Controller/GroupAjaxController.php +++ /dev/null @@ -1,26 +0,0 @@ -request->getStringParam('term'); - $formatter = new GroupAutoCompleteFormatter($this->groupManager->find($search)); - $this->response->json($formatter->format()); - } -} diff --git a/sources/app/Controller/GroupCreationController.php b/sources/app/Controller/GroupCreationController.php deleted file mode 100644 index b297b19..0000000 --- a/sources/app/Controller/GroupCreationController.php +++ /dev/null @@ -1,49 +0,0 @@ -response->html($this->template->render('group_creation/show', array( - 'errors' => $errors, - 'values' => $values, - ))); - } - - /** - * Validate and save a new group - * - * @access public - */ - public function save() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->groupValidator->validateCreation($values); - - if ($valid) { - if ($this->groupModel->create($values['name']) !== false) { - $this->flash->success(t('Group created successfully.')); - return $this->response->redirect($this->helper->url->to('GroupListController', 'index'), true); - } else { - $this->flash->failure(t('Unable to create your group.')); - } - } - - return $this->show($values, $errors); - } -} diff --git a/sources/app/Controller/GroupListController.php b/sources/app/Controller/GroupListController.php deleted file mode 100644 index 4486bbf..0000000 --- a/sources/app/Controller/GroupListController.php +++ /dev/null @@ -1,173 +0,0 @@ -paginator - ->setUrl('GroupListController', 'index') - ->setMax(30) - ->setOrder('name') - ->setQuery($this->groupModel->getQuery()) - ->calculate(); - - $this->response->html($this->helper->layout->app('group/index', array( - 'title' => t('Groups').' ('.$paginator->getTotal().')', - 'paginator' => $paginator, - ))); - } - - /** - * List all users - * - * @access public - */ - public function users() - { - $group_id = $this->request->getIntegerParam('group_id'); - $group = $this->groupModel->getById($group_id); - - $paginator = $this->paginator - ->setUrl('GroupListController', 'users', array('group_id' => $group_id)) - ->setMax(30) - ->setOrder('username') - ->setQuery($this->groupMemberModel->getQuery($group_id)) - ->calculate(); - - $this->response->html($this->helper->layout->app('group/users', array( - 'title' => t('Members of %s', $group['name']).' ('.$paginator->getTotal().')', - 'paginator' => $paginator, - 'group' => $group, - ))); - } - - /** - * Form to associate a user to a group - * - * @access public - * @param array $values - * @param array $errors - */ - public function associate(array $values = array(), array $errors = array()) - { - $group_id = $this->request->getIntegerParam('group_id'); - $group = $this->groupModel->getById($group_id); - - if (empty($values)) { - $values['group_id'] = $group_id; - } - - $this->response->html($this->template->render('group/associate', array( - 'users' => $this->userModel->prepareList($this->groupMemberModel->getNotMembers($group_id)), - 'group' => $group, - 'errors' => $errors, - 'values' => $values, - ))); - } - - /** - * Add user to a group - * - * @access public - */ - public function addUser() - { - $values = $this->request->getValues(); - - if (isset($values['group_id']) && isset($values['user_id'])) { - if ($this->groupMemberModel->addUser($values['group_id'], $values['user_id'])) { - $this->flash->success(t('Group member added successfully.')); - return $this->response->redirect($this->helper->url->to('GroupListController', 'users', array('group_id' => $values['group_id'])), true); - } else { - $this->flash->failure(t('Unable to add group member.')); - } - } - - return $this->associate($values); - } - - /** - * Confirmation dialog to remove a user from a group - * - * @access public - */ - public function dissociate() - { - $group_id = $this->request->getIntegerParam('group_id'); - $user_id = $this->request->getIntegerParam('user_id'); - $group = $this->groupModel->getById($group_id); - $user = $this->userModel->getById($user_id); - - $this->response->html($this->template->render('group/dissociate', array( - 'group' => $group, - 'user' => $user, - ))); - } - - /** - * Remove a user from a group - * - * @access public - */ - public function removeUser() - { - $this->checkCSRFParam(); - $group_id = $this->request->getIntegerParam('group_id'); - $user_id = $this->request->getIntegerParam('user_id'); - - if ($this->groupMemberModel->removeUser($group_id, $user_id)) { - $this->flash->success(t('User removed successfully from this group.')); - } else { - $this->flash->failure(t('Unable to remove this user from the group.')); - } - - $this->response->redirect($this->helper->url->to('GroupListController', 'users', array('group_id' => $group_id)), true); - } - - /** - * Confirmation dialog to remove a group - * - * @access public - */ - public function confirm() - { - $group_id = $this->request->getIntegerParam('group_id'); - $group = $this->groupModel->getById($group_id); - - $this->response->html($this->template->render('group/remove', array( - 'group' => $group, - ))); - } - - /** - * Remove a group - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $group_id = $this->request->getIntegerParam('group_id'); - - if ($this->groupModel->remove($group_id)) { - $this->flash->success(t('Group removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this group.')); - } - - $this->response->redirect($this->helper->url->to('GroupListController', 'index'), true); - } -} diff --git a/sources/app/Controller/GroupModificationController.php b/sources/app/Controller/GroupModificationController.php deleted file mode 100644 index bd181b7..0000000 --- a/sources/app/Controller/GroupModificationController.php +++ /dev/null @@ -1,53 +0,0 @@ -groupModel->getById($this->request->getIntegerParam('group_id')); - } - - $this->response->html($this->template->render('group_modification/show', array( - 'errors' => $errors, - 'values' => $values, - ))); - } - - /** - * Validate and save a group - * - * @access public - */ - public function save() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->groupValidator->validateModification($values); - - if ($valid) { - if ($this->groupModel->update($values) !== false) { - $this->flash->success(t('Group updated successfully.')); - return $this->response->redirect($this->helper->url->to('GroupListController', 'index'), true); - } else { - $this->flash->failure(t('Unable to update your group.')); - } - } - - return $this->show($values, $errors); - } -} diff --git a/sources/app/Controller/ICalendarController.php b/sources/app/Controller/ICalendarController.php deleted file mode 100644 index e354c6f..0000000 --- a/sources/app/Controller/ICalendarController.php +++ /dev/null @@ -1,101 +0,0 @@ -request->getStringParam('token'); - $user = $this->userModel->getByToken($token); - - // Token verification - if (empty($user)) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - // Common filter - $queryBuilder = new QueryBuilder(); - $queryBuilder - ->withQuery($this->taskFinderModel->getICalQuery()) - ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN)) - ->withFilter(new TaskAssigneeFilter($user['id'])); - - // Calendar properties - $calendar = new iCalendar('Kanboard'); - $calendar->setName($user['name'] ?: $user['username']); - $calendar->setDescription($user['name'] ?: $user['username']); - $calendar->setPublishedTTL('PT1H'); - - $this->renderCalendar($queryBuilder, $calendar); - } - - /** - * Get project iCalendar - * - * @access public - */ - public function project() - { - $token = $this->request->getStringParam('token'); - $project = $this->projectModel->getByToken($token); - - // Token verification - if (empty($project)) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - // Common filter - $queryBuilder = new QueryBuilder(); - $queryBuilder - ->withQuery($this->taskFinderModel->getICalQuery()) - ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN)) - ->withFilter(new TaskProjectFilter($project['id'])); - - // Calendar properties - $calendar = new iCalendar('Kanboard'); - $calendar->setName($project['name']); - $calendar->setDescription($project['name']); - $calendar->setPublishedTTL('PT1H'); - - $this->renderCalendar($queryBuilder, $calendar); - } - - /** - * Common method to render iCal events - * - * @access private - * @param QueryBuilder $queryBuilder - * @param iCalendar $calendar - */ - private function renderCalendar(QueryBuilder $queryBuilder, iCalendar $calendar) - { - $start = $this->request->getStringParam('start', strtotime('-2 month')); - $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()); - } -} diff --git a/sources/app/Controller/LinkController.php b/sources/app/Controller/LinkController.php deleted file mode 100644 index 477b25a..0000000 --- a/sources/app/Controller/LinkController.php +++ /dev/null @@ -1,150 +0,0 @@ -linkModel->getById($this->request->getIntegerParam('link_id')); - - if (empty($link)) { - throw new PageNotFoundException(); - } - - return $link; - } - - /** - * List of links - * - * @access public - * @param array $values - * @param array $errors - */ - public function index(array $values = array(), array $errors = array()) - { - $this->response->html($this->helper->layout->config('link/index', array( - 'links' => $this->linkModel->getMergedList(), - 'values' => $values, - 'errors' => $errors, - 'title' => t('Settings').' > '.t('Task\'s links'), - ))); - } - - /** - * Validate and save a new link - * - * @access public - */ - public function save() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->linkValidator->validateCreation($values); - - 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')); - } else { - $this->flash->failure(t('Unable to create your link.')); - } - } - - return $this->index($values, $errors); - } - - /** - * Edit form - * - * @access public - * @param array $values - * @param array $errors - * @throws PageNotFoundException - */ - public function edit(array $values = array(), array $errors = array()) - { - $link = $this->getLink(); - $link['label'] = t($link['label']); - - $this->response->html($this->helper->layout->config('link/edit', array( - 'values' => $values ?: $link, - 'errors' => $errors, - 'labels' => $this->linkModel->getList($link['id']), - 'link' => $link, - 'title' => t('Link modification') - ))); - } - - /** - * Edit a link (validate the form and update the database) - * - * @access public - */ - public function update() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->linkValidator->validateModification($values); - - if ($valid) { - if ($this->linkModel->update($values)) { - $this->flash->success(t('Link updated successfully.')); - return $this->response->redirect($this->helper->url->to('LinkController', 'index')); - } else { - $this->flash->failure(t('Unable to update your link.')); - } - } - - return $this->edit($values, $errors); - } - - /** - * Confirmation dialog before removing a link - * - * @access public - */ - public function confirm() - { - $link = $this->getLink(); - - $this->response->html($this->helper->layout->config('link/remove', array( - 'link' => $link, - 'title' => t('Remove a link') - ))); - } - - /** - * Remove a link - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $link = $this->getLink(); - - if ($this->linkModel->remove($link['id'])) { - $this->flash->success(t('Link removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this link.')); - } - - $this->response->redirect($this->helper->url->to('LinkController', 'index')); - } -} diff --git a/sources/app/Controller/OAuthController.php b/sources/app/Controller/OAuthController.php deleted file mode 100644 index 7663ddc..0000000 --- a/sources/app/Controller/OAuthController.php +++ /dev/null @@ -1,130 +0,0 @@ -request->getStringParam('code'); - $state = $this->request->getStringParam('state'); - - if (! empty($code)) { - $this->step2($provider, $code, $state); - } else { - $this->response->redirect($this->authenticationManager->getProvider($provider)->getService()->getAuthorizationUrl()); - } - } - - /** - * Link or authenticate the user - * - * @access protected - * @param string $providerName - * @param string $code - * @param string $state - */ - protected function step2($providerName, $code, $state) - { - $provider = $this->authenticationManager->getProvider($providerName); - $provider->setCode($code); - $hasValidState = $provider->getService()->isValidateState($state); - - if ($this->userSession->isLogged()) { - if ($hasValidState) { - $this->link($provider); - } else { - $this->flash->failure(t('The OAuth2 state parameter is invalid')); - $this->response->redirect($this->helper->url->to('UserViewController', 'external', array('user_id' => $this->userSession->getId()))); - } - } else { - if ($hasValidState) { - $this->authenticate($providerName); - } else { - $this->authenticationFailure(t('The OAuth2 state parameter is invalid')); - } - } - } - - /** - * Link the account - * - * @access protected - * @param OAuthAuthenticationProviderInterface $provider - */ - protected function link(OAuthAuthenticationProviderInterface $provider) - { - if (! $provider->authenticate()) { - $this->flash->failure(t('External authentication failed')); - } else { - $this->userProfile->assign($this->userSession->getId(), $provider->getUser()); - $this->flash->success(t('Your external account is linked to your profile successfully.')); - } - - $this->response->redirect($this->helper->url->to('UserViewController', 'external', array('user_id' => $this->userSession->getId()))); - } - - /** - * Unlink external account - * - * @access public - */ - public function unlink() - { - $backend = $this->request->getStringParam('backend'); - $this->checkCSRFParam(); - - if ($this->authenticationManager->getProvider($backend)->unlink($this->userSession->getId())) { - $this->flash->success(t('Your external account is not linked anymore to your profile.')); - } else { - $this->flash->failure(t('Unable to unlink your external account.')); - } - - $this->response->redirect($this->helper->url->to('UserViewController', 'external', array('user_id' => $this->userSession->getId()))); - } - - /** - * Authenticate the account - * - * @access protected - * @param string $providerName - */ - protected function authenticate($providerName) - { - if ($this->authenticationManager->oauthAuthentication($providerName)) { - $this->response->redirect($this->helper->url->to('DashboardController', 'show')); - } else { - $this->authenticationFailure(t('External authentication failed')); - } - } - - /** - * Show login failure page - * - * @access protected - * @param string $message - */ - protected function authenticationFailure($message) - { - $this->response->html($this->helper->layout->app('auth/index', array( - 'errors' => array('login' => $message), - 'values' => array(), - 'no_layout' => true, - 'title' => t('Login') - ))); - } -} diff --git a/sources/app/Controller/PasswordResetController.php b/sources/app/Controller/PasswordResetController.php deleted file mode 100644 index a1780ed..0000000 --- a/sources/app/Controller/PasswordResetController.php +++ /dev/null @@ -1,132 +0,0 @@ -checkActivation(); - - $this->response->html($this->helper->layout->app('password_reset/create', array( - 'errors' => $errors, - 'values' => $values, - 'no_layout' => true, - ))); - } - - /** - * Validate and send the email - */ - public function save() - { - $this->checkActivation(); - - $values = $this->request->getValues(); - list($valid, $errors) = $this->passwordResetValidator->validateCreation($values); - - if ($valid) { - $this->sendEmail($values['username']); - $this->response->redirect($this->helper->url->to('AuthController', 'login')); - } else { - $this->create($values, $errors); - } - } - - /** - * Show the form to set a new password - * - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\BaseException - */ - public function change(array $values = array(), array $errors = array()) - { - $this->checkActivation(); - - $token = $this->request->getStringParam('token'); - $user_id = $this->passwordResetModel->getUserIdByToken($token); - - if ($user_id !== false) { - $this->response->html($this->helper->layout->app('password_reset/change', array( - 'token' => $token, - 'errors' => $errors, - 'values' => $values, - 'no_layout' => true, - ))); - } else { - $this->response->redirect($this->helper->url->to('AuthController', 'login')); - } - } - - /** - * Set the new password - */ - public function update() - { - $this->checkActivation(); - - $token = $this->request->getStringParam('token'); - $values = $this->request->getValues(); - list($valid, $errors) = $this->passwordResetValidator->validateModification($values); - - if ($valid) { - $user_id = $this->passwordResetModel->getUserIdByToken($token); - - if ($user_id !== false) { - $this->userModel->update(array('id' => $user_id, 'password' => $values['password'])); - $this->passwordResetModel->disable($user_id); - } - - return $this->response->redirect($this->helper->url->to('AuthController', 'login')); - } - - return $this->change($values, $errors); - } - - /** - * Send the email - * - * @param string $username - */ - private function sendEmail($username) - { - $token = $this->passwordResetModel->create($username); - - if ($token !== false) { - $user = $this->userModel->getByUsername($username); - - $this->emailClient->send( - $user['email'], - $user['name'] ?: $user['username'], - t('Password Reset for Kanboard'), - $this->template->render('password_reset/email', array('token' => $token)) - ); - } - } - - /** - * Check feature availability - */ - private function checkActivation() - { - if ($this->configModel->get('password_reset', 0) == 0) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - } -} diff --git a/sources/app/Controller/PluginController.php b/sources/app/Controller/PluginController.php deleted file mode 100644 index 7b9d64d..0000000 --- a/sources/app/Controller/PluginController.php +++ /dev/null @@ -1,126 +0,0 @@ -response->html($this->helper->layout->plugin('plugin/show', array( - 'plugins' => $this->pluginLoader->getPlugins(), - 'title' => t('Installed Plugins'), - 'is_configured' => Installer::isConfigured(), - ))); - } - - /** - * Display list of available plugins - */ - public function directory() - { - $installedPlugins = array(); - - foreach ($this->pluginLoader->getPlugins() as $plugin) { - $installedPlugins[$plugin->getPluginName()] = $plugin->getPluginVersion(); - } - - $this->response->html($this->helper->layout->plugin('plugin/directory', array( - 'installed_plugins' => $installedPlugins, - 'available_plugins' => Directory::getInstance($this->container)->getAvailablePlugins(), - 'title' => t('Plugin Directory'), - 'is_configured' => Installer::isConfigured(), - ))); - } - - /** - * Install plugin from URL - * - * @throws \Kanboard\Core\Controller\AccessForbiddenException - */ - public function install() - { - $this->checkCSRFParam(); - $pluginArchiveUrl = urldecode($this->request->getStringParam('archive_url')); - - try { - $installer = new Installer($this->container); - $installer->install($pluginArchiveUrl); - $this->flash->success(t('Plugin installed successfully.')); - } catch (PluginInstallerException $e) { - $this->flash->failure($e->getMessage()); - } - - $this->response->redirect($this->helper->url->to('PluginController', 'show')); - } - - /** - * Update plugin from URL - * - * @throws \Kanboard\Core\Controller\AccessForbiddenException - */ - public function update() - { - $this->checkCSRFParam(); - $pluginArchiveUrl = urldecode($this->request->getStringParam('archive_url')); - - try { - $installer = new Installer($this->container); - $installer->update($pluginArchiveUrl); - $this->flash->success(t('Plugin updated successfully.')); - } catch (PluginInstallerException $e) { - $this->flash->failure($e->getMessage()); - } - - $this->response->redirect($this->helper->url->to('PluginController', 'show')); - } - - /** - * Confirmation before to remove the plugin - */ - public function confirm() - { - $pluginId = $this->request->getStringParam('pluginId'); - $plugins = $this->pluginLoader->getPlugins(); - - $this->response->html($this->template->render('plugin/remove', array( - 'plugin_id' => $pluginId, - 'plugin' => $plugins[$pluginId], - ))); - } - - /** - * Remove a plugin - * - * @throws \Kanboard\Core\Controller\AccessForbiddenException - */ - public function uninstall() - { - $this->checkCSRFParam(); - $pluginId = $this->request->getStringParam('pluginId'); - - try { - $installer = new Installer($this->container); - $installer->uninstall($pluginId); - $this->flash->success(t('Plugin removed successfully.')); - } catch (PluginInstallerException $e) { - $this->flash->failure($e->getMessage()); - } - - $this->response->redirect($this->helper->url->to('PluginController', 'show')); - } -} diff --git a/sources/app/Controller/ProjectActionDuplicationController.php b/sources/app/Controller/ProjectActionDuplicationController.php deleted file mode 100644 index a4993cc..0000000 --- a/sources/app/Controller/ProjectActionDuplicationController.php +++ /dev/null @@ -1,38 +0,0 @@ -getProject(); - $projects = $this->projectUserRoleModel->getProjectsByUser($this->userSession->getId()); - unset($projects[$project['id']]); - - $this->response->html($this->template->render('project_action_duplication/show', array( - 'project' => $project, - 'projects_list' => $projects, - ))); - } - - public function save() - { - $project = $this->getProject(); - $src_project_id = $this->request->getValue('src_project_id'); - - if ($this->actionModel->duplicate($src_project_id, $project['id'])) { - $this->flash->success(t('Actions duplicated successfully.')); - } else { - $this->flash->failure(t('Unable to duplicate actions.')); - } - - $this->response->redirect($this->helper->url->to('ActionController', 'index', array('project_id' => $project['id']))); - } -} diff --git a/sources/app/Controller/ProjectCreationController.php b/sources/app/Controller/ProjectCreationController.php deleted file mode 100644 index c471cfd..0000000 --- a/sources/app/Controller/ProjectCreationController.php +++ /dev/null @@ -1,129 +0,0 @@ - t('Do not duplicate anything')) + $this->projectUserRoleModel->getActiveProjectsByUser($this->userSession->getId()); - - $this->response->html($this->helper->layout->app('project_creation/create', array( - 'values' => $values, - 'errors' => $errors, - 'is_private' => $is_private, - 'projects_list' => $projects_list, - 'title' => $is_private ? t('New private project') : t('New project'), - ))); - } - - /** - * Display a form to create a private project - * - * @access public - * @param array $values - * @param array $errors - */ - public function createPrivate(array $values = array(), array $errors = array()) - { - $values['is_private'] = 1; - $this->create($values, $errors); - } - - /** - * Validate and save a new project - * - * @access public - */ - public function save() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->projectValidator->validateCreation($values); - - if ($valid) { - $project_id = $this->createOrDuplicate($values); - - if ($project_id > 0) { - $this->flash->success(t('Your project have been created successfully.')); - return $this->response->redirect($this->helper->url->to('ProjectViewController', 'show', array('project_id' => $project_id))); - } - - $this->flash->failure(t('Unable to create your project.')); - } - - return $this->create($values, $errors); - } - - /** - * Create or duplicate a project - * - * @access private - * @param array $values - * @return boolean|integer - */ - private function createOrDuplicate(array $values) - { - if (empty($values['src_project_id'])) { - return $this->createNewProject($values); - } - - return $this->duplicateNewProject($values); - } - - /** - * Save a new project - * - * @access private - * @param array $values - * @return boolean|integer - */ - private function createNewProject(array $values) - { - $project = array( - 'name' => $values['name'], - 'is_private' => $values['is_private'], - ); - - return $this->projectModel->create($project, $this->userSession->getId(), true); - } - - /** - * Creatte from another project - * - * @access private - * @param array $values - * @return boolean|integer - */ - private function duplicateNewProject(array $values) - { - $selection = array(); - - foreach ($this->projectDuplicationModel->getOptionalSelection() as $item) { - if (isset($values[$item]) && $values[$item] == 1) { - $selection[] = $item; - } - } - - return $this->projectDuplicationModel->duplicate( - $values['src_project_id'], - $selection, - $this->userSession->getId(), - $values['name'], - $values['is_private'] == 1 - ); - } -} diff --git a/sources/app/Controller/ProjectEditController.php b/sources/app/Controller/ProjectEditController.php deleted file mode 100644 index 228d681..0000000 --- a/sources/app/Controller/ProjectEditController.php +++ /dev/null @@ -1,133 +0,0 @@ -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); - } - - /** - * 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); - } - - /** - * Validate and update a project - * - * @access public - */ - public function update() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - $redirect = $this->request->getStringParam('redirect', 'edit'); - - $values = $this->prepareValues($redirect, $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); - } else { - $this->flash->failure(t('Unable to update this project.')); - } - } - - return $this->$redirect($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) - { - 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); - } - } - } - - 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/sources/app/Controller/ProjectFileController.php b/sources/app/Controller/ProjectFileController.php deleted file mode 100644 index cbe4867..0000000 --- a/sources/app/Controller/ProjectFileController.php +++ /dev/null @@ -1,79 +0,0 @@ -getProject(); - - $this->response->html($this->template->render('project_file/create', array( - 'project' => $project, - 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')), - ))); - } - - /** - * Save uploaded files - * - * @access public - */ - public function save() - { - $project = $this->getProject(); - - if (! $this->projectFileModel->uploadFiles($project['id'], $this->request->getFileInfo('files'))) { - $this->flash->failure(t('Unable to upload the file.')); - } - - $this->response->redirect($this->helper->url->to('ProjectOverviewController', 'show', array('project_id' => $project['id'])), true); - } - - /** - * Remove a file - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $file = $this->projectFileModel->getById($this->request->getIntegerParam('file_id')); - - if ($this->projectFileModel->remove($file['id'])) { - $this->flash->success(t('File removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this file.')); - } - - $this->response->redirect($this->helper->url->to('ProjectOverviewController', 'show', array('project_id' => $project['id']))); - } - - /** - * Confirmation dialog before removing a file - * - * @access public - */ - public function confirm() - { - $project = $this->getProject(); - $file = $this->projectFileModel->getById($this->request->getIntegerParam('file_id')); - - $this->response->html($this->template->render('project_file/remove', array( - 'project' => $project, - 'file' => $file, - ))); - } -} diff --git a/sources/app/Controller/ProjectGanttController.php b/sources/app/Controller/ProjectGanttController.php deleted file mode 100644 index a70d9ee..0000000 --- a/sources/app/Controller/ProjectGanttController.php +++ /dev/null @@ -1,57 +0,0 @@ -projectPermissionModel->getActiveProjectIds($this->userSession->getId()); - $filter = $this->projectQuery - ->withFilter(new ProjectTypeFilter(ProjectModel::TYPE_TEAM)) - ->withFilter(new ProjectStatusFilter(ProjectModel::ACTIVE)) - ->withFilter(new ProjectIdsFilter($project_ids)); - - $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)), - 'title' => t('Gantt chart for all projects'), - ))); - } - - /** - * Save new project start date and end date - */ - public function save() - { - $values = $this->request->getJson(); - - $result = $this->projectModel->update(array( - 'id' => $values['id'], - 'start_date' => $this->dateParser->getIsoDate(strtotime($values['start'])), - 'end_date' => $this->dateParser->getIsoDate(strtotime($values['end'])), - )); - - if (! $result) { - $this->response->json(array('message' => 'Unable to save project'), 400); - } else { - $this->response->json(array('message' => 'OK'), 201); - } - } -} diff --git a/sources/app/Controller/ProjectListController.php b/sources/app/Controller/ProjectListController.php deleted file mode 100644 index e117240..0000000 --- a/sources/app/Controller/ProjectListController.php +++ /dev/null @@ -1,41 +0,0 @@ -userSession->isAdmin()) { - $project_ids = $this->projectModel->getAllIds(); - } else { - $project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId()); - } - - $nb_projects = count($project_ids); - - $paginator = $this->paginator - ->setUrl('ProjectListController', 'show') - ->setMax(20) - ->setOrder('name') - ->setQuery($this->projectModel->getQueryColumnStats($project_ids)) - ->calculate(); - - $this->response->html($this->helper->layout->app('project_list/show', array( - 'paginator' => $paginator, - 'nb_projects' => $nb_projects, - 'title' => t('Projects').' ('.$nb_projects.')' - ))); - } -} diff --git a/sources/app/Controller/ProjectOverviewController.php b/sources/app/Controller/ProjectOverviewController.php deleted file mode 100644 index abdff65..0000000 --- a/sources/app/Controller/ProjectOverviewController.php +++ /dev/null @@ -1,32 +0,0 @@ -getProject(); - $this->projectModel->getColumnStats($project); - - $this->response->html($this->helper->layout->app('project_overview/show', array( - 'project' => $project, - 'title' => $project['name'], - 'description' => $this->helper->projectHeader->getDescription($project), - 'users' => $this->projectUserRoleModel->getAllUsersGroupedByRole($project['id']), - 'roles' => $this->role->getProjectRoles(), - 'events' => $this->helper->projectActivity->getProjectEvents($project['id'], 10), - 'images' => $this->projectFileModel->getAllImages($project['id']), - 'files' => $this->projectFileModel->getAllDocuments($project['id']), - ))); - } -} diff --git a/sources/app/Controller/ProjectPermissionController.php b/sources/app/Controller/ProjectPermissionController.php deleted file mode 100644 index f3ca6ed..0000000 --- a/sources/app/Controller/ProjectPermissionController.php +++ /dev/null @@ -1,198 +0,0 @@ -getProject(); - - if (empty($values)) { - $values['role'] = Role::PROJECT_MEMBER; - } - - $this->response->html($this->helper->layout->project('project_permission/index', array( - 'project' => $project, - 'users' => $this->projectUserRoleModel->getUsers($project['id']), - 'groups' => $this->projectGroupRoleModel->getGroups($project['id']), - 'roles' => $this->role->getProjectRoles(), - 'values' => $values, - 'errors' => $errors, - 'title' => t('Project Permissions'), - ))); - } - - /** - * Allow everybody - * - * @access public - */ - public function allowEverybody() - { - $project = $this->getProject(); - $values = $this->request->getValues() + array('is_everybody_allowed' => 0); - - if ($this->projectModel->update($values)) { - $this->flash->success(t('Project updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectPermissionController', 'index', array('project_id' => $project['id']))); - } - - /** - * Add user to the project - * - * @access public - */ - public function addUser() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - if (empty($values['user_id'])) { - $this->flash->failure(t('User not found.')); - } elseif ($this->projectUserRoleModel->addUser($values['project_id'], $values['user_id'], $values['role'])) { - $this->flash->success(t('Project updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectPermissionController', 'index', array('project_id' => $project['id']))); - } - - /** - * Revoke user access - * - * @access public - */ - public function removeUser() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $user_id = $this->request->getIntegerParam('user_id'); - - if ($this->projectUserRoleModel->removeUser($project['id'], $user_id)) { - $this->flash->success(t('Project updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectPermissionController', 'index', array('project_id' => $project['id']))); - } - - /** - * Change user role - * - * @access public - */ - public function changeUserRole() - { - $project = $this->getProject(); - $values = $this->request->getJson(); - - 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')); - } - } - - /** - * Add group to the project - * - * @access public - */ - public function addGroup() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - if (empty($values['group_id']) && ! empty($values['external_id'])) { - $values['group_id'] = $this->groupModel->create($values['name'], $values['external_id']); - } - - if ($this->projectGroupRoleModel->addGroup($project['id'], $values['group_id'], $values['role'])) { - $this->flash->success(t('Project updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectPermissionController', 'index', array('project_id' => $project['id']))); - } - - /** - * Revoke group access - * - * @access public - */ - public function removeGroup() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $group_id = $this->request->getIntegerParam('group_id'); - - if ($this->projectGroupRoleModel->removeGroup($project['id'], $group_id)) { - $this->flash->success(t('Project updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectPermissionController', 'index', array('project_id' => $project['id']))); - } - - /** - * Change group role - * - * @access public - */ - public function changeGroupRole() - { - $project = $this->getProject(); - $values = $this->request->getJson(); - - if (! empty($project) && ! empty($values) && $this->projectGroupRoleModel->changeGroupRole($project['id'], $values['id'], $values['role'])) { - $this->response->json(array('status' => 'ok')); - } else { - $this->response->json(array('status' => 'error')); - } - } -} diff --git a/sources/app/Controller/ProjectStatusController.php b/sources/app/Controller/ProjectStatusController.php deleted file mode 100644 index 78e7787..0000000 --- a/sources/app/Controller/ProjectStatusController.php +++ /dev/null @@ -1,102 +0,0 @@ -getProject(); - - $this->response->html($this->template->render('project_status/enable', array( - 'project' => $project, - 'title' => t('Project activation') - ))); - } - - /** - * Enable the project - */ - public function enable() - { - $project = $this->getProject(); - $this->checkCSRFParam(); - - if ($this->projectModel->enable($project['id'])) { - $this->flash->success(t('Project activated successfully.')); - } else { - $this->flash->failure(t('Unable to activate this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectViewController', 'show', array('project_id' => $project['id'])), true); - } - - /** - * Disable a project (confirmation dialog box) - */ - public function confirmDisable() - { - $project = $this->getProject(); - - $this->response->html($this->template->render('project_status/disable', array( - 'project' => $project, - 'title' => t('Project activation') - ))); - } - - /** - * Disable a project - */ - public function disable() - { - $project = $this->getProject(); - $this->checkCSRFParam(); - - if ($this->projectModel->disable($project['id'])) { - $this->flash->success(t('Project disabled successfully.')); - } else { - $this->flash->failure(t('Unable to disable this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectViewController', 'show', array('project_id' => $project['id'])), true); - } - - /** - * Remove a project (confirmation dialog box) - */ - public function confirmRemove() - { - $project = $this->getProject(); - - $this->response->html($this->template->render('project_status/remove', array( - 'project' => $project, - 'title' => t('Remove project') - ))); - } - - /** - * Remove a project - */ - public function remove() - { - $project = $this->getProject(); - $this->checkCSRFParam(); - - if ($this->projectModel->remove($project['id'])) { - $this->flash->success(t('Project removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectListController', 'show'), true); - } -} diff --git a/sources/app/Controller/ProjectTagController.php b/sources/app/Controller/ProjectTagController.php deleted file mode 100644 index acf514d..0000000 --- a/sources/app/Controller/ProjectTagController.php +++ /dev/null @@ -1,134 +0,0 @@ -getProject(); - - $this->response->html($this->helper->layout->project('project_tag/index', array( - 'project' => $project, - 'tags' => $this->tagModel->getAllByProject($project['id']), - 'title' => t('Project tags management'), - ))); - } - - public function create(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - - if (empty($values)) { - $values['project_id'] = $project['id']; - } - - $this->response->html($this->template->render('project_tag/create', array( - 'project' => $project, - 'values' => $values, - 'errors' => $errors, - ))); - } - - public function save() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - list($valid, $errors) = $this->tagValidator->validateCreation($values); - - if ($valid) { - if ($this->tagModel->create($project['id'], $values['name']) > 0) { - $this->flash->success(t('Tag created successfully.')); - } else { - $this->flash->failure(t('Unable to create this tag.')); - } - - $this->response->redirect($this->helper->url->to('ProjectTagController', 'index', array('project_id' => $project['id']))); - } else { - $this->create($values, $errors); - } - } - - public function edit(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - - if (empty($values)) { - $values = $tag; - } - - $this->response->html($this->template->render('project_tag/edit', array( - 'project' => $project, - 'tag' => $tag, - 'values' => $values, - 'errors' => $errors, - ))); - } - - public function update() - { - $project = $this->getProject(); - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - $values = $this->request->getValues(); - list($valid, $errors) = $this->tagValidator->validateModification($values); - - if ($tag['project_id'] != $project['id']) { - throw new AccessForbiddenException(); - } - - if ($valid) { - if ($this->tagModel->update($values['id'], $values['name'])) { - $this->flash->success(t('Tag updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this tag.')); - } - - $this->response->redirect($this->helper->url->to('ProjectTagController', 'index', array('project_id' => $project['id']))); - } else { - $this->edit($values, $errors); - } - } - - public function confirm() - { - $project = $this->getProject(); - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - - $this->response->html($this->template->render('project_tag/remove', array( - 'tag' => $tag, - 'project' => $project, - ))); - } - - public function remove() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - - if ($tag['project_id'] != $project['id']) { - throw new AccessForbiddenException(); - } - - if ($this->tagModel->remove($tag_id)) { - $this->flash->success(t('Tag removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this tag.')); - } - - $this->response->redirect($this->helper->url->to('ProjectTagController', 'index', array('project_id' => $project['id']))); - } -} diff --git a/sources/app/Controller/ProjectUserOverviewController.php b/sources/app/Controller/ProjectUserOverviewController.php deleted file mode 100644 index 686de83..0000000 --- a/sources/app/Controller/ProjectUserOverviewController.php +++ /dev/null @@ -1,130 +0,0 @@ -request->getIntegerParam('user_id', UserModel::EVERYBODY_ID); - - if ($this->userSession->isAdmin()) { - $project_ids = $this->projectModel->getAllIds(); - } else { - $project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId()); - } - - return array($user_id, $project_ids, $this->userModel->getActiveUsersList(true)); - } - - private function role($role, $action, $title, $title_user) - { - list($user_id, $project_ids, $users) = $this->common(); - - $query = $this->projectPermissionModel->getQueryByRole($project_ids, $role)->callback(array($this->projectModel, 'applyColumnStats')); - - if ($user_id !== UserModel::EVERYBODY_ID && isset($users[$user_id])) { - $query->eq(UserModel::TABLE.'.id', $user_id); - $title = t($title_user, $users[$user_id]); - } - - $paginator = $this->paginator - ->setUrl('ProjectUserOverviewController', $action, array('user_id' => $user_id)) - ->setMax(30) - ->setOrder('projects.name') - ->setQuery($query) - ->calculate(); - - $this->response->html($this->helper->layout->projectUser('project_user_overview/roles', array( - 'paginator' => $paginator, - 'title' => $title, - 'user_id' => $user_id, - 'users' => $users, - ))); - } - - private function tasks($is_active, $action, $title, $title_user) - { - list($user_id, $project_ids, $users) = $this->common(); - - $query = $this->taskFinderModel->getProjectUserOverviewQuery($project_ids, $is_active); - - if ($user_id !== UserModel::EVERYBODY_ID && isset($users[$user_id])) { - $query->eq(TaskModel::TABLE.'.owner_id', $user_id); - $title = t($title_user, $users[$user_id]); - } - - $paginator = $this->paginator - ->setUrl('ProjectUserOverviewController', $action, array('user_id' => $user_id)) - ->setMax(50) - ->setOrder(TaskModel::TABLE.'.id') - ->setQuery($query) - ->calculate(); - - $this->response->html($this->helper->layout->projectUser('project_user_overview/tasks', array( - 'paginator' => $paginator, - 'title' => $title, - 'user_id' => $user_id, - 'users' => $users, - ))); - } - - /** - * Display the list of project managers - * - */ - public function managers() - { - $this->role(Role::PROJECT_MANAGER, 'managers', t('People who are project managers'), 'Projects where "%s" is manager'); - } - - /** - * Display the list of project members - * - */ - public function members() - { - $this->role(Role::PROJECT_MEMBER, 'members', t('People who are project members'), 'Projects where "%s" is member'); - } - - /** - * Display the list of open taks - * - */ - public function opens() - { - $this->tasks(TaskModel::STATUS_OPEN, 'opens', t('Open tasks'), 'Open tasks assigned to "%s"'); - } - - /** - * Display the list of closed tasks - * - */ - public function closed() - { - $this->tasks(TaskModel::STATUS_CLOSED, 'closed', t('Closed tasks'), 'Closed tasks assigned to "%s"'); - } - - /** - * Users tooltip - */ - public function users() - { - $project = $this->getProject(); - - return $this->response->html($this->template->render('project_user_overview/tooltip_users', array( - 'users' => $this->projectUserRoleModel->getAllUsersGroupedByRole($project['id']), - 'roles' => $this->role->getProjectRoles(), - ))); - } -} diff --git a/sources/app/Controller/ProjectViewController.php b/sources/app/Controller/ProjectViewController.php deleted file mode 100644 index 92b9380..0000000 --- a/sources/app/Controller/ProjectViewController.php +++ /dev/null @@ -1,162 +0,0 @@ -getProject(); - - $this->response->html($this->helper->layout->project('project_view/show', array( - 'project' => $project, - 'stats' => $this->projectModel->getTaskStats($project['id']), - 'title' => $project['name'], - ))); - } - - /** - * Public access management - * - * @access public - */ - public function share() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('project_view/share', array( - 'project' => $project, - 'title' => t('Public access'), - ))); - } - - /** - * Change project sharing - * - * @throws \Kanboard\Core\Controller\AccessForbiddenException - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function updateSharing() - { - $project = $this->getProject(); - $this->checkCSRFParam(); - $switch = $this->request->getStringParam('switch'); - - if ($this->projectModel->{$switch.'PublicAccess'}($project['id'])) { - $this->flash->success(t('Project updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectViewController', 'share', array('project_id' => $project['id']))); - } - - /** - * Integrations page - * - * @access public - */ - public function integrations() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('project_view/integrations', array( - 'project' => $project, - 'title' => t('Integrations'), - 'webhook_token' => $this->configModel->get('webhook_token'), - 'values' => $this->projectMetadataModel->getAll($project['id']), - 'errors' => array(), - ))); - } - - /** - * Update integrations - * - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function updateIntegrations() - { - $project = $this->getProject(); - - $this->projectMetadataModel->save($project['id'], $this->request->getValues()); - $this->flash->success(t('Project updated successfully.')); - $this->response->redirect($this->helper->url->to('ProjectViewController', 'integrations', array('project_id' => $project['id']))); - } - - /** - * Display project notifications - * - * @access public - */ - public function notifications() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('project_view/notifications', array( - 'notifications' => $this->projectNotificationModel->readSettings($project['id']), - 'types' => $this->projectNotificationTypeModel->getTypes(), - 'project' => $project, - 'title' => t('Notifications'), - ))); - } - - /** - * Update notifications - * - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function updateNotifications() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - $this->projectNotificationModel->saveSettings($project['id'], $values); - $this->flash->success(t('Project updated successfully.')); - $this->response->redirect($this->helper->url->to('ProjectViewController', 'notifications', array('project_id' => $project['id']))); - } - - /** - * Duplicate a project - * - * @author Antonio Rabelo - * @author Michael Lüpkes - * @access public - */ - public function duplicate() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('project_view/duplicate', array( - 'project' => $project, - 'title' => t('Clone this project') - ))); - } - - /** - * Do project duplication - */ - public function doDuplication() - { - $project = $this->getProject(); - $project_id = $this->projectDuplicationModel->duplicate($project['id'], array_keys($this->request->getValues()), $this->userSession->getId()); - - if ($project_id !== false) { - $this->flash->success(t('Project cloned successfully.')); - } else { - $this->flash->failure(t('Unable to clone this project.')); - } - - $this->response->redirect($this->helper->url->to('ProjectViewController', 'show', array('project_id' => $project_id))); - } -} diff --git a/sources/app/Controller/SearchController.php b/sources/app/Controller/SearchController.php deleted file mode 100644 index 8557b18..0000000 --- a/sources/app/Controller/SearchController.php +++ /dev/null @@ -1,67 +0,0 @@ -projectUserRoleModel->getProjectsByUser($this->userSession->getId()); - $search = urldecode($this->request->getStringParam('search')); - $nb_tasks = 0; - - $paginator = $this->paginator - ->setUrl('SearchController', 'index', array('search' => $search)) - ->setMax(30) - ->setOrder('tasks.id') - ->setDirection('DESC'); - - if ($search !== '' && ! empty($projects)) { - $paginator - ->setQuery($this->taskLexer - ->build($search) - ->withFilter(new TaskProjectsFilter(array_keys($projects))) - ->getQuery() - ) - ->calculate(); - - $nb_tasks = $paginator->getTotal(); - } - - $this->response->html($this->helper->layout->app('search/index', array( - 'values' => array( - 'search' => $search, - 'controller' => 'SearchController', - 'action' => 'index', - ), - 'paginator' => $paginator, - 'title' => t('Search tasks').($nb_tasks > 0 ? ' ('.$nb_tasks.')' : '') - ))); - } - - public function activity() - { - $search = urldecode($this->request->getStringParam('search')); - $events = $this->helper->projectActivity->searchEvents($search); - $nb_events = count($events); - - $this->response->html($this->helper->layout->app('search/activity', array( - 'values' => array( - 'search' => $search, - 'controller' => 'SearchController', - 'action' => 'activity', - ), - 'title' => t('Search in activity stream').($nb_events > 0 ? ' ('.$nb_events.')' : ''), - 'nb_events' => $nb_events, - 'events' => $events, - ))); - } -} diff --git a/sources/app/Controller/SubtaskController.php b/sources/app/Controller/SubtaskController.php deleted file mode 100644 index 93dab5c..0000000 --- a/sources/app/Controller/SubtaskController.php +++ /dev/null @@ -1,177 +0,0 @@ -getTask(); - - if (empty($values)) { - $values = array( - 'task_id' => $task['id'], - 'another_subtask' => $this->request->getIntegerParam('another_subtask', 0) - ); - } - - $this->response->html($this->template->render('subtask/create', array( - 'values' => $values, - 'errors' => $errors, - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($task['project_id']), - 'task' => $task, - ))); - } - - /** - * Validation and creation - * - * @access public - */ - public function save() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->subtaskValidator->validateCreation($values); - - if ($valid) { - if ($this->subtaskModel->create($values) !== false) { - $this->flash->success(t('Sub-task added successfully.')); - } else { - $this->flash->failure(t('Unable to create your sub-task.')); - } - - if (isset($values['another_subtask']) && $values['another_subtask'] == 1) { - return $this->create(array('project_id' => $task['project_id'], 'task_id' => $task['id'], 'another_subtask' => 1)); - } - - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'), true); - } - - return $this->create($values, $errors); - } - - /** - * Edit form - * - * @access public - * @param array $values - * @param array $errors - * @throws AccessForbiddenException - * @throws PageNotFoundException - */ - public function edit(array $values = array(), array $errors = array()) - { - $task = $this->getTask(); - $subtask = $this->getSubtask(); - - $this->response->html($this->template->render('subtask/edit', array( - 'values' => empty($values) ? $subtask : $values, - 'errors' => $errors, - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($task['project_id']), - 'status_list' => $this->subtaskModel->getStatusList(), - 'subtask' => $subtask, - 'task' => $task, - ))); - } - - /** - * Update and validate a subtask - * - * @access public - */ - public function update() - { - $task = $this->getTask(); - $this->getSubtask(); - - $values = $this->request->getValues(); - list($valid, $errors) = $this->subtaskValidator->validateModification($values); - - if ($valid) { - if ($this->subtaskModel->update($values)) { - $this->flash->success(t('Sub-task updated successfully.')); - } else { - $this->flash->failure(t('Unable to update your sub-task.')); - } - - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); - } - - return $this->edit($values, $errors); - } - - /** - * Confirmation dialog before removing a subtask - * - * @access public - */ - public function confirm() - { - $task = $this->getTask(); - $subtask = $this->getSubtask(); - - $this->response->html($this->template->render('subtask/remove', array( - 'subtask' => $subtask, - 'task' => $task, - ))); - } - - /** - * Remove a subtask - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $task = $this->getTask(); - $subtask = $this->getSubtask(); - - if ($this->subtaskModel->remove($subtask['id'])) { - $this->flash->success(t('Sub-task removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this sub-task.')); - } - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); - } - - /** - * Move subtask position - * - * @access public - */ - public function movePosition() - { - $project_id = $this->request->getIntegerParam('project_id'); - $task_id = $this->request->getIntegerParam('task_id'); - $values = $this->request->getJson(); - - if (! empty($values) && $this->helper->user->hasProjectAccess('SubtaskController', 'movePosition', $project_id)) { - $result = $this->subtaskModel->changePosition($task_id, $values['subtask_id'], $values['position']); - $this->response->json(array('result' => $result)); - } else { - throw new AccessForbiddenException(); - } - } -} diff --git a/sources/app/Controller/SubtaskConverterController.php b/sources/app/Controller/SubtaskConverterController.php deleted file mode 100644 index 65bcd2d..0000000 --- a/sources/app/Controller/SubtaskConverterController.php +++ /dev/null @@ -1,39 +0,0 @@ -getTask(); - $subtask = $this->getSubtask(); - - $this->response->html($this->template->render('subtask_converter/show', array( - 'subtask' => $subtask, - 'task' => $task, - ))); - } - - public function save() - { - $project = $this->getProject(); - $subtask = $this->getSubtask(); - - $task_id = $this->subtaskModel->convertToTask($project['id'], $subtask['id']); - - if ($task_id !== false) { - $this->flash->success(t('Subtask converted to task successfully.')); - } else { - $this->flash->failure(t('Unable to convert the subtask.')); - } - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $project['id'], 'task_id' => $task_id)), true); - } -} diff --git a/sources/app/Controller/SubtaskRestrictionController.php b/sources/app/Controller/SubtaskRestrictionController.php deleted file mode 100644 index 084fc0d..0000000 --- a/sources/app/Controller/SubtaskRestrictionController.php +++ /dev/null @@ -1,61 +0,0 @@ -getTask(); - $subtask = $this->getSubtask(); - - $this->response->html($this->template->render('subtask_restriction/show', array( - 'status_list' => array( - SubtaskModel::STATUS_TODO => t('Todo'), - SubtaskModel::STATUS_DONE => t('Done'), - ), - 'subtask_inprogress' => $this->subtaskModel->getSubtaskInProgress($this->userSession->getId()), - 'subtask' => $subtask, - 'task' => $task, - ))); - } - - /** - * Change status of the in progress subtask and the other subtask - * - * @access public - */ - public function save() - { - $task = $this->getTask(); - $subtask = $this->getSubtask(); - $values = $this->request->getValues(); - - // Change status of the previous "in progress" subtask - $this->subtaskModel->update(array( - 'id' => $values['id'], - 'status' => $values['status'], - )); - - // Set the current subtask to "in progress" - $this->subtaskModel->update(array( - 'id' => $subtask['id'], - 'status' => SubtaskModel::STATUS_INPROGRESS, - )); - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); - } -} diff --git a/sources/app/Controller/SubtaskStatusController.php b/sources/app/Controller/SubtaskStatusController.php deleted file mode 100644 index 699951f..0000000 --- a/sources/app/Controller/SubtaskStatusController.php +++ /dev/null @@ -1,71 +0,0 @@ - In Progress -> Done - * - * @access public - */ - public function change() - { - $task = $this->getTask(); - $subtask = $this->getSubtask(); - - $status = $this->subtaskModel->toggleStatus($subtask['id']); - - if ($this->request->getIntegerParam('refresh-table') === 0) { - $subtask['status'] = $status; - $html = $this->helper->subtask->toggleStatus($subtask, $task['project_id']); - } else { - $html = $this->renderTable($task); - } - - $this->response->html($html); - } - - /** - * Start/stop timer for subtasks - * - * @access public - */ - public function timer() - { - $task = $this->getTask(); - $subtask_id = $this->request->getIntegerParam('subtask_id'); - $timer = $this->request->getStringParam('timer'); - - if ($timer === 'start') { - $this->subtaskTimeTrackingModel->logStartTime($subtask_id, $this->userSession->getId()); - } elseif ($timer === 'stop') { - $this->subtaskTimeTrackingModel->logEndTime($subtask_id, $this->userSession->getId()); - $this->subtaskTimeTrackingModel->updateTaskTimeTracking($task['id']); - } - - $this->response->html($this->renderTable($task)); - } - - /** - * Render table - * - * @access private - * @param array $task - * @return string - */ - private function renderTable(array $task) - { - return $this->template->render('subtask/table', array( - 'task' => $task, - 'subtasks' => $this->subtaskModel->getAll($task['id']), - 'editable' => true, - )); - } -} diff --git a/sources/app/Controller/SwimlaneController.php b/sources/app/Controller/SwimlaneController.php deleted file mode 100644 index c7c20ce..0000000 --- a/sources/app/Controller/SwimlaneController.php +++ /dev/null @@ -1,314 +0,0 @@ -swimlaneModel->getById($this->request->getIntegerParam('swimlane_id')); - - if (empty($swimlane)) { - throw new PageNotFoundException(); - } - - return $swimlane; - } - - /** - * List of swimlanes for a given project - * - * @access public - */ - public function index() - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project('swimlane/index', array( - 'default_swimlane' => $this->swimlaneModel->getDefault($project['id']), - 'active_swimlanes' => $this->swimlaneModel->getAllByStatus($project['id'], SwimlaneModel::ACTIVE), - 'inactive_swimlanes' => $this->swimlaneModel->getAllByStatus($project['id'], SwimlaneModel::INACTIVE), - 'project' => $project, - 'title' => t('Swimlanes') - ))); - } - - /** - * Create a new swimlane - * - * @access public - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function create(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - - $this->response->html($this->template->render('swimlane/create', array( - 'values' => $values + array('project_id' => $project['id']), - 'errors' => $errors, - 'project' => $project, - ))); - } - - /** - * Validate and save a new swimlane - * - * @access public - */ - public function save() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - list($valid, $errors) = $this->swimlaneValidator->validateCreation($values); - - if ($valid) { - if ($this->swimlaneModel->create($values) !== false) { - $this->flash->success(t('Your swimlane have been created successfully.')); - return $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id']))); - } else { - $errors = array('name' => array(t('Another swimlane with the same name exists in the project'))); - } - } - - return $this->create($values, $errors); - } - - /** - * Edit default swimlane (display the form) - * - * @access public - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function editDefault(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - $swimlane = $this->swimlaneModel->getDefault($project['id']); - - $this->response->html($this->helper->layout->project('swimlane/edit_default', array( - 'values' => empty($values) ? $swimlane : $values, - 'errors' => $errors, - 'project' => $project, - ))); - } - - /** - * Change the default swimlane - * - * @access public - */ - public function updateDefault() - { - $project = $this->getProject(); - - $values = $this->request->getValues() + array('show_default_swimlane' => 0); - list($valid, $errors) = $this->swimlaneValidator->validateDefaultModification($values); - - if ($valid) { - if ($this->swimlaneModel->updateDefault($values)) { - $this->flash->success(t('The default swimlane have been updated successfully.')); - return $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id'])), true); - } else { - $this->flash->failure(t('Unable to update this swimlane.')); - } - } - - return $this->editDefault($values, $errors); - } - - /** - * Edit a swimlane (display the form) - * - * @access public - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function edit(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - $swimlane = $this->getSwimlane(); - - $this->response->html($this->helper->layout->project('swimlane/edit', array( - 'values' => empty($values) ? $swimlane : $values, - 'errors' => $errors, - 'project' => $project, - ))); - } - - /** - * Edit a swimlane (validate the form and update the database) - * - * @access public - */ - public function update() - { - $project = $this->getProject(); - - $values = $this->request->getValues(); - list($valid, $errors) = $this->swimlaneValidator->validateModification($values); - - if ($valid) { - if ($this->swimlaneModel->update($values)) { - $this->flash->success(t('Swimlane updated successfully.')); - return $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id']))); - } else { - $errors = array('name' => array(t('Another swimlane with the same name exists in the project'))); - } - } - - return $this->edit($values, $errors); - } - - /** - * Confirmation dialog before removing a swimlane - * - * @access public - */ - public function confirm() - { - $project = $this->getProject(); - $swimlane = $this->getSwimlane(); - - $this->response->html($this->helper->layout->project('swimlane/remove', array( - 'project' => $project, - 'swimlane' => $swimlane, - ))); - } - - /** - * Remove a swimlane - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $swimlane_id = $this->request->getIntegerParam('swimlane_id'); - - if ($this->swimlaneModel->remove($project['id'], $swimlane_id)) { - $this->flash->success(t('Swimlane removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this swimlane.')); - } - - $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id']))); - } - - /** - * Disable a swimlane - * - * @access public - */ - public function disable() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $swimlane_id = $this->request->getIntegerParam('swimlane_id'); - - if ($this->swimlaneModel->disable($project['id'], $swimlane_id)) { - $this->flash->success(t('Swimlane updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this swimlane.')); - } - - $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id']))); - } - - /** - * Disable default swimlane - * - * @access public - */ - public function disableDefault() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - - if ($this->swimlaneModel->disableDefault($project['id'])) { - $this->flash->success(t('Swimlane updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this swimlane.')); - } - - $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id']))); - } - - /** - * Enable a swimlane - * - * @access public - */ - public function enable() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - $swimlane_id = $this->request->getIntegerParam('swimlane_id'); - - if ($this->swimlaneModel->enable($project['id'], $swimlane_id)) { - $this->flash->success(t('Swimlane updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this swimlane.')); - } - - $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id']))); - } - - /** - * Enable default swimlane - * - * @access public - */ - public function enableDefault() - { - $this->checkCSRFParam(); - $project = $this->getProject(); - - if ($this->swimlaneModel->enableDefault($project['id'])) { - $this->flash->success(t('Swimlane updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this swimlane.')); - } - - $this->response->redirect($this->helper->url->to('SwimlaneController', 'index', array('project_id' => $project['id']))); - } - - /** - * Move swimlane position - * - * @access public - */ - public function move() - { - $project = $this->getProject(); - $values = $this->request->getJson(); - - if (! empty($values) && isset($values['swimlane_id']) && isset($values['position'])) { - $result = $this->swimlaneModel->changePosition($project['id'], $values['swimlane_id'], $values['position']); - $this->response->json(array('result' => $result)); - } else { - throw new AccessForbiddenException(); - } - } -} diff --git a/sources/app/Controller/TagController.php b/sources/app/Controller/TagController.php deleted file mode 100644 index b838991..0000000 --- a/sources/app/Controller/TagController.php +++ /dev/null @@ -1,121 +0,0 @@ -response->html($this->helper->layout->config('tag/index', array( - 'tags' => $this->tagModel->getAllByProject(0), - 'title' => t('Settings').' > '.t('Global tags management'), - ))); - } - - public function create(array $values = array(), array $errors = array()) - { - if (empty($values)) { - $values['project_id'] = 0; - } - - $this->response->html($this->template->render('tag/create', array( - 'values' => $values, - 'errors' => $errors, - ))); - } - - public function save() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->tagValidator->validateCreation($values); - - if ($valid) { - if ($this->tagModel->create(0, $values['name']) > 0) { - $this->flash->success(t('Tag created successfully.')); - } else { - $this->flash->failure(t('Unable to create this tag.')); - } - - $this->response->redirect($this->helper->url->to('TagController', 'index')); - } else { - $this->create($values, $errors); - } - } - - public function edit(array $values = array(), array $errors = array()) - { - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - - if (empty($values)) { - $values = $tag; - } - - $this->response->html($this->template->render('tag/edit', array( - 'tag' => $tag, - 'values' => $values, - 'errors' => $errors, - ))); - } - - public function update() - { - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - $values = $this->request->getValues(); - list($valid, $errors) = $this->tagValidator->validateModification($values); - - if ($tag['project_id'] != 0) { - throw new AccessForbiddenException(); - } - - if ($valid) { - if ($this->tagModel->update($values['id'], $values['name'])) { - $this->flash->success(t('Tag updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this tag.')); - } - - $this->response->redirect($this->helper->url->to('TagController', 'index')); - } else { - $this->edit($values, $errors); - } - } - - public function confirm() - { - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - - $this->response->html($this->template->render('tag/remove', array( - 'tag' => $tag, - ))); - } - - public function remove() - { - $this->checkCSRFParam(); - $tag_id = $this->request->getIntegerParam('tag_id'); - $tag = $this->tagModel->getById($tag_id); - - if ($tag['project_id'] != 0) { - throw new AccessForbiddenException(); - } - - if ($this->tagModel->remove($tag_id)) { - $this->flash->success(t('Tag removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this tag.')); - } - - $this->response->redirect($this->helper->url->to('TagController', 'index')); - } -} diff --git a/sources/app/Controller/TaskAjaxController.php b/sources/app/Controller/TaskAjaxController.php deleted file mode 100644 index f9feff1..0000000 --- a/sources/app/Controller/TaskAjaxController.php +++ /dev/null @@ -1,49 +0,0 @@ -request->getStringParam('term'); - $project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId()); - $exclude_task_id = $this->request->getIntegerParam('exclude_task_id'); - - if (empty($project_ids)) { - $this->response->json(array()); - } else { - - $filter = $this->taskQuery->withFilter(new TaskProjectsFilter($project_ids)); - - if (! empty($exclude_task_id)) { - $filter->withFilter(new TaskIdExclusionFilter(array($exclude_task_id))); - } - - if (ctype_digit($search)) { - $filter->withFilter(new TaskIdFilter($search)); - } else { - $filter->withFilter(new TaskTitleFilter($search)); - } - - $this->response->json($filter->format(new TaskAutoCompleteFormatter($this->container))); - } - } -} diff --git a/sources/app/Controller/TaskBulkController.php b/sources/app/Controller/TaskBulkController.php deleted file mode 100644 index df7f589..0000000 --- a/sources/app/Controller/TaskBulkController.php +++ /dev/null @@ -1,89 +0,0 @@ -getProject(); - - if (empty($values)) { - $values = array( - 'swimlane_id' => $this->request->getIntegerParam('swimlane_id'), - 'column_id' => $this->request->getIntegerParam('column_id'), - 'project_id' => $project['id'], - ); - } - - $this->response->html($this->template->render('task_bulk/show', array( - 'project' => $project, - 'values' => $values, - 'errors' => $errors, - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true), - 'colors_list' => $this->colorModel->getList(), - 'categories_list' => $this->categoryModel->getList($project['id']), - ))); - } - - /** - * Save all tasks in the database - */ - public function save() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - list($valid, $errors) = $this->taskValidator->validateBulkCreation($values); - - if ($valid) { - $this->createTasks($project, $values); - $this->response->redirect($this->helper->url->to( - 'BoardViewController', - 'show', - array('project_id' => $project['id']), - 'swimlane-'. $values['swimlane_id'] - ), true); - } else { - $this->show($values, $errors); - } - } - - /** - * Create all tasks - * - * @param array $project - * @param array $values - */ - protected function createTasks(array $project, array $values) - { - $tasks = preg_split('/\r\n|[\r\n]/', $values['tasks']); - - foreach ($tasks as $title) { - $title = trim($title); - - if (! empty($title)) { - $this->taskCreationModel->create(array( - 'title' => $title, - 'column_id' => $values['column_id'], - 'swimlane_id' => $values['swimlane_id'], - 'category_id' => empty($values['category_id']) ? 0 : $values['category_id'], - 'owner_id' => empty($values['owner_id']) ? 0 : $values['owner_id'], - 'color_id' => $values['color_id'], - 'project_id' => $project['id'], - )); - } - } - } -} diff --git a/sources/app/Controller/TaskCreationController.php b/sources/app/Controller/TaskCreationController.php deleted file mode 100644 index 073b31b..0000000 --- a/sources/app/Controller/TaskCreationController.php +++ /dev/null @@ -1,86 +0,0 @@ -getProject(); - $swimlanes_list = $this->swimlaneModel->getList($project['id'], false, true); - - if (empty($values)) { - $values = array( - 'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanes_list)), - 'column_id' => $this->request->getIntegerParam('column_id'), - 'color_id' => $this->colorModel->getDefaultColor(), - 'owner_id' => $this->userSession->getId(), - ); - - $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)); - } - - $this->response->html($this->template->render('task_creation/show', array( - 'project' => $project, - '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), - 'categories_list' => $this->categoryModel->getList($project['id']), - 'swimlanes_list' => $swimlanes_list, - 'title' => $project['name'].' > '.t('New task') - ))); - } - - /** - * 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.')); - return $this->afterSave($project, $values); - } - - $this->flash->failure(t('Unable to create your task.')); - return $this->show($values, $errors); - } - - private function afterSave(array $project, array &$values) - { - if (isset($values['another_task']) && $values['another_task'] == 1) { - return $this->show(array( - 'owner_id' => $values['owner_id'], - 'color_id' => $values['color_id'], - 'category_id' => isset($values['category_id']) ? $values['category_id'] : 0, - 'column_id' => $values['column_id'], - 'swimlane_id' => isset($values['swimlane_id']) ? $values['swimlane_id'] : 0, - 'another_task' => 1, - )); - } - - return $this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id'])), true); - } -} diff --git a/sources/app/Controller/TaskDuplicationController.php b/sources/app/Controller/TaskDuplicationController.php deleted file mode 100644 index 915bf8f..0000000 --- a/sources/app/Controller/TaskDuplicationController.php +++ /dev/null @@ -1,141 +0,0 @@ -getTask(); - - if ($this->request->getStringParam('confirmation') === 'yes') { - $this->checkCSRFParam(); - $task_id = $this->taskDuplicationModel->duplicate($task['id']); - - if ($task_id > 0) { - $this->flash->success(t('Task created successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task_id))); - } else { - $this->flash->failure(t('Unable to create this task.')); - return $this->response->redirect($this->helper->url->to('TaskDuplicationController', 'duplicate', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); - } - } - - return $this->response->html($this->template->render('task_duplication/duplicate', array( - 'task' => $task, - ))); - } - - /** - * Move a task to another project - * - * @access public - */ - public function move() - { - $task = $this->getTask(); - - if ($this->request->isPost()) { - $values = $this->request->getValues(); - list($valid, ) = $this->taskValidator->validateProjectModification($values); - - if ($valid && $this->taskProjectMoveModel->moveToProject($task['id'], - $values['project_id'], - $values['swimlane_id'], - $values['column_id'], - $values['category_id'], - $values['owner_id'])) { - $this->flash->success(t('Task updated successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $values['project_id'], 'task_id' => $task['id']))); - } - - $this->flash->failure(t('Unable to update your task.')); - } - - return $this->chooseDestination($task, 'task_duplication/move'); - } - - /** - * Duplicate a task to another project - * - * @access public - */ - public function copy() - { - $task = $this->getTask(); - - if ($this->request->isPost()) { - $values = $this->request->getValues(); - list($valid, ) = $this->taskValidator->validateProjectModification($values); - - if ($valid) { - $task_id = $this->taskProjectDuplicationModel->duplicateToProject( - $task['id'], $values['project_id'], $values['swimlane_id'], - $values['column_id'], $values['category_id'], $values['owner_id'] - ); - - if ($task_id > 0) { - $this->flash->success(t('Task created successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $values['project_id'], 'task_id' => $task_id))); - } - } - - $this->flash->failure(t('Unable to create your task.')); - } - - return $this->chooseDestination($task, 'task_duplication/copy'); - } - - /** - * Choose destination when move/copy task to another project - * - * @access private - * @param array $task - * @param string $template - */ - private function chooseDestination(array $task, $template) - { - $values = array(); - $projects_list = $this->projectUserRoleModel->getActiveProjectsByUser($this->userSession->getId()); - - unset($projects_list[$task['project_id']]); - - if (! empty($projects_list)) { - $dst_project_id = $this->request->getIntegerParam('dst_project_id', key($projects_list)); - - $swimlanes_list = $this->swimlaneModel->getList($dst_project_id, false, true); - $columns_list = $this->columnModel->getList($dst_project_id); - $categories_list = $this->categoryModel->getList($dst_project_id); - $users_list = $this->projectUserRoleModel->getAssignableUsersList($dst_project_id); - - $values = $this->taskDuplicationModel->checkDestinationProjectValues($task); - $values['project_id'] = $dst_project_id; - } else { - $swimlanes_list = array(); - $columns_list = array(); - $categories_list = array(); - $users_list = array(); - } - - $this->response->html($this->template->render($template, array( - 'values' => $values, - 'task' => $task, - 'projects_list' => $projects_list, - 'swimlanes_list' => $swimlanes_list, - 'columns_list' => $columns_list, - 'categories_list' => $categories_list, - 'users_list' => $users_list, - ))); - } -} diff --git a/sources/app/Controller/TaskExternalLinkController.php b/sources/app/Controller/TaskExternalLinkController.php deleted file mode 100644 index 9c04eb0..0000000 --- a/sources/app/Controller/TaskExternalLinkController.php +++ /dev/null @@ -1,178 +0,0 @@ -getTask(); - - $this->response->html($this->template->render('task_external_link/find', array( - 'values' => $values, - 'errors' => $errors, - 'task' => $task, - 'types' => $this->externalLinkManager->getTypes(), - ))); - } - - /** - * Second creation form - * - * @access public - */ - public function create() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - - try { - $provider = $this->externalLinkManager->setUserInput($values)->find(); - $link = $provider->getLink(); - - $this->response->html($this->template->render('task_external_link/create', array( - 'values' => array( - 'title' => $link->getTitle(), - 'url' => $link->getUrl(), - 'link_type' => $provider->getType(), - ), - 'dependencies' => $provider->getDependencies(), - 'errors' => array(), - 'task' => $task, - ))); - - } catch (ExternalLinkProviderNotFound $e) { - $errors = array('text' => array(t('Unable to fetch link information.'))); - $this->find($values, $errors); - } - } - - /** - * Save link - * - * @access public - */ - public function save() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - list($valid, $errors) = $this->externalLinkValidator->validateCreation($values); - - if ($valid && $this->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); - } - - return $this->edit($values, $errors); - } - - /** - * Edit form - * - * @access public - * @param array $values - * @param array $errors - * @throws ExternalLinkProviderNotFound - * @throws PageNotFoundException - * @throws \Kanboard\Core\Controller\AccessForbiddenException - */ - public function edit(array $values = array(), array $errors = array()) - { - $task = $this->getTask(); - $link_id = $this->request->getIntegerParam('link_id'); - - if ($link_id > 0) { - $values = $this->taskExternalLinkModel->getById($link_id); - } - - if (empty($values)) { - throw new PageNotFoundException(); - } - - $provider = $this->externalLinkManager->getProvider($values['link_type']); - - $this->response->html($this->template->render('task_external_link/edit', array( - 'values' => $values, - 'errors' => $errors, - 'task' => $task, - 'dependencies' => $provider->getDependencies(), - ))); - } - - /** - * Update link - * - * @access public - */ - public function update() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - list($valid, $errors) = $this->externalLinkValidator->validateModification($values); - - if ($valid && $this->taskExternalLinkModel->update($values)) { - $this->flash->success(t('Link updated successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); - } - - return $this->edit($values, $errors); - } - - /** - * Confirmation dialog before removing a link - * - * @access public - */ - public function confirm() - { - $task = $this->getTask(); - $link_id = $this->request->getIntegerParam('link_id'); - $link = $this->taskExternalLinkModel->getById($link_id); - - if (empty($link)) { - throw new PageNotFoundException(); - } - - $this->response->html($this->template->render('task_external_link/remove', array( - 'link' => $link, - 'task' => $task, - ))); - } - - /** - * Remove a link - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $task = $this->getTask(); - - if ($this->taskExternalLinkModel->remove($this->request->getIntegerParam('link_id'))) { - $this->flash->success(t('Link removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this link.')); - } - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); - } -} diff --git a/sources/app/Controller/TaskFileController.php b/sources/app/Controller/TaskFileController.php deleted file mode 100644 index 77c0c02..0000000 --- a/sources/app/Controller/TaskFileController.php +++ /dev/null @@ -1,98 +0,0 @@ -getTask(); - - if ($this->request->isPost() && $this->taskFileModel->uploadScreenshot($task['id'], $this->request->getValue('screenshot')) !== false) { - $this->flash->success(t('Screenshot uploaded successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); - } - - return $this->response->html($this->template->render('task_file/screenshot', array( - 'task' => $task, - ))); - } - - /** - * File upload form - * - * @access public - */ - public function create() - { - $task = $this->getTask(); - - $this->response->html($this->template->render('task_file/create', array( - 'task' => $task, - 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')), - ))); - } - - /** - * File upload (save files) - * - * @access public - */ - public function save() - { - $task = $this->getTask(); - - if (! $this->taskFileModel->uploadFiles($task['id'], $this->request->getFileInfo('files'))) { - $this->flash->failure(t('Unable to upload the file.')); - } - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); - } - - /** - * Remove a file - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $task = $this->getTask(); - $file = $this->taskFileModel->getById($this->request->getIntegerParam('file_id')); - - if ($file['task_id'] == $task['id'] && $this->taskFileModel->remove($file['id'])) { - $this->flash->success(t('File removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this file.')); - } - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); - } - - /** - * Confirmation dialog before removing a file - * - * @access public - */ - public function confirm() - { - $task = $this->getTask(); - $file = $this->taskFileModel->getById($this->request->getIntegerParam('file_id')); - - $this->response->html($this->template->render('task_file/remove', array( - 'task' => $task, - 'file' => $file, - ))); - } -} diff --git a/sources/app/Controller/TaskGanttController.php b/sources/app/Controller/TaskGanttController.php deleted file mode 100644 index 868368e..0000000 --- a/sources/app/Controller/TaskGanttController.php +++ /dev/null @@ -1,62 +0,0 @@ -getProject(); - $search = $this->helper->projectHeader->getSearchQuery($project); - $sorting = $this->request->getStringParam('sorting', 'board'); - $filter = $this->taskLexer->build($search)->withFilter(new TaskProjectFilter($project['id'])); - - if ($sorting === 'date') { - $filter->getQuery()->asc(TaskModel::TABLE.'.date_started')->asc(TaskModel::TABLE.'.date_creation'); - } else { - $filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position'); - } - - $this->response->html($this->helper->layout->app('task_gantt/show', array( - 'project' => $project, - 'title' => $project['name'], - 'description' => $this->helper->projectHeader->getDescription($project), - 'sorting' => $sorting, - 'tasks' => $filter->format(new TaskGanttFormatter($this->container)), - ))); - } - - /** - * Save new task start date and due date - */ - public function save() - { - $this->getProject(); - $values = $this->request->getJson(); - - $result = $this->taskModificationModel->update(array( - 'id' => $values['id'], - 'date_started' => strtotime($values['start']), - 'date_due' => strtotime($values['end']), - )); - - if (! $result) { - $this->response->json(array('message' => 'Unable to save task'), 400); - } else { - $this->response->json(array('message' => 'OK'), 201); - } - } -} diff --git a/sources/app/Controller/TaskGanttCreationController.php b/sources/app/Controller/TaskGanttCreationController.php deleted file mode 100644 index 07b74a4..0000000 --- a/sources/app/Controller/TaskGanttCreationController.php +++ /dev/null @@ -1,70 +0,0 @@ -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), - 'title' => $project['name'].' > '.t('New task') - ))); - } - - /** - * 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) { - $task_id = $this->taskCreationModel->create($values); - - if ($task_id !== false) { - $this->flash->success(t('Task created successfully.')); - return $this->response->redirect($this->helper->url->to('TaskGanttController', 'show', array('project_id' => $project['id']))); - } else { - $this->flash->failure(t('Unable to create your task.')); - } - } - - return $this->show($values, $errors); - } -} diff --git a/sources/app/Controller/TaskImportController.php b/sources/app/Controller/TaskImportController.php deleted file mode 100644 index aff2d39..0000000 --- a/sources/app/Controller/TaskImportController.php +++ /dev/null @@ -1,74 +0,0 @@ -getProject(); - - $this->response->html($this->helper->layout->project('task_import/show', array( - 'project' => $project, - 'values' => $values, - 'errors' => $errors, - 'max_size' => ini_get('upload_max_filesize'), - 'delimiters' => Csv::getDelimiters(), - 'enclosures' => Csv::getEnclosures(), - 'title' => t('Import tasks from CSV file'), - ), 'task_import/sidebar')); - } - - /** - * Process CSV file - */ - public function save() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - $filename = $this->request->getFilePath('file'); - - if (! file_exists($filename)) { - $this->show($values, array('file' => array(t('Unable to read your file')))); - } else { - $this->taskImport->projectId = $project['id']; - - $csv = new Csv($values['delimiter'], $values['enclosure']); - $csv->setColumnMapping($this->taskImport->getColumnMapping()); - $csv->read($filename, array($this->taskImport, 'import')); - - if ($this->taskImport->counter > 0) { - $this->flash->success(t('%d task(s) have been imported successfully.', $this->taskImport->counter)); - } else { - $this->flash->failure(t('Nothing have been imported!')); - } - - $this->response->redirect($this->helper->url->to('TaskImportController', 'show', array('project_id' => $project['id']))); - } - } - - /** - * Generate template - * - */ - public function template() - { - $this->response->withFileDownload('tasks.csv'); - $this->response->csv(array($this->taskImport->getColumnMapping())); - } -} diff --git a/sources/app/Controller/TaskInternalLinkController.php b/sources/app/Controller/TaskInternalLinkController.php deleted file mode 100644 index a140f1f..0000000 --- a/sources/app/Controller/TaskInternalLinkController.php +++ /dev/null @@ -1,167 +0,0 @@ -taskLinkModel->getById($this->request->getIntegerParam('link_id')); - - if (empty($link)) { - throw new PageNotFoundException(); - } - - return $link; - } - - /** - * Creation form - * - * @access public - * @param array $values - * @param array $errors - * @throws PageNotFoundException - * @throws \Kanboard\Core\Controller\AccessForbiddenException - */ - public function create(array $values = array(), array $errors = array()) - { - $task = $this->getTask(); - - $this->response->html($this->template->render('task_internal_link/create', array( - 'values' => $values, - 'errors' => $errors, - 'task' => $task, - 'labels' => $this->linkModel->getList(0, false), - ))); - } - - /** - * Validation and creation - * - * @access public - */ - public function save() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->taskLinkValidator->validateCreation($values); - - if ($valid) { - if ($this->taskLinkModel->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) { - $this->flash->success(t('Link added successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); - } - - $errors = array('title' => array(t('The exact same link already exists'))); - $this->flash->failure(t('Unable to create your link.')); - } - - return $this->create($values, $errors); - } - - /** - * Edit form - * - * @access public - * @param array $values - * @param array $errors - * @throws PageNotFoundException - * @throws \Kanboard\Core\Controller\AccessForbiddenException - */ - public function edit(array $values = array(), array $errors = array()) - { - $task = $this->getTask(); - $task_link = $this->getTaskLink(); - - if (empty($values)) { - $opposite_task = $this->taskFinderModel->getById($task_link['opposite_task_id']); - $values = $task_link; - $values['title'] = '#'.$opposite_task['id'].' - '.$opposite_task['title']; - } - - $this->response->html($this->template->render('task_internal_link/edit', array( - 'values' => $values, - 'errors' => $errors, - 'task_link' => $task_link, - 'task' => $task, - 'labels' => $this->linkModel->getList(0, false) - ))); - } - - /** - * Validation and update - * - * @access public - */ - public function update() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->taskLinkValidator->validateModification($values); - - if ($valid) { - if ($this->taskLinkModel->update($values['id'], $values['task_id'], $values['opposite_task_id'], $values['link_id'])) { - $this->flash->success(t('Link updated successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links'); - } - - $this->flash->failure(t('Unable to update your link.')); - } - - return $this->edit($values, $errors); - } - - /** - * Confirmation dialog before removing a link - * - * @access public - */ - public function confirm() - { - $task = $this->getTask(); - $link = $this->getTaskLink(); - - $this->response->html($this->template->render('task_internal_link/remove', array( - 'link' => $link, - 'task' => $task, - ))); - } - - /** - * Remove a link - * - * @access public - */ - public function remove() - { - $this->checkCSRFParam(); - $task = $this->getTask(); - - if ($this->taskLinkModel->remove($this->request->getIntegerParam('link_id'))) { - $this->flash->success(t('Link removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this link.')); - } - - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); - } -} diff --git a/sources/app/Controller/TaskListController.php b/sources/app/Controller/TaskListController.php deleted file mode 100644 index c6d1fa9..0000000 --- a/sources/app/Controller/TaskListController.php +++ /dev/null @@ -1,45 +0,0 @@ -getProject(); - $search = $this->helper->projectHeader->getSearchQuery($project); - - $paginator = $this->paginator - ->setUrl('TaskListController', 'show', array('project_id' => $project['id'])) - ->setMax(30) - ->setOrder(TaskModel::TABLE.'.id') - ->setDirection('DESC') - ->setQuery($this->taskLexer - ->build($search) - ->withFilter(new TaskProjectFilter($project['id'])) - ->getQuery() - ) - ->calculate(); - - $this->response->html($this->helper->layout->app('task_list/show', array( - 'project' => $project, - 'title' => $project['name'], - 'description' => $this->helper->projectHeader->getDescription($project), - 'paginator' => $paginator, - ))); - } -} diff --git a/sources/app/Controller/TaskModificationController.php b/sources/app/Controller/TaskModificationController.php deleted file mode 100644 index b064123..0000000 --- a/sources/app/Controller/TaskModificationController.php +++ /dev/null @@ -1,78 +0,0 @@ -getTask(); - $this->taskModificationModel->update(array('id' => $task['id'], 'date_started' => time())); - $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']))); - } - - /** - * Display a form to edit a task - * - * @access public - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\AccessForbiddenException - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function edit(array $values = array(), array $errors = array()) - { - $task = $this->getTask(); - $project = $this->projectModel->getById($task['project_id']); - - if (empty($values)) { - $values = $task; - $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)); - $values = $this->dateParser->format($values, array('date_due'), $this->dateParser->getUserDateFormat()); - $values = $this->dateParser->format($values, array('date_started'), $this->dateParser->getUserDateTimeFormat()); - } - - $this->response->html($this->template->render('task_modification/show', array( - 'project' => $project, - 'values' => $values, - 'errors' => $errors, - 'task' => $task, - 'tags' => $this->taskTagModel->getList($task['id']), - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($task['project_id']), - 'categories_list' => $this->categoryModel->getList($task['project_id']), - ))); - } - - /** - * Validate and update a task - * - * @access public - */ - public function update() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->taskValidator->validateModification($values); - - if ($valid && $this->taskModificationModel->update($values)) { - $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 { - $this->flash->failure(t('Unable to update your task.')); - $this->edit($values, $errors); - } - } -} diff --git a/sources/app/Controller/TaskPopoverController.php b/sources/app/Controller/TaskPopoverController.php deleted file mode 100644 index 4e3c11a..0000000 --- a/sources/app/Controller/TaskPopoverController.php +++ /dev/null @@ -1,26 +0,0 @@ -getTask(); - - $this->response->html($this->template->render('task_file/screenshot', array( - 'task' => $task, - ))); - } -} diff --git a/sources/app/Controller/TaskRecurrenceController.php b/sources/app/Controller/TaskRecurrenceController.php deleted file mode 100644 index c6fdfa3..0000000 --- a/sources/app/Controller/TaskRecurrenceController.php +++ /dev/null @@ -1,65 +0,0 @@ -getTask(); - - if (empty($values)) { - $values = $task; - } - - $this->response->html($this->template->render('task_recurrence/edit', array( - 'values' => $values, - 'errors' => $errors, - 'task' => $task, - 'recurrence_status_list' => $this->taskRecurrenceModel->getRecurrenceStatusList(), - 'recurrence_trigger_list' => $this->taskRecurrenceModel->getRecurrenceTriggerList(), - 'recurrence_timeframe_list' => $this->taskRecurrenceModel->getRecurrenceTimeframeList(), - 'recurrence_basedate_list' => $this->taskRecurrenceModel->getRecurrenceBasedateList(), - ))); - } - - /** - * Update recurrence form - * - * @access public - */ - public function update() - { - $task = $this->getTask(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->taskValidator->validateEditRecurrence($values); - - if ($valid) { - if ($this->taskModificationModel->update($values)) { - $this->flash->success(t('Task updated successfully.')); - } else { - $this->flash->failure(t('Unable to update your task.')); - } - - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); - } - - return $this->edit($values, $errors); - } -} diff --git a/sources/app/Controller/TaskStatusController.php b/sources/app/Controller/TaskStatusController.php deleted file mode 100644 index 82b4f9c..0000000 --- a/sources/app/Controller/TaskStatusController.php +++ /dev/null @@ -1,62 +0,0 @@ -changeStatus('close', 'task_status/close', t('Task closed successfully.'), t('Unable to close this task.')); - } - - /** - * Open a task - * - * @access public - */ - public function open() - { - $this->changeStatus('open', 'task_status/open', t('Task opened successfully.'), t('Unable to open this task.')); - } - - /** - * Common method to change status - * - * @access private - * @param string $method - * @param string $template - * @param string $success_message - * @param string $failure_message - */ - private function changeStatus($method, $template, $success_message, $failure_message) - { - $task = $this->getTask(); - - if ($this->request->getStringParam('confirmation') === 'yes') { - $this->checkCSRFParam(); - - if ($this->taskStatusModel->$method($task['id'])) { - $this->flash->success($success_message); - } else { - $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); - } - - return $this->response->html($this->template->render($template, array( - 'task' => $task, - ))); - } -} diff --git a/sources/app/Controller/TaskSuppressionController.php b/sources/app/Controller/TaskSuppressionController.php deleted file mode 100644 index 600107c..0000000 --- a/sources/app/Controller/TaskSuppressionController.php +++ /dev/null @@ -1,53 +0,0 @@ -getTask(); - - if (! $this->helper->user->canRemoveTask($task)) { - throw new AccessForbiddenException(); - } - - $this->response->html($this->template->render('task_suppression/remove', array( - 'task' => $task, - 'redirect' => $this->request->getStringParam('redirect'), - ))); - } - - /** - * Remove a task - */ - public function remove() - { - $task = $this->getTask(); - $this->checkCSRFParam(); - - if (! $this->helper->user->canRemoveTask($task)) { - throw new AccessForbiddenException(); - } - - if ($this->taskModel->remove($task['id'])) { - $this->flash->success(t('Task removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this task.')); - } - - $redirect = $this->request->getStringParam('redirect') === ''; - $this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $task['project_id'])), $redirect); - } -} diff --git a/sources/app/Controller/TaskViewController.php b/sources/app/Controller/TaskViewController.php deleted file mode 100644 index f40f8be..0000000 --- a/sources/app/Controller/TaskViewController.php +++ /dev/null @@ -1,147 +0,0 @@ -projectModel->getByToken($this->request->getStringParam('token')); - - // Token verification - if (empty($project)) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - $task = $this->taskFinderModel->getDetails($this->request->getIntegerParam('task_id')); - - if (empty($task)) { - throw PageNotFoundException::getInstance()->withoutLayout(); - } - - if ($task['project_id'] != $project['id']) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - $this->response->html($this->helper->layout->app('task/public', array( - 'project' => $project, - 'comments' => $this->commentModel->getAll($task['id']), - 'subtasks' => $this->subtaskModel->getAll($task['id']), - 'links' => $this->taskLinkModel->getAllGroupedByLabel($task['id']), - 'task' => $task, - 'columns_list' => $this->columnModel->getList($task['project_id']), - 'colors_list' => $this->colorModel->getList(), - 'tags' => $this->taskTagModel->getList($task['id']), - 'title' => $task['title'], - 'no_layout' => true, - 'auto_refresh' => true, - 'not_editable' => true, - ))); - } - - /** - * Show a task - * - * @access public - */ - public function show() - { - $task = $this->getTask(); - $subtasks = $this->subtaskModel->getAll($task['id']); - - $values = array( - 'id' => $task['id'], - 'date_started' => $task['date_started'], - 'time_estimated' => $task['time_estimated'] ?: '', - 'time_spent' => $task['time_spent'] ?: '', - ); - - $values = $this->dateParser->format($values, array('date_started'), $this->dateParser->getUserDateTimeFormat()); - - $this->response->html($this->helper->layout->task('task/show', array( - 'task' => $task, - 'project' => $this->projectModel->getById($task['project_id']), - 'values' => $values, - 'files' => $this->taskFileModel->getAllDocuments($task['id']), - 'images' => $this->taskFileModel->getAllImages($task['id']), - 'comments' => $this->commentModel->getAll($task['id'], $this->userSession->getCommentSorting()), - 'subtasks' => $subtasks, - 'internal_links' => $this->taskLinkModel->getAllGroupedByLabel($task['id']), - 'external_links' => $this->taskExternalLinkModel->getAll($task['id']), - 'link_label_list' => $this->linkModel->getList(0, false), - 'tags' => $this->taskTagModel->getList($task['id']), - ))); - } - - /** - * Display task analytics - * - * @access public - */ - public function analytics() - { - $task = $this->getTask(); - - $this->response->html($this->helper->layout->task('task/analytics', array( - 'task' => $task, - 'project' => $this->projectModel->getById($task['project_id']), - 'lead_time' => $this->taskAnalyticModel->getLeadTime($task), - 'cycle_time' => $this->taskAnalyticModel->getCycleTime($task), - 'time_spent_columns' => $this->taskAnalyticModel->getTimeSpentByColumn($task), - ))); - } - - /** - * Display the time tracking details - * - * @access public - */ - public function timetracking() - { - $task = $this->getTask(); - - $subtask_paginator = $this->paginator - ->setUrl('TaskViewController', 'timetracking', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'pagination' => 'subtasks')) - ->setMax(15) - ->setOrder('start') - ->setDirection('DESC') - ->setQuery($this->subtaskTimeTrackingModel->getTaskQuery($task['id'])) - ->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks'); - - $this->response->html($this->helper->layout->task('task/time_tracking_details', array( - 'task' => $task, - 'project' => $this->projectModel->getById($task['project_id']), - 'subtask_paginator' => $subtask_paginator, - ))); - } - - /** - * Display the task transitions - * - * @access public - */ - public function transitions() - { - $task = $this->getTask(); - - $this->response->html($this->helper->layout->task('task/transitions', array( - 'task' => $task, - 'project' => $this->projectModel->getById($task['project_id']), - 'transitions' => $this->transitionModel->getAllByTask($task['id']), - ))); - } -} diff --git a/sources/app/Controller/TwoFactorController.php b/sources/app/Controller/TwoFactorController.php deleted file mode 100644 index d02c895..0000000 --- a/sources/app/Controller/TwoFactorController.php +++ /dev/null @@ -1,202 +0,0 @@ -userSession->getId()) { - throw new AccessForbiddenException(); - } - } - - /** - * Show form to disable/enable 2FA - * - * @access public - */ - public function index() - { - $user = $this->getUser(); - $this->checkCurrentUser($user); - unset($this->sessionStorage->twoFactorSecret); - - $this->response->html($this->helper->layout->user('twofactor/index', array( - 'user' => $user, - 'provider' => $this->authenticationManager->getPostAuthenticationProvider()->getName(), - ))); - } - - /** - * Show page with secret and test form - * - * @access public - */ - public function show() - { - $user = $this->getUser(); - $this->checkCurrentUser($user); - - $label = $user['email'] ?: $user['username']; - $provider = $this->authenticationManager->getPostAuthenticationProvider(); - - if (! isset($this->sessionStorage->twoFactorSecret)) { - $provider->generateSecret(); - $provider->beforeCode(); - $this->sessionStorage->twoFactorSecret = $provider->getSecret(); - } else { - $provider->setSecret($this->sessionStorage->twoFactorSecret); - } - - $this->response->html($this->helper->layout->user('twofactor/show', array( - 'user' => $user, - 'secret' => $this->sessionStorage->twoFactorSecret, - 'qrcode_url' => $provider->getQrCodeUrl($label), - 'key_url' => $provider->getKeyUrl($label), - ))); - } - - /** - * Test code and save secret - * - * @access public - */ - public function test() - { - $user = $this->getUser(); - $this->checkCurrentUser($user); - - $values = $this->request->getValues(); - - $provider = $this->authenticationManager->getPostAuthenticationProvider(); - $provider->setCode(empty($values['code']) ? '' : $values['code']); - $provider->setSecret($this->sessionStorage->twoFactorSecret); - - if ($provider->authenticate()) { - $this->flash->success(t('The two factor authentication code is valid.')); - - $this->userModel->update(array( - 'id' => $user['id'], - 'twofactor_activated' => 1, - 'twofactor_secret' => $this->authenticationManager->getPostAuthenticationProvider()->getSecret(), - )); - - unset($this->sessionStorage->twoFactorSecret); - $this->userSession->disablePostAuthentication(); - - $this->response->redirect($this->helper->url->to('TwoFactorController', 'index', array('user_id' => $user['id']))); - } else { - $this->flash->failure(t('The two factor authentication code is not valid.')); - $this->response->redirect($this->helper->url->to('TwoFactorController', 'show', array('user_id' => $user['id']))); - } - } - - /** - * Disable 2FA for the current user - * - * @access public - */ - public function deactivate() - { - $user = $this->getUser(); - $this->checkCurrentUser($user); - - $this->userModel->update(array( - 'id' => $user['id'], - 'twofactor_activated' => 0, - 'twofactor_secret' => '', - )); - - // Allow the user to test or disable the feature - $this->userSession->disablePostAuthentication(); - - $this->flash->success(t('User updated successfully.')); - $this->response->redirect($this->helper->url->to('TwoFactorController', 'index', array('user_id' => $user['id']))); - } - - /** - * Check 2FA - * - * @access public - */ - public function check() - { - $user = $this->getUser(); - $this->checkCurrentUser($user); - - $values = $this->request->getValues(); - - $provider = $this->authenticationManager->getPostAuthenticationProvider(); - $provider->setCode(empty($values['code']) ? '' : $values['code']); - $provider->setSecret($user['twofactor_secret']); - - if ($provider->authenticate()) { - $this->userSession->validatePostAuthentication(); - $this->flash->success(t('The two factor authentication code is valid.')); - $this->response->redirect($this->helper->url->to('DashboardController', 'show')); - } else { - $this->flash->failure(t('The two factor authentication code is not valid.')); - $this->response->redirect($this->helper->url->to('TwoFactorController', 'code')); - } - } - - /** - * Ask the 2FA code - * - * @access public - */ - public function code() - { - if (! isset($this->sessionStorage->twoFactorBeforeCodeCalled)) { - $provider = $this->authenticationManager->getPostAuthenticationProvider(); - $provider->beforeCode(); - $this->sessionStorage->twoFactorBeforeCodeCalled = true; - } - - $this->response->html($this->helper->layout->app('twofactor/check', array( - 'title' => t('Check two factor authentication code'), - ))); - } - - /** - * Disable 2FA for a user - * - * @access public - */ - public function disable() - { - $user = $this->getUser(); - - if ($this->request->getStringParam('disable') === 'yes') { - $this->checkCSRFParam(); - - $this->userModel->update(array( - 'id' => $user['id'], - 'twofactor_activated' => 0, - 'twofactor_secret' => '', - )); - - return $this->response->redirect($this->helper->url->to('UserViewController', 'show', array('user_id' => $user['id']))); - } - - return $this->response->html($this->helper->layout->user('twofactor/disable', array( - 'user' => $user, - ))); - } -} diff --git a/sources/app/Controller/UserAjaxController.php b/sources/app/Controller/UserAjaxController.php deleted file mode 100644 index ed18047..0000000 --- a/sources/app/Controller/UserAjaxController.php +++ /dev/null @@ -1,52 +0,0 @@ -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))); - } - - /** - * User mention auto-completion (Ajax) - * - * @access public - */ - public function mention() - { - $project_id = $this->request->getStringParam('project_id'); - $query = $this->request->getStringParam('q'); - $users = $this->projectPermissionModel->findUsernames($project_id, $query); - $this->response->json($users); - } - - /** - * Check if the user is connected - * - * @access public - */ - public function status() - { - $this->response->text('OK'); - } -} diff --git a/sources/app/Controller/UserCreationController.php b/sources/app/Controller/UserCreationController.php deleted file mode 100644 index 9c873f8..0000000 --- a/sources/app/Controller/UserCreationController.php +++ /dev/null @@ -1,83 +0,0 @@ -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( - 'timezones' => $this->timezoneModel->getTimezones(true), - 'languages' => $this->languageModel->getLanguages(true), - 'roles' => $this->role->getApplicationRoles(), - 'projects' => $this->projectModel->getList(), - 'errors' => $errors, - 'values' => $values + array('role' => Role::APP_USER), - ))); - } - - /** - * Validate and save a new user - * - * @access public - */ - public function save() - { - $values = $this->request->getValues(); - list($valid, $errors) = $this->userValidator->validateCreation($values); - - if ($valid) { - $this->createUser($values); - } else { - $this->show($values, $errors); - } - } - - /** - * Create user - * - * @param array $values - */ - private function createUser(array $values) - { - $project_id = empty($values['project_id']) ? 0 : $values['project_id']; - unset($values['project_id']); - - $user_id = $this->userModel->create($values); - - if ($user_id !== false) { - if ($project_id !== 0) { - $this->projectUserRoleModel->addUser($project_id, $user_id, Role::PROJECT_MEMBER); - } - - if (! empty($values['notifications_enabled'])) { - $this->userNotificationTypeModel->saveSelectedTypes($user_id, array(MailNotification::TYPE)); - } - - $this->flash->success(t('User created successfully.')); - $this->response->redirect($this->helper->url->to('UserViewController', 'show', array('user_id' => $user_id))); - } else { - $this->flash->failure(t('Unable to create your user.')); - $this->response->redirect($this->helper->url->to('UserListController', 'show')); - } - } -} diff --git a/sources/app/Controller/UserCredentialController.php b/sources/app/Controller/UserCredentialController.php deleted file mode 100644 index 4021dc3..0000000 --- a/sources/app/Controller/UserCredentialController.php +++ /dev/null @@ -1,109 +0,0 @@ -getUser(); - - return $this->response->html($this->helper->layout->user('user_credential/password', array( - 'values' => $values + array('id' => $user['id']), - 'errors' => $errors, - 'user' => $user, - ))); - } - - /** - * Save new password - * - * @throws \Kanboard\Core\Controller\AccessForbiddenException - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function savePassword() - { - $user = $this->getUser(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->userValidator->validatePasswordModification($values); - - if ($valid) { - if ($this->userModel->update($values)) { - $this->flash->success(t('Password modified successfully.')); - $this->userLockingModel->resetFailedLogin($user['username']); - } else { - $this->flash->failure(t('Unable to change the password.')); - } - - return $this->response->redirect($this->helper->url->to('UserViewController', 'show', array('user_id' => $user['id']))); - } - - return $this->changePassword($values, $errors); - } - - /** - * Display a form to edit authentication - * - * @access public - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\AccessForbiddenException - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function changeAuthentication(array $values = array(), array $errors = array()) - { - $user = $this->getUser(); - - if (empty($values)) { - $values = $user; - unset($values['password']); - } - - return $this->response->html($this->helper->layout->user('user_credential/authentication', array( - 'values' => $values, - 'errors' => $errors, - 'user' => $user, - ))); - } - - /** - * Save authentication - * - * @throws \Kanboard\Core\Controller\AccessForbiddenException - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function saveAuthentication() - { - $user = $this->getUser(); - $values = $this->request->getValues() + array('disable_login_form' => 0, 'is_ldap_user' => 0); - list($valid, $errors) = $this->userValidator->validateModification($values); - - if ($valid) { - if ($this->userModel->update($values)) { - $this->flash->success(t('User updated successfully.')); - } else { - $this->flash->failure(t('Unable to update your user.')); - } - - return $this->response->redirect($this->helper->url->to('UserCredentialController', 'changeAuthentication', array('user_id' => $user['id']))); - } - - return $this->changeAuthentication($values, $errors); - } -} diff --git a/sources/app/Controller/UserImportController.php b/sources/app/Controller/UserImportController.php deleted file mode 100644 index fec9a31..0000000 --- a/sources/app/Controller/UserImportController.php +++ /dev/null @@ -1,77 +0,0 @@ -response->html($this->template->render('user_import/show', array( - 'values' => $values, - 'errors' => $errors, - 'max_size' => ini_get('upload_max_filesize'), - 'delimiters' => Csv::getDelimiters(), - 'enclosures' => Csv::getEnclosures(), - ))); - } - - /** - * Submit form - */ - public function save() - { - $values = $this->request->getValues(); - $filename = $this->request->getFilePath('file'); - - if (! file_exists($filename)) { - $this->flash->failure(t('Unable to read your file')); - } else { - $this->importFile($values, $filename); - } - - $this->response->redirect($this->helper->url->to('UserListController', 'show')); - } - - /** - * Generate template - * - */ - public function template() - { - $this->response->withFileDownload('users.csv'); - $this->response->csv(array($this->userImport->getColumnMapping())); - } - - /** - * Process file - * - * @param array $values - * @param $filename - */ - private function importFile(array $values, $filename) - { - $csv = new Csv($values['delimiter'], $values['enclosure']); - $csv->setColumnMapping($this->userImport->getColumnMapping()); - $csv->read($filename, array($this->userImport, 'import')); - - if ($this->userImport->counter > 0) { - $this->flash->success(t('%d user(s) have been imported successfully.', $this->userImport->counter)); - } else { - $this->flash->failure(t('Nothing have been imported!')); - } - } -} diff --git a/sources/app/Controller/UserListController.php b/sources/app/Controller/UserListController.php deleted file mode 100644 index 31fcdd4..0000000 --- a/sources/app/Controller/UserListController.php +++ /dev/null @@ -1,32 +0,0 @@ -paginator - ->setUrl('UserListController', 'show') - ->setMax(30) - ->setOrder('username') - ->setQuery($this->userModel->getQuery()) - ->calculate(); - - $this->response->html($this->helper->layout->app('user_list/show', array( - 'title' => t('Users').' ('.$paginator->getTotal().')', - 'paginator' => $paginator, - ))); - } -} diff --git a/sources/app/Controller/UserModificationController.php b/sources/app/Controller/UserModificationController.php deleted file mode 100644 index d339fd9..0000000 --- a/sources/app/Controller/UserModificationController.php +++ /dev/null @@ -1,69 +0,0 @@ -getUser(); - - if (empty($values)) { - $values = $user; - unset($values['password']); - } - - return $this->response->html($this->helper->layout->user('user_modification/show', array( - 'values' => $values, - 'errors' => $errors, - 'user' => $user, - 'timezones' => $this->timezoneModel->getTimezones(true), - 'languages' => $this->languageModel->getLanguages(true), - 'roles' => $this->role->getApplicationRoles(), - ))); - } - - /** - * Save user information - */ - public function save() - { - $user = $this->getUser(); - $values = $this->request->getValues(); - - if (! $this->userSession->isAdmin()) { - if (isset($values['role'])) { - unset($values['role']); - } - } - - list($valid, $errors) = $this->userValidator->validateModification($values); - - if ($valid) { - if ($this->userModel->update($values)) { - $this->flash->success(t('User updated successfully.')); - } else { - $this->flash->failure(t('Unable to update your user.')); - } - - return $this->response->redirect($this->helper->url->to('UserViewController', 'show', array('user_id' => $user['id']))); - } - - return $this->show($values, $errors); - } -} diff --git a/sources/app/Controller/UserStatusController.php b/sources/app/Controller/UserStatusController.php deleted file mode 100644 index 070fb6f..0000000 --- a/sources/app/Controller/UserStatusController.php +++ /dev/null @@ -1,111 +0,0 @@ -getUser(); - - $this->response->html($this->helper->layout->user('user_status/remove', array( - 'user' => $user, - ))); - } - - /** - * Remove a user - * - * @access public - */ - public function remove() - { - $user = $this->getUser(); - $this->checkCSRFParam(); - - if ($this->userModel->remove($user['id'])) { - $this->flash->success(t('User removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this user.')); - } - - $this->response->redirect($this->helper->url->to('UserListController', 'show')); - } - - /** - * Confirm enable a user - * - * @access public - */ - public function confirmEnable() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->user('user_status/enable', array( - 'user' => $user, - ))); - } - - /** - * Enable a user - * - * @access public - */ - public function enable() - { - $user = $this->getUser(); - $this->checkCSRFParam(); - - if ($this->userModel->enable($user['id'])) { - $this->flash->success(t('User activated successfully.')); - } else { - $this->flash->failure(t('Unable to enable this user.')); - } - - $this->response->redirect($this->helper->url->to('UserListController', 'show')); - } - - /** - * Confirm disable a user - * - * @access public - */ - public function confirmDisable() - { - $user = $this->getUser(); - - $this->response->html($this->helper->layout->user('user_status/disable', array( - 'user' => $user, - ))); - } - - /** - * Disable a user - * - * @access public - */ - public function disable() - { - $user = $this->getUser(); - $this->checkCSRFParam(); - - if ($this->userModel->disable($user['id'])) { - $this->flash->success(t('User disabled successfully.')); - } else { - $this->flash->failure(t('Unable to disable this user.')); - } - - $this->response->redirect($this->helper->url->to('UserListController', 'show')); - } -} diff --git a/sources/app/Controller/UserViewController.php b/sources/app/Controller/UserViewController.php deleted file mode 100644 index a73c5c5..0000000 --- a/sources/app/Controller/UserViewController.php +++ /dev/null @@ -1,217 +0,0 @@ -userModel->getById($this->request->getIntegerParam('user_id')); - - if (empty($user)) { - throw new PageNotFoundException(); - } - - $this->response->html($this->helper->layout->app('user_view/profile', array( - 'title' => $user['name'] ?: $user['username'], - 'user' => $user, - ))); - } - - /** - * Display user information - * - * @access public - */ - public function show() - { - $user = $this->getUser(); - $this->response->html($this->helper->layout->user('user_view/show', array( - 'user' => $user, - 'timezones' => $this->timezoneModel->getTimezones(true), - 'languages' => $this->languageModel->getLanguages(true), - ))); - } - - /** - * Display timesheet - * - * @access public - */ - public function timesheet() - { - $user = $this->getUser(); - - $subtask_paginator = $this->paginator - ->setUrl('UserViewController', 'timesheet', array('user_id' => $user['id'], 'pagination' => 'subtasks')) - ->setMax(20) - ->setOrder('start') - ->setDirection('DESC') - ->setQuery($this->subtaskTimeTrackingModel->getUserQuery($user['id'])) - ->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks'); - - $this->response->html($this->helper->layout->user('user_view/timesheet', array( - 'subtask_paginator' => $subtask_paginator, - 'user' => $user, - ))); - } - - /** - * Display last password reset - * - * @access public - */ - public function passwordReset() - { - $user = $this->getUser(); - $this->response->html($this->helper->layout->user('user_view/password_reset', array( - 'tokens' => $this->passwordResetModel->getAll($user['id']), - 'user' => $user, - ))); - } - - /** - * Display last connections - * - * @access public - */ - public function lastLogin() - { - $user = $this->getUser(); - $this->response->html($this->helper->layout->user('user_view/last', array( - 'last_logins' => $this->lastLoginModel->getAll($user['id']), - 'user' => $user, - ))); - } - - /** - * Display user sessions - * - * @access public - */ - public function sessions() - { - $user = $this->getUser(); - $this->response->html($this->helper->layout->user('user_view/sessions', array( - 'sessions' => $this->rememberMeSessionModel->getAll($user['id']), - 'user' => $user, - ))); - } - - /** - * Remove a "RememberMe" token - * - * @access public - */ - public function removeSession() - { - $this->checkCSRFParam(); - $user = $this->getUser(); - $this->rememberMeSessionModel->remove($this->request->getIntegerParam('id')); - $this->response->redirect($this->helper->url->to('UserViewController', 'sessions', array('user_id' => $user['id']))); - } - - /** - * Display user notifications - * - * @access public - */ - public function notifications() - { - $user = $this->getUser(); - - if ($this->request->isPost()) { - $values = $this->request->getValues(); - $this->userNotificationModel->saveSettings($user['id'], $values); - $this->flash->success(t('User updated successfully.')); - return $this->response->redirect($this->helper->url->to('UserViewController', 'notifications', array('user_id' => $user['id']))); - } - - return $this->response->html($this->helper->layout->user('user_view/notifications', array( - 'projects' => $this->projectUserRoleModel->getProjectsByUser($user['id'], array(ProjectModel::ACTIVE)), - 'notifications' => $this->userNotificationModel->readSettings($user['id']), - 'types' => $this->userNotificationTypeModel->getTypes(), - 'filters' => $this->userNotificationFilterModel->getFilters(), - 'user' => $user, - ))); - } - - /** - * Display user integrations - * - * @access public - */ - public function integrations() - { - $user = $this->getUser(); - - if ($this->request->isPost()) { - $values = $this->request->getValues(); - $this->userMetadataModel->save($user['id'], $values); - $this->flash->success(t('User updated successfully.')); - $this->response->redirect($this->helper->url->to('UserViewController', 'integrations', array('user_id' => $user['id']))); - } - - $this->response->html($this->helper->layout->user('user_view/integrations', array( - 'user' => $user, - 'values' => $this->userMetadataModel->getAll($user['id']), - ))); - } - - /** - * Display external accounts - * - * @access public - */ - public function external() - { - $user = $this->getUser(); - $this->response->html($this->helper->layout->user('user_view/external', array( - 'last_logins' => $this->lastLoginModel->getAll($user['id']), - 'user' => $user, - ))); - } - - /** - * Public access management - * - * @access public - */ - public function share() - { - $user = $this->getUser(); - $switch = $this->request->getStringParam('switch'); - - if ($switch === 'enable' || $switch === 'disable') { - $this->checkCSRFParam(); - - if ($this->userModel->{$switch . 'PublicAccess'}($user['id'])) { - $this->flash->success(t('User updated successfully.')); - } else { - $this->flash->failure(t('Unable to update this user.')); - } - - return $this->response->redirect($this->helper->url->to('UserViewController', 'share', array('user_id' => $user['id']))); - } - - return $this->response->html($this->helper->layout->user('user_view/share', array( - 'user' => $user, - 'title' => t('Public access'), - ))); - } -} diff --git a/sources/app/Controller/WebNotificationController.php b/sources/app/Controller/WebNotificationController.php deleted file mode 100644 index 30e317f..0000000 --- a/sources/app/Controller/WebNotificationController.php +++ /dev/null @@ -1,79 +0,0 @@ -getUserId(); - - $this->userUnreadNotificationModel->markAllAsRead($user_id); - $this->response->redirect($this->helper->url->to('DashboardController', 'notifications', array('user_id' => $user_id))); - } - - /** - * Mark a notification as read - * - * @access public - */ - public function remove() - { - $user_id = $this->getUserId(); - $notification_id = $this->request->getIntegerParam('notification_id'); - - $this->userUnreadNotificationModel->markAsRead($user_id, $notification_id); - $this->response->redirect($this->helper->url->to('DashboardController', 'notifications', array('user_id' => $user_id))); - } - - /** - * Redirect to the task and mark notification as read - */ - public function redirect() - { - $user_id = $this->getUserId(); - $notification_id = $this->request->getIntegerParam('notification_id'); - - $notification = $this->userUnreadNotificationModel->getById($notification_id); - $this->userUnreadNotificationModel->markAsRead($user_id, $notification_id); - - if (empty($notification)) { - $this->response->redirect($this->helper->url->to('DashboardController', 'notifications', array('user_id' => $user_id))); - } elseif ($this->helper->text->contains($notification['event_name'], 'comment')) { - $this->response->redirect($this->helper->url->to( - 'TaskViewController', - 'show', - array('task_id' => $this->notificationModel->getTaskIdFromEvent($notification['event_name'], $notification['event_data'])), - 'comment-'.$notification['event_data']['comment']['id'] - )); - } else { - $this->response->redirect($this->helper->url->to( - 'TaskViewController', - 'show', - array('task_id' => $this->notificationModel->getTaskIdFromEvent($notification['event_name'], $notification['event_data'])) - )); - } - } - - private function getUserId() - { - $user_id = $this->request->getIntegerParam('user_id'); - - if (! $this->userSession->isAdmin() && $user_id != $this->userSession->getId()) { - $user_id = $this->userSession->getId(); - } - - return $user_id; - } -} diff --git a/sources/app/Core/Action/ActionManager.php b/sources/app/Core/Action/ActionManager.php deleted file mode 100644 index 1dfd820..0000000 --- a/sources/app/Core/Action/ActionManager.php +++ /dev/null @@ -1,142 +0,0 @@ -actions[$action->getName()] = $action; - return $this; - } - - /** - * Get automatic action instance - * - * @access public - * @param string $name Absolute class name with namespace - * @return ActionBase - */ - public function getAction($name) - { - if (isset($this->actions[$name])) { - return $this->actions[$name]; - } - - throw new RuntimeException('Automatic Action Not Found: '.$name); - } - - /** - * Get available automatic actions - * - * @access public - * @return array - */ - public function getAvailableActions() - { - $actions = array(); - - foreach ($this->actions as $action) { - if (count($action->getEvents()) > 0) { - $actions[$action->getName()] = $action->getDescription(); - } - } - - asort($actions); - - return $actions; - } - - /** - * Get all available action parameters - * - * @access public - * @param array $actions - * @return array - */ - public function getAvailableParameters(array $actions) - { - $params = array(); - - foreach ($actions as $action) { - $currentAction = $this->getAction($action['action_name']); - $params[$currentAction->getName()] = $currentAction->getActionRequiredParameters(); - } - - return $params; - } - - /** - * Get list of compatible events for a given action - * - * @access public - * @param string $name - * @return array - */ - public function getCompatibleEvents($name) - { - $events = array(); - $actionEvents = $this->getAction($name)->getEvents(); - - foreach ($this->eventManager->getAll() as $event => $description) { - if (in_array($event, $actionEvents)) { - $events[$event] = $description; - } - } - - return $events; - } - - /** - * Bind automatic actions to events - * - * @access public - * @return ActionManager - */ - public function attachEvents() - { - if ($this->userSession->isLogged()) { - $actions = $this->actionModel->getAllByUser($this->userSession->getId()); - } else { - $actions = $this->actionModel->getAll(); - } - - foreach ($actions as $action) { - $listener = clone $this->getAction($action['action_name']); - $listener->setProjectId($action['project_id']); - - foreach ($action['params'] as $param_name => $param_value) { - $listener->setParam($param_name, $param_value); - } - - $this->dispatcher->addListener($action['event_name'], array($listener, 'execute')); - } - - return $this; - } -} diff --git a/sources/app/Core/Base.php b/sources/app/Core/Base.php deleted file mode 100644 index 8103ec1..0000000 --- a/sources/app/Core/Base.php +++ /dev/null @@ -1,205 +0,0 @@ -container = $container; - } - - /** - * Load automatically models - * - * @access public - * @param string $name Model name - * @return mixed - */ - public function __get($name) - { - return $this->container[$name]; - } - - /** - * Get object instance - * - * @static - * @access public - * @param Container $container - * @return static - */ - public static function getInstance(Container $container) - { - $self = new static($container); - return $self; - } -} diff --git a/sources/app/Core/Cache/Base.php b/sources/app/Core/Cache/Base.php deleted file mode 100644 index d62b850..0000000 --- a/sources/app/Core/Cache/Base.php +++ /dev/null @@ -1,38 +0,0 @@ -get($key); - - if ($result === null) { - $result = call_user_func_array(array($class, $method), array_splice($args, 1)); - $this->set($key, $result); - } - - return $result; - } -} diff --git a/sources/app/Core/Cache/CacheInterface.php b/sources/app/Core/Cache/CacheInterface.php deleted file mode 100644 index d9e9747..0000000 --- a/sources/app/Core/Cache/CacheInterface.php +++ /dev/null @@ -1,45 +0,0 @@ -storage[$key] = $value; - } - - /** - * Fetch value from cache - * - * @access public - * @param string $key - * @return mixed Null when not found, cached value otherwise - */ - public function get($key) - { - return isset($this->storage[$key]) ? $this->storage[$key] : null; - } - - /** - * Clear all cache - * - * @access public - */ - public function flush() - { - $this->storage = array(); - } - - /** - * Remove cached value - * - * @access public - * @param string $key - */ - public function remove($key) - { - unset($this->storage[$key]); - } -} diff --git a/sources/app/Core/Controller/AccessForbiddenException.php b/sources/app/Core/Controller/AccessForbiddenException.php deleted file mode 100644 index b5dccb7..0000000 --- a/sources/app/Core/Controller/AccessForbiddenException.php +++ /dev/null @@ -1,14 +0,0 @@ -withoutLayout = true; - return $this; - } - - /** - * Return true if no layout - * - * @access public - * @return boolean - */ - public function hasLayout() - { - return $this->withoutLayout; - } -} diff --git a/sources/app/Core/Controller/BaseMiddleware.php b/sources/app/Core/Controller/BaseMiddleware.php deleted file mode 100644 index e94ad95..0000000 --- a/sources/app/Core/Controller/BaseMiddleware.php +++ /dev/null @@ -1,58 +0,0 @@ -nextMiddleware = $nextMiddleware; - return $this; - } - - /** - * @return BaseMiddleware - */ - public function getNextMiddleware() - { - return $this->nextMiddleware; - } - - /** - * Move to next middleware - */ - public function next() - { - if ($this->nextMiddleware !== null) { - if (DEBUG) { - $this->logger->debug(__METHOD__.' => ' . get_class($this->nextMiddleware)); - } - - $this->nextMiddleware->execute(); - } - } -} diff --git a/sources/app/Core/Controller/PageNotFoundException.php b/sources/app/Core/Controller/PageNotFoundException.php deleted file mode 100644 index e96a205..0000000 --- a/sources/app/Core/Controller/PageNotFoundException.php +++ /dev/null @@ -1,14 +0,0 @@ -executeMiddleware(); - - if (!$this->response->isResponseAlreadySent()) { - $this->executeController(); - } - } catch (PageNotFoundException $e) { - $controllerObject = new AppController($this->container); - $controllerObject->notFound($e->hasLayout()); - } catch (AccessForbiddenException $e) { - $controllerObject = new AppController($this->container); - $controllerObject->accessForbidden($e->hasLayout()); - } - } - - /** - * Execute all middleware - */ - protected function executeMiddleware() - { - if (DEBUG) { - $this->logger->debug(__METHOD__); - } - - $bootstrapMiddleware = new BootstrapMiddleware($this->container); - $authenticationMiddleware = new AuthenticationMiddleware($this->container); - $postAuthenticationMiddleware = new PostAuthenticationMiddleware($this->container); - $appAuthorizationMiddleware = new ApplicationAuthorizationMiddleware($this->container); - $projectAuthorizationMiddleware = new ProjectAuthorizationMiddleware($this->container); - - $bootstrapMiddleware->setNextMiddleware($authenticationMiddleware); - $authenticationMiddleware->setNextMiddleware($postAuthenticationMiddleware); - $postAuthenticationMiddleware->setNextMiddleware($appAuthorizationMiddleware); - $appAuthorizationMiddleware->setNextMiddleware($projectAuthorizationMiddleware); - - $bootstrapMiddleware->execute(); - } - - /** - * Execute the controller - */ - protected function executeController() - { - $className = $this->getControllerClassName(); - - if (DEBUG) { - $this->logger->debug(__METHOD__.' => '.$className.'::'.$this->router->getAction()); - } - - $controllerObject = new $className($this->container); - $controllerObject->{$this->router->getAction()}(); - } - - /** - * Get controller class name - * - * @access protected - * @return string - * @throws RuntimeException - */ - protected function getControllerClassName() - { - if ($this->router->getPlugin() !== '') { - $className = '\Kanboard\Plugin\\'.$this->router->getPlugin().'\Controller\\'.$this->router->getController(); - } else { - $className = '\Kanboard\Controller\\'.$this->router->getController(); - } - - if (! class_exists($className)) { - throw new RuntimeException('Controller not found'); - } - - if (! method_exists($className, $this->router->getAction())) { - throw new RuntimeException('Action not implemented'); - } - - return $className; - } -} diff --git a/sources/app/Core/Csv.php b/sources/app/Core/Csv.php deleted file mode 100644 index 8801016..0000000 --- a/sources/app/Core/Csv.php +++ /dev/null @@ -1,216 +0,0 @@ -delimiter = $delimiter; - $this->enclosure = $enclosure; - } - - /** - * Get list of delimiters - * - * @static - * @access public - * @return array - */ - public static function getDelimiters() - { - return array( - ',' => t('Comma'), - ';' => t('Semi-colon'), - '\t' => t('Tab'), - '|' => t('Vertical bar'), - ); - } - - /** - * Get list of enclosures - * - * @static - * @access public - * @return array - */ - public static function getEnclosures() - { - return array( - '"' => t('Double Quote'), - "'" => t('Single Quote'), - '' => t('None'), - ); - } - - /** - * Check boolean field value - * - * @static - * @access public - * @param mixed $value - * @return int - */ - public static function getBooleanValue($value) - { - if (! empty($value)) { - $value = trim(strtolower($value)); - return $value === '1' || $value{0} === 't' || $value{0} === 'y' ? 1 : 0; - } - - return 0; - } - - /** - * Output CSV file to standard output - * - * @static - * @access public - * @param array $rows - */ - public static function output(array $rows) - { - $csv = new static; - $csv->write('php://output', $rows); - } - - /** - * Define column mapping between CSV and SQL columns - * - * @access public - * @param array $columns - * @return Csv - */ - public function setColumnMapping(array $columns) - { - $this->columns = $columns; - return $this; - } - - /** - * Read CSV file - * - * @access public - * @param string $filename - * @param callable $callback Example: function(array $row, $line_number) - * @return Csv - */ - public function read($filename, $callback) - { - $file = new SplFileObject($filename); - $file->setFlags(SplFileObject::READ_CSV); - $file->setCsvControl($this->delimiter, $this->enclosure); - $line_number = 0; - - foreach ($file as $row) { - $row = $this->filterRow($row); - - if (! empty($row) && $line_number > 0) { - call_user_func_array($callback, array($this->associateColumns($row), $line_number)); - } - - $line_number++; - } - - return $this; - } - - /** - * Write CSV file - * - * @access public - * @param string $filename - * @param array $rows - * @return Csv - */ - public function write($filename, array $rows) - { - $fp = fopen($filename, 'w'); - - if (is_resource($fp)) { - foreach ($rows as $row) { - fputcsv($fp, $row, $this->delimiter, $this->enclosure); - } - - fclose($fp); - } - - return $this; - } - - /** - * Associate columns header with row values - * - * @access private - * @param array $row - * @return array - */ - private function associateColumns(array $row) - { - $line = array(); - $index = 0; - - foreach ($this->columns as $sql_name => $csv_name) { - if (isset($row[$index])) { - $line[$sql_name] = $row[$index]; - } else { - $line[$sql_name] = ''; - } - - $index++; - } - - return $line; - } - - /** - * Filter empty rows - * - * @access private - * @param array $row - * @return array - */ - private function filterRow(array $row) - { - return array_filter($row); - } -} diff --git a/sources/app/Core/DateParser.php b/sources/app/Core/DateParser.php deleted file mode 100644 index a7b10a7..0000000 --- a/sources/app/Core/DateParser.php +++ /dev/null @@ -1,336 +0,0 @@ -configModel->get('application_date_format', DateParser::DATE_FORMAT); - } - - /** - * Get date time format from settings - * - * @access public - * @return string - */ - public function getUserDateTimeFormat() - { - return $this->configModel->get('application_datetime_format', DateParser::DATE_TIME_FORMAT); - } - - /** - * Get time format from settings - * - * @access public - * @return string - */ - public function getUserTimeFormat() - { - return $this->configModel->get('application_time_format', DateParser::TIME_FORMAT); - } - - /** - * List of time formats - * - * @access public - * @return string[] - */ - public function getTimeFormats() - { - return array( - 'H:i', - 'g:i a', - ); - } - - /** - * List of date formats - * - * @access public - * @param boolean $iso - * @return string[] - */ - public function getDateFormats($iso = false) - { - $formats = array( - $this->getUserDateFormat(), - ); - - $isoFormats = array( - 'Y-m-d', - 'Y_m_d', - ); - - $userFormats = array( - 'm/d/Y', - 'd/m/Y', - 'Y/m/d', - 'd.m.Y', - ); - - if ($iso) { - $formats = array_merge($formats, $isoFormats, $userFormats); - } else { - $formats = array_merge($formats, $userFormats); - } - - return array_unique($formats); - } - - /** - * List of datetime formats - * - * @access public - * @param boolean $iso - * @return string[] - */ - public function getDateTimeFormats($iso = false) - { - $formats = array( - $this->getUserDateTimeFormat(), - ); - - foreach ($this->getDateFormats($iso) as $date) { - foreach ($this->getTimeFormats() as $time) { - $formats[] = $date.' '.$time; - } - } - - return array_unique($formats); - } - - /** - * List of all date formats - * - * @access public - * @param boolean $iso - * @return string[] - */ - public function getAllDateFormats($iso = false) - { - return array_merge($this->getDateFormats($iso), $this->getDateTimeFormats($iso)); - } - - /** - * Get available formats (visible in settings) - * - * @access public - * @param array $formats - * @return array - */ - public function getAvailableFormats(array $formats) - { - $values = array(); - - foreach ($formats as $format) { - $values[$format] = date($format).' ('.$format.')'; - } - - return $values; - } - - /** - * Get formats for date parsing - * - * @access public - * @return array - */ - public function getParserFormats() - { - return array( - $this->getUserDateFormat(), - 'Y-m-d', - 'Y_m_d', - $this->getUserDateTimeFormat(), - 'Y-m-d H:i', - 'Y_m_d H:i', - ); - } - - /** - * Parse a date and return a unix timestamp, try different date formats - * - * @access public - * @param string $value Date to parse - * @return integer - */ - public function getTimestamp($value) - { - if (ctype_digit($value)) { - return (int) $value; - } - - foreach ($this->getParserFormats() as $format) { - $timestamp = $this->getValidDate($value, $format); - - if ($timestamp !== 0) { - return $timestamp; - } - } - - return 0; - } - - /** - * Return a timestamp if the given date format is correct otherwise return 0 - * - * @access private - * @param string $value Date to parse - * @param string $format Date format - * @return integer - */ - private function getValidDate($value, $format) - { - $date = DateTime::createFromFormat($format, $value); - - if ($date !== false) { - $errors = DateTime::getLastErrors(); - if ($errors['error_count'] === 0 && $errors['warning_count'] === 0) { - $timestamp = $date->getTimestamp(); - return $timestamp > 0 ? $timestamp : 0; - } - } - - return 0; - } - - /** - * Return true if the date is within the date range - * - * @access public - * @param DateTime $date - * @param DateTime $start - * @param DateTime $end - * @return boolean - */ - public function withinDateRange(DateTime $date, DateTime $start, DateTime $end) - { - return $date >= $start && $date <= $end; - } - - /** - * Get the total number of hours between 2 datetime objects - * Minutes are rounded to the nearest quarter - * - * @access public - * @param DateTime $d1 - * @param DateTime $d2 - * @return float - */ - public function getHours(DateTime $d1, DateTime $d2) - { - $seconds = $this->getRoundedSeconds(abs($d1->getTimestamp() - $d2->getTimestamp())); - return round($seconds / 3600, 2); - } - - /** - * Round the timestamp to the nearest quarter - * - * @access public - * @param integer $seconds Timestamp - * @return integer - */ - public function getRoundedSeconds($seconds) - { - return (int) round($seconds / (15 * 60)) * (15 * 60); - } - - /** - * Get ISO-8601 date from user input - * - * @access public - * @param string $value Date to parse - * @return string - */ - public function getIsoDate($value) - { - return date('Y-m-d', $this->getTimestamp($value)); - } - - /** - * Get a timestamp from an ISO date format - * - * @access public - * @param string $value - * @return integer - */ - public function getTimestampFromIsoFormat($value) - { - return $this->removeTimeFromTimestamp(ctype_digit($value) ? $value : strtotime($value)); - } - - /** - * Remove the time from a timestamp - * - * @access public - * @param integer $timestamp - * @return integer - */ - public function removeTimeFromTimestamp($timestamp) - { - return mktime(0, 0, 0, date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp)); - } - - /** - * Format date (form display) - * - * @access public - * @param array $values Database values - * @param string[] $fields Date fields - * @param string $format Date format - * @return array - */ - public function format(array $values, array $fields, $format) - { - foreach ($fields as $field) { - if (! empty($values[$field])) { - $values[$field] = date($format, $values[$field]); - } else { - $values[$field] = ''; - } - } - - return $values; - } - - /** - * Convert date to timestamp - * - * @access public - * @param array $values Database values - * @param string[] $fields Date fields - * @param boolean $keep_time Keep time or not - * @return array - */ - public function convert(array $values, array $fields, $keep_time = false) - { - foreach ($fields as $field) { - if (! empty($values[$field])) { - $timestamp = $this->getTimestamp($values[$field]); - $values[$field] = $keep_time ? $timestamp : $this->removeTimeFromTimestamp($timestamp); - } - } - - return $values; - } -} diff --git a/sources/app/Core/Event/EventManager.php b/sources/app/Core/Event/EventManager.php deleted file mode 100644 index 9ae4317..0000000 --- a/sources/app/Core/Event/EventManager.php +++ /dev/null @@ -1,63 +0,0 @@ -events[$event] = $description; - return $this; - } - - /** - * Get the list of events and description that can be used from the user interface - * - * @access public - * @return array - */ - public function getAll() - { - $events = array( - TaskLinkModel::EVENT_CREATE_UPDATE => t('Task link creation or modification'), - TaskModel::EVENT_MOVE_COLUMN => t('Move a task to another column'), - TaskModel::EVENT_UPDATE => t('Task modification'), - TaskModel::EVENT_CREATE => t('Task creation'), - TaskModel::EVENT_OPEN => t('Reopen a task'), - TaskModel::EVENT_CLOSE => t('Closing a task'), - TaskModel::EVENT_CREATE_UPDATE => t('Task creation or modification'), - TaskModel::EVENT_ASSIGNEE_CHANGE => t('Task assignee change'), - TaskModel::EVENT_DAILY_CRONJOB => t('Daily background job for tasks'), - ); - - $events = array_merge($events, $this->events); - asort($events); - - return $events; - } -} diff --git a/sources/app/Core/ExternalLink/ExternalLinkInterface.php b/sources/app/Core/ExternalLink/ExternalLinkInterface.php deleted file mode 100644 index 2dbc0a1..0000000 --- a/sources/app/Core/ExternalLink/ExternalLinkInterface.php +++ /dev/null @@ -1,36 +0,0 @@ -providers, $provider); - return $this; - } - - /** - * Get provider - * - * @access public - * @param string $type - * @throws ExternalLinkProviderNotFound - * @return ExternalLinkProviderInterface - */ - public function getProvider($type) - { - foreach ($this->providers as $provider) { - if ($provider->getType() === $type) { - return $provider; - } - } - - throw new ExternalLinkProviderNotFound('Unable to find link provider: '.$type); - } - - /** - * Get link types - * - * @access public - * @return array - */ - public function getTypes() - { - $types = array(); - - foreach ($this->providers as $provider) { - $types[$provider->getType()] = $provider->getName(); - } - - asort($types); - - return array(self::TYPE_AUTO => t('Auto')) + $types; - } - - /** - * Get dependency label from a provider - * - * @access public - * @param string $type - * @param string $dependency - * @return string - */ - public function getDependencyLabel($type, $dependency) - { - $provider = $this->getProvider($type); - $dependencies = $provider->getDependencies(); - return isset($dependencies[$dependency]) ? $dependencies[$dependency] : $dependency; - } - - /** - * Find a provider that match - * - * @access public - * @throws ExternalLinkProviderNotFound - * @return ExternalLinkProviderInterface - */ - public function find() - { - if ($this->userInputType === self::TYPE_AUTO) { - $provider = $this->findProvider(); - } else { - $provider = $this->getProvider($this->userInputType); - $provider->setUserTextInput($this->userInputText); - - if (! $provider->match()) { - throw new ExternalLinkProviderNotFound('Unable to parse URL with selected provider'); - } - } - - if ($provider === null) { - throw new ExternalLinkProviderNotFound('Unable to find link information from provided information'); - } - - return $provider; - } - - /** - * Set form values - * - * @access public - * @param array $values - * @return ExternalLinkManager - */ - public function setUserInput(array $values) - { - $this->userInputType = empty($values['type']) ? self::TYPE_AUTO : $values['type']; - $this->userInputText = empty($values['text']) ? '' : trim($values['text']); - return $this; - } - - /** - * Set provider type - * - * @access public - * @param string $userInputType - * @return ExternalLinkManager - */ - public function setUserInputType($userInputType) - { - $this->userInputType = $userInputType; - return $this; - } - - /** - * Set external link - * @param string $userInputText - * @return ExternalLinkManager - */ - public function setUserInputText($userInputText) - { - $this->userInputText = $userInputText; - return $this; - } - - /** - * Find a provider that user input - * - * @access private - * @return ExternalLinkProviderInterface - */ - private function findProvider() - { - foreach ($this->providers as $provider) { - $provider->setUserTextInput($this->userInputText); - - if ($provider->match()) { - return $provider; - } - } - - return null; - } -} diff --git a/sources/app/Core/ExternalLink/ExternalLinkProviderInterface.php b/sources/app/Core/ExternalLink/ExternalLinkProviderInterface.php deleted file mode 100644 index c908e1e..0000000 --- a/sources/app/Core/ExternalLink/ExternalLinkProviderInterface.php +++ /dev/null @@ -1,71 +0,0 @@ - t('Related'), - * 'child' => t('Child'), - * 'parent' => t('Parent'), - * 'self' => t('Self'), - * ] - * - * The dictionary key is saved in the database. - * - * @access public - * @return array - */ - public function getDependencies(); - - /** - * Set text entered by the user - * - * @access public - * @param string $input - */ - public function setUserTextInput($input); - - /** - * Return true if the provider can parse correctly the user input - * - * @access public - * @return boolean - */ - public function match(); - - /** - * Get the link found with the properties - * - * @access public - * @return ExternalLinkInterface - */ - public function getLink(); -} diff --git a/sources/app/Core/ExternalLink/ExternalLinkProviderNotFound.php b/sources/app/Core/ExternalLink/ExternalLinkProviderNotFound.php deleted file mode 100644 index 4fd0520..0000000 --- a/sources/app/Core/ExternalLink/ExternalLinkProviderNotFound.php +++ /dev/null @@ -1,15 +0,0 @@ - 'T_WHITESPACE', - '/^([<=>]{0,2}[0-9]{4}-[0-9]{2}-[0-9]{2})/' => 'T_STRING', - '/^([<=>]{1,2}\w+)/u' => 'T_STRING', - '/^([<=>]{1,2}".+")/' => 'T_STRING', - '/^("(.+)")/' => 'T_STRING', - '/^(\S+)/u' => 'T_STRING', - '/^(#\d+)/' => 'T_STRING', - ); - - /** - * Default token - * - * @access private - * @var string - */ - private $defaultToken = ''; - - /** - * Add token - * - * @access public - * @param string $regex - * @param string $token - * @return $this - */ - public function addToken($regex, $token) - { - $this->tokenMap = array($regex => $token) + $this->tokenMap; - return $this; - } - - /** - * Set default token - * - * @access public - * @param string $token - * @return $this - */ - public function setDefaultToken($token) - { - $this->defaultToken = $token; - return $this; - } - - /** - * Tokenize input string - * - * @access public - * @param string $input - * @return array - */ - public function tokenize($input) - { - $tokens = array(); - $this->offset = 0; - $input_length = mb_strlen($input, 'UTF-8'); - - while ($this->offset < $input_length) { - $result = $this->match(mb_substr($input, $this->offset, $input_length, 'UTF-8')); - - if ($result === false) { - return array(); - } - - $tokens[] = $result; - } - - return $this->map($tokens); - } - - /** - * Find a token that match and move the offset - * - * @access protected - * @param string $string - * @return array|boolean - */ - protected function match($string) - { - foreach ($this->tokenMap as $pattern => $name) { - if (preg_match($pattern, $string, $matches)) { - $this->offset += mb_strlen($matches[1], 'UTF-8'); - - return array( - 'match' => str_replace('"', '', $matches[1]), - 'token' => $name, - ); - } - } - - return false; - } - - /** - * Build map of tokens and matches - * - * @access protected - * @param array $tokens - * @return array - */ - protected function map(array $tokens) - { - $map = array(); - $leftOver = ''; - - while (false !== ($token = current($tokens))) { - if ($token['token'] === 'T_STRING' || $token['token'] === 'T_WHITESPACE') { - $leftOver .= $token['match']; - } else { - $next = next($tokens); - - if ($next !== false && $next['token'] === 'T_STRING') { - $map[$token['token']][] = $next['match']; - } - } - - next($tokens); - } - - $leftOver = trim($leftOver); - - if ($this->defaultToken !== '' && $leftOver !== '') { - $map[$this->defaultToken] = array($leftOver); - } - - return $map; - } -} diff --git a/sources/app/Core/Filter/LexerBuilder.php b/sources/app/Core/Filter/LexerBuilder.php deleted file mode 100644 index 7a9a714..0000000 --- a/sources/app/Core/Filter/LexerBuilder.php +++ /dev/null @@ -1,151 +0,0 @@ -lexer = new Lexer; - $this->queryBuilder = new QueryBuilder(); - } - - /** - * Add a filter - * - * @access public - * @param FilterInterface $filter - * @param bool $default - * @return LexerBuilder - */ - public function withFilter(FilterInterface $filter, $default = false) - { - $attributes = $filter->getAttributes(); - - foreach ($attributes as $attribute) { - $this->filters[$attribute] = $filter; - $this->lexer->addToken(sprintf("/^(%s:)/", $attribute), $attribute); - - if ($default) { - $this->lexer->setDefaultToken($attribute); - } - } - - return $this; - } - - /** - * Set the query - * - * @access public - * @param Table $query - * @return LexerBuilder - */ - public function withQuery(Table $query) - { - $this->query = $query; - $this->queryBuilder->withQuery($this->query); - return $this; - } - - /** - * Parse the input and build the query - * - * @access public - * @param string $input - * @return QueryBuilder - */ - public function build($input) - { - $tokens = $this->lexer->tokenize($input); - - foreach ($tokens as $token => $values) { - if (isset($this->filters[$token])) { - $this->applyFilters($this->filters[$token], $values); - } - } - - return $this->queryBuilder; - } - - /** - * Apply filters to the query - * - * @access protected - * @param FilterInterface $filter - * @param array $values - */ - protected function applyFilters(FilterInterface $filter, array $values) - { - $len = count($values); - - if ($len > 1) { - $criteria = new OrCriteria(); - $criteria->withQuery($this->query); - - foreach ($values as $value) { - $currentFilter = clone($filter); - $criteria->withFilter($currentFilter->withValue($value)); - } - - $this->queryBuilder->withCriteria($criteria); - } elseif ($len === 1) { - $this->queryBuilder->withFilter($filter->withValue($values[0])); - } - } - - /** - * Clone object with deep copy - */ - public function __clone() - { - $this->lexer = clone $this->lexer; - $this->query = clone $this->query; - $this->queryBuilder = clone $this->queryBuilder; - } -} diff --git a/sources/app/Core/Filter/OrCriteria.php b/sources/app/Core/Filter/OrCriteria.php deleted file mode 100644 index 174b845..0000000 --- a/sources/app/Core/Filter/OrCriteria.php +++ /dev/null @@ -1,68 +0,0 @@ -query = $query; - return $this; - } - - /** - * Set filter - * - * @access public - * @param FilterInterface $filter - * @return CriteriaInterface - */ - public function withFilter(FilterInterface $filter) - { - $this->filters[] = $filter; - return $this; - } - - /** - * Apply condition - * - * @access public - * @return CriteriaInterface - */ - public function apply() - { - $this->query->beginOr(); - - foreach ($this->filters as $filter) { - $filter->withQuery($this->query)->apply(); - } - - $this->query->closeOr(); - return $this; - } -} diff --git a/sources/app/Core/Filter/QueryBuilder.php b/sources/app/Core/Filter/QueryBuilder.php deleted file mode 100644 index 3de82b6..0000000 --- a/sources/app/Core/Filter/QueryBuilder.php +++ /dev/null @@ -1,103 +0,0 @@ -query = $query; - return $this; - } - - /** - * Set a filter - * - * @access public - * @param FilterInterface $filter - * @return QueryBuilder - */ - public function withFilter(FilterInterface $filter) - { - $filter->withQuery($this->query)->apply(); - return $this; - } - - /** - * Set a criteria - * - * @access public - * @param CriteriaInterface $criteria - * @return QueryBuilder - */ - public function withCriteria(CriteriaInterface $criteria) - { - $criteria->withQuery($this->query)->apply(); - return $this; - } - - /** - * Set a formatter - * - * @access public - * @param FormatterInterface $formatter - * @return string|array - */ - public function format(FormatterInterface $formatter) - { - return $formatter->withQuery($this->query)->format(); - } - - /** - * Get the query result as array - * - * @access public - * @return array - */ - public function toArray() - { - return $this->query->findAll(); - } - - /** - * Get Query object - * - * @access public - * @return Table - */ - public function getQuery() - { - return $this->query; - } - - /** - * Clone object with deep copy - */ - public function __clone() - { - $this->query = clone $this->query; - } -} diff --git a/sources/app/Core/Group/GroupBackendProviderInterface.php b/sources/app/Core/Group/GroupBackendProviderInterface.php deleted file mode 100644 index 74c5cb0..0000000 --- a/sources/app/Core/Group/GroupBackendProviderInterface.php +++ /dev/null @@ -1,21 +0,0 @@ -providers[] = $provider; - return $this; - } - - /** - * Find a group from a search query - * - * @access public - * @param string $input - * @return GroupProviderInterface[] - */ - public function find($input) - { - $groups = array(); - - foreach ($this->providers as $provider) { - $groups = array_merge($groups, $provider->find($input)); - } - - return $this->removeDuplicates($groups); - } - - /** - * Remove duplicated groups - * - * @access private - * @param array $groups - * @return GroupProviderInterface[] - */ - private function removeDuplicates(array $groups) - { - $result = array(); - - foreach ($groups as $group) { - if (! isset($result[$group->getName()])) { - $result[$group->getName()] = $group; - } - } - - return array_values($result); - } -} diff --git a/sources/app/Core/Group/GroupProviderInterface.php b/sources/app/Core/Group/GroupProviderInterface.php deleted file mode 100644 index 4c7c16e..0000000 --- a/sources/app/Core/Group/GroupProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ -container = $container; - $this->helpers = new Container; - } - - /** - * Expose helpers with magic getter - * - * @access public - * @param string $helper - * @return mixed - */ - public function __get($helper) - { - return $this->getHelper($helper); - } - - /** - * Expose helpers with method - * - * @access public - * @param string $helper - * @return mixed - */ - public function getHelper($helper) - { - return $this->helpers[$helper]; - } - - /** - * Register a new Helper - * - * @access public - * @param string $property - * @param string $className - * @return Helper - */ - public function register($property, $className) - { - $container = $this->container; - - $this->helpers[$property] = function() use ($className, $container) { - return new $className($container); - }; - - return $this; - } -} diff --git a/sources/app/Core/Http/Client.php b/sources/app/Core/Http/Client.php deleted file mode 100644 index 3c4397e..0000000 --- a/sources/app/Core/Http/Client.php +++ /dev/null @@ -1,224 +0,0 @@ -doRequest('GET', $url, '', $headers); - } - - /** - * Send a GET HTTP request and parse JSON response - * - * @access public - * @param string $url - * @param string[] $headers - * @return array - */ - public function getJson($url, array $headers = array()) - { - $response = $this->doRequest('GET', $url, '', array_merge(array('Accept: application/json'), $headers)); - return json_decode($response, true) ?: array(); - } - - /** - * Send a POST HTTP request encoded in JSON - * - * @access public - * @param string $url - * @param array $data - * @param string[] $headers - * @return string - */ - public function postJson($url, array $data, array $headers = array()) - { - return $this->doRequest( - 'POST', - $url, - json_encode($data), - array_merge(array('Content-type: application/json'), $headers) - ); - } - - /** - * Send a POST HTTP request encoded in JSON (Fire and forget) - * - * @access public - * @param string $url - * @param array $data - * @param string[] $headers - */ - public function postJsonAsync($url, array $data, array $headers = array()) - { - $this->queueManager->push(HttpAsyncJob::getInstance($this->container)->withParams( - 'POST', - $url, - json_encode($data), - array_merge(array('Content-type: application/json'), $headers) - )); - } - - /** - * Send a POST HTTP request encoded in www-form-urlencoded - * - * @access public - * @param string $url - * @param array $data - * @param string[] $headers - * @return string - */ - public function postForm($url, array $data, array $headers = array()) - { - return $this->doRequest( - 'POST', - $url, - http_build_query($data), - array_merge(array('Content-type: application/x-www-form-urlencoded'), $headers) - ); - } - - /** - * Send a POST HTTP request encoded in www-form-urlencoded (fire and forget) - * - * @access public - * @param string $url - * @param array $data - * @param string[] $headers - */ - public function postFormAsync($url, array $data, array $headers = array()) - { - $this->queueManager->push(HttpAsyncJob::getInstance($this->container)->withParams( - 'POST', - $url, - http_build_query($data), - array_merge(array('Content-type: application/x-www-form-urlencoded'), $headers) - )); - } - - /** - * Make the HTTP request - * - * @access public - * @param string $method - * @param string $url - * @param string $content - * @param string[] $headers - * @return string - */ - public function doRequest($method, $url, $content, array $headers) - { - if (empty($url)) { - return ''; - } - - $startTime = microtime(true); - $stream = @fopen(trim($url), 'r', false, stream_context_create($this->getContext($method, $content, $headers))); - $response = ''; - - if (is_resource($stream)) { - $response = stream_get_contents($stream); - } else { - $this->logger->error('HttpClient: request failed'); - } - - if (DEBUG) { - $this->logger->debug('HttpClient: url='.$url); - $this->logger->debug('HttpClient: headers='.var_export($headers, true)); - $this->logger->debug('HttpClient: payload='.$content); - $this->logger->debug('HttpClient: metadata='.var_export(@stream_get_meta_data($stream), true)); - $this->logger->debug('HttpClient: response='.$response); - $this->logger->debug('HttpClient: executionTime='.(microtime(true) - $startTime)); - } - - return $response; - } - - /** - * Get stream context - * - * @access private - * @param string $method - * @param string $content - * @param string[] $headers - * @return array - */ - private function getContext($method, $content, array $headers) - { - $default_headers = array( - 'User-Agent: '.self::HTTP_USER_AGENT, - 'Connection: close', - ); - - if (HTTP_PROXY_USERNAME) { - $default_headers[] = 'Proxy-Authorization: Basic '.base64_encode(HTTP_PROXY_USERNAME.':'.HTTP_PROXY_PASSWORD); - } - - $headers = array_merge($default_headers, $headers); - - $context = array( - 'http' => array( - 'method' => $method, - 'protocol_version' => 1.1, - 'timeout' => self::HTTP_TIMEOUT, - 'max_redirects' => self::HTTP_MAX_REDIRECTS, - 'header' => implode("\r\n", $headers), - 'content' => $content, - ) - ); - - if (HTTP_PROXY_HOSTNAME) { - $context['http']['proxy'] = 'tcp://'.HTTP_PROXY_HOSTNAME.':'.HTTP_PROXY_PORT; - $context['http']['request_fulluri'] = true; - } - - if (HTTP_VERIFY_SSL_CERTIFICATE === false) { - $context['ssl'] = array( - 'verify_peer' => false, - 'verify_peer_name' => false, - 'allow_self_signed' => true, - ); - } - - return $context; - } -} diff --git a/sources/app/Core/Http/OAuth2.php b/sources/app/Core/Http/OAuth2.php deleted file mode 100644 index 211ca5b..0000000 --- a/sources/app/Core/Http/OAuth2.php +++ /dev/null @@ -1,150 +0,0 @@ -clientId = $clientId; - $this->secret = $secret; - $this->callbackUrl = $callbackUrl; - $this->authUrl = $authUrl; - $this->tokenUrl = $tokenUrl; - $this->scopes = $scopes; - - return $this; - } - - /** - * Generate OAuth2 state and return the token value - * - * @access public - * @return string - */ - public function getState() - { - if (! isset($this->sessionStorage->oauthState) || empty($this->sessionStorage->oauthState)) { - $this->sessionStorage->oauthState = $this->token->getToken(); - } - - return $this->sessionStorage->oauthState; - } - - /** - * Check the validity of the state (CSRF token) - * - * @access public - * @param string $state - * @return bool - */ - public function isValidateState($state) - { - return $state === $this->getState(); - } - - /** - * Get authorization url - * - * @access public - * @return string - */ - public function getAuthorizationUrl() - { - $params = array( - 'response_type' => 'code', - 'client_id' => $this->clientId, - 'redirect_uri' => $this->callbackUrl, - 'scope' => implode(' ', $this->scopes), - 'state' => $this->getState(), - ); - - return $this->authUrl.'?'.http_build_query($params); - } - - /** - * Get authorization header - * - * @access public - * @return string - */ - public function getAuthorizationHeader() - { - if (strtolower($this->tokenType) === 'bearer') { - return 'Authorization: Bearer '.$this->accessToken; - } - - return ''; - } - - /** - * Get access token - * - * @access public - * @param string $code - * @return string - */ - public function getAccessToken($code) - { - if (empty($this->accessToken) && ! empty($code)) { - $params = array( - 'code' => $code, - 'client_id' => $this->clientId, - 'client_secret' => $this->secret, - 'redirect_uri' => $this->callbackUrl, - 'grant_type' => 'authorization_code', - 'state' => $this->getState(), - ); - - $response = json_decode($this->httpClient->postForm($this->tokenUrl, $params, array('Accept: application/json')), true); - - $this->tokenType = isset($response['token_type']) ? $response['token_type'] : ''; - $this->accessToken = isset($response['access_token']) ? $response['access_token'] : ''; - } - - return $this->accessToken; - } - - /** - * Set access token - * - * @access public - * @param string $token - * @param string $type - * @return string - */ - public function setAccessToken($token, $type = 'bearer') - { - $this->accessToken = $token; - $this->tokenType = $type; - } -} diff --git a/sources/app/Core/Http/RememberMeCookie.php b/sources/app/Core/Http/RememberMeCookie.php deleted file mode 100644 index a32b35f..0000000 --- a/sources/app/Core/Http/RememberMeCookie.php +++ /dev/null @@ -1,120 +0,0 @@ - $token, - 'sequence' => $sequence, - ); - } - - /** - * Return true if the current user has a RememberMe cookie - * - * @access public - * @return bool - */ - public function hasCookie() - { - return $this->request->getCookie(self::COOKIE_NAME) !== ''; - } - - /** - * Write and encode the cookie - * - * @access public - * @param string $token Session token - * @param string $sequence Sequence token - * @param string $expiration Cookie expiration - * @return boolean - */ - public function write($token, $sequence, $expiration) - { - return setcookie( - self::COOKIE_NAME, - $this->encode($token, $sequence), - $expiration, - $this->helper->url->dir(), - null, - $this->request->isHTTPS(), - true - ); - } - - /** - * Read and decode the cookie - * - * @access public - * @return mixed - */ - public function read() - { - $cookie = $this->request->getCookie(self::COOKIE_NAME); - - if (empty($cookie)) { - return false; - } - - return $this->decode($cookie); - } - - /** - * Remove the cookie - * - * @access public - * @return boolean - */ - public function remove() - { - return setcookie( - self::COOKIE_NAME, - '', - time() - 3600, - $this->helper->url->dir(), - null, - $this->request->isHTTPS(), - true - ); - } -} diff --git a/sources/app/Core/Http/Request.php b/sources/app/Core/Http/Request.php deleted file mode 100644 index e0df2d3..0000000 --- a/sources/app/Core/Http/Request.php +++ /dev/null @@ -1,346 +0,0 @@ -server = empty($server) ? $_SERVER : $server; - $this->get = empty($get) ? $_GET : $get; - $this->post = empty($post) ? $_POST : $post; - $this->files = empty($files) ? $_FILES : $files; - $this->cookies = empty($cookies) ? $_COOKIE : $cookies; - } - - /** - * Set GET parameters - * - * @param array $params - */ - public function setParams(array $params) - { - $this->get = array_merge($this->get, $params); - } - - /** - * Get query string string parameter - * - * @access public - * @param string $name Parameter name - * @param string $default_value Default value - * @return string - */ - public function getStringParam($name, $default_value = '') - { - return isset($this->get[$name]) ? $this->get[$name] : $default_value; - } - - /** - * Get query string integer parameter - * - * @access public - * @param string $name Parameter name - * @param integer $default_value Default value - * @return integer - */ - public function getIntegerParam($name, $default_value = 0) - { - return isset($this->get[$name]) && ctype_digit($this->get[$name]) ? (int) $this->get[$name] : $default_value; - } - - /** - * Get a form value - * - * @access public - * @param string $name Form field name - * @return string|null - */ - public function getValue($name) - { - $values = $this->getValues(); - return isset($values[$name]) ? $values[$name] : null; - } - - /** - * Get form values and check for CSRF token - * - * @access public - * @return array - */ - public function getValues() - { - 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 array(); - } - - /** - * Get the raw body of the HTTP request - * - * @access public - * @return string - */ - public function getBody() - { - return file_get_contents('php://input'); - } - - /** - * Get the Json request body - * - * @access public - * @return array - */ - public function getJson() - { - return json_decode($this->getBody(), true) ?: array(); - } - - /** - * Get the content of an uploaded file - * - * @access public - * @param string $name Form file name - * @return string - */ - public function getFileContent($name) - { - if (isset($this->files[$name]['tmp_name'])) { - return file_get_contents($this->files[$name]['tmp_name']); - } - - return ''; - } - - /** - * Get the path of an uploaded file - * - * @access public - * @param string $name Form file name - * @return string - */ - public function getFilePath($name) - { - return isset($this->files[$name]['tmp_name']) ? $this->files[$name]['tmp_name'] : ''; - } - - /** - * Get info of an uploaded file - * - * @access public - * @param string $name Form file name - * @return array - */ - public function getFileInfo($name) - { - return isset($this->files[$name]) ? $this->files[$name] : array(); - } - - /** - * Return HTTP method - * - * @access public - * @return bool - */ - public function getMethod() - { - return $this->getServerVariable('REQUEST_METHOD'); - } - - /** - * Return true if the HTTP request is sent with the POST method - * - * @access public - * @return bool - */ - public function isPost() - { - return $this->getServerVariable('REQUEST_METHOD') === 'POST'; - } - - /** - * Return true if the HTTP request is an Ajax request - * - * @access public - * @return bool - */ - public function isAjax() - { - return $this->getHeader('X-Requested-With') === 'XMLHttpRequest'; - } - - /** - * Check if the page is requested through HTTPS - * - * Note: IIS return the value 'off' and other web servers an empty value when it's not HTTPS - * - * @access public - * @return boolean - */ - public function isHTTPS() - { - if ($this->getServerVariable('HTTP_X_FORWARDED_PROTO') === 'https') { - return true; - } - - return $this->getServerVariable('HTTPS') !== '' && $this->server['HTTPS'] !== 'off'; - } - - /** - * Get cookie value - * - * @access public - * @param string $name - * @return string - */ - public function getCookie($name) - { - return isset($this->cookies[$name]) ? $this->cookies[$name] : ''; - } - - /** - * Return a HTTP header value - * - * @access public - * @param string $name Header name - * @return string - */ - public function getHeader($name) - { - $name = 'HTTP_'.str_replace('-', '_', strtoupper($name)); - return $this->getServerVariable($name); - } - - /** - * Get remote user - * - * @access public - * @return string - */ - public function getRemoteUser() - { - return $this->getServerVariable(REVERSE_PROXY_USER_HEADER); - } - - /** - * Returns query string - * - * @access public - * @return string - */ - public function getQueryString() - { - return $this->getServerVariable('QUERY_STRING'); - } - - /** - * Return URI - * - * @access public - * @return string - */ - public function getUri() - { - return $this->getServerVariable('REQUEST_URI'); - } - - /** - * Get the user agent - * - * @access public - * @return string - */ - public function getUserAgent() - { - return empty($this->server['HTTP_USER_AGENT']) ? t('Unknown') : $this->server['HTTP_USER_AGENT']; - } - - /** - * Get the IP address of the user - * - * @access public - * @return string - */ - public function getIpAddress() - { - $keys = array( - 'HTTP_CLIENT_IP', - 'HTTP_X_FORWARDED_FOR', - 'HTTP_X_FORWARDED', - 'HTTP_X_CLUSTER_CLIENT_IP', - 'HTTP_FORWARDED_FOR', - 'HTTP_FORWARDED', - 'REMOTE_ADDR' - ); - - foreach ($keys as $key) { - if ($this->getServerVariable($key) !== '') { - foreach (explode(',', $this->server[$key]) as $ipAddress) { - return trim($ipAddress); - } - } - } - - return t('Unknown'); - } - - /** - * Get start time - * - * @access public - * @return float - */ - public function getStartTime() - { - return $this->getServerVariable('REQUEST_TIME_FLOAT') ?: 0; - } - - /** - * Get server variable - * - * @access public - * @param string $variable - * @return string - */ - public function getServerVariable($variable) - { - return isset($this->server[$variable]) ? $this->server[$variable] : ''; - } -} diff --git a/sources/app/Core/Http/Response.php b/sources/app/Core/Http/Response.php deleted file mode 100644 index 0f16fb6..0000000 --- a/sources/app/Core/Http/Response.php +++ /dev/null @@ -1,385 +0,0 @@ -responseSent; - } - - /** - * Set HTTP status code - * - * @access public - * @param integer $statusCode - * @return $this - */ - public function withStatusCode($statusCode) - { - $this->httpStatusCode = $statusCode; - return $this; - } - - /** - * Set HTTP header - * - * @access public - * @param string $header - * @param string $value - * @return $this - */ - public function withHeader($header, $value) - { - $this->httpHeaders[$header] = $value; - return $this; - } - - /** - * Set content type header - * - * @access public - * @param string $value - * @return $this - */ - public function withContentType($value) - { - $this->httpHeaders['Content-Type'] = $value; - return $this; - } - - /** - * Set default security headers - * - * @access public - * @return $this - */ - public function withSecurityHeaders() - { - $this->httpHeaders['X-Content-Type-Options'] = 'nosniff'; - $this->httpHeaders['X-XSS-Protection'] = '1; mode=block'; - return $this; - } - - /** - * Set header Content-Security-Policy - * - * @access public - * @param array $policies - * @return $this - */ - public function withContentSecurityPolicy(array $policies = array()) - { - $values = ''; - - foreach ($policies as $policy => $acl) { - $values .= $policy.' '.trim($acl).'; '; - } - - $this->withHeader('Content-Security-Policy', $values); - return $this; - } - - /** - * Set header X-Frame-Options - * - * @access public - * @return $this - */ - public function withXframe() - { - $this->withHeader('X-Frame-Options', 'DENY'); - return $this; - } - - /** - * Set header Strict-Transport-Security (only if we use HTTPS) - * - * @access public - * @return $this - */ - public function withStrictTransportSecurity() - { - if ($this->request->isHTTPS()) { - $this->withHeader('Strict-Transport-Security', 'max-age=31536000'); - } - - return $this; - } - - /** - * Set HTTP response body - * - * @access public - * @param string $body - * @return $this - */ - public function withBody($body) - { - $this->httpBody = $body; - return $this; - } - - /** - * Send headers to cache a resource - * - * @access public - * @param integer $duration - * @param string $etag - * @return $this - */ - public function withCache($duration, $etag = '') - { - $this - ->withHeader('Pragma', 'cache') - ->withHeader('Expires', gmdate('D, d M Y H:i:s', time() + $duration) . ' GMT') - ->withHeader('Cache-Control', 'public, max-age=' . $duration) - ; - - if ($etag) { - $this->withHeader('ETag', '"' . $etag . '"'); - } - - return $this; - } - - /** - * Send no cache headers - * - * @access public - * @return $this - */ - public function withoutCache() - { - $this->withHeader('Pragma', 'no-cache'); - $this->withHeader('Expires', 'Sat, 26 Jul 1997 05:00:00 GMT'); - return $this; - } - - /** - * Force the browser to download an attachment - * - * @access public - * @param string $filename - * @return $this - */ - public function withFileDownload($filename) - { - $this->withHeader('Content-Disposition', 'attachment; filename="'.$filename.'"'); - $this->withHeader('Content-Transfer-Encoding', 'binary'); - $this->withHeader('Content-Type', 'application/octet-stream'); - return $this; - } - - /** - * Send headers and body - * - * @access public - */ - public function send() - { - $this->responseSent = true; - - if ($this->httpStatusCode !== 200) { - header('Status: '.$this->httpStatusCode); - header($this->request->getServerVariable('SERVER_PROTOCOL').' '.$this->httpStatusCode); - } - - foreach ($this->httpHeaders as $header => $value) { - header($header.': '.$value); - } - - if (! empty($this->httpBody)) { - echo $this->httpBody; - } - } - - /** - * Send a custom HTTP status code - * - * @access public - * @param integer $statusCode - */ - public function status($statusCode) - { - $this->withStatusCode($statusCode); - $this->send(); - } - - /** - * Redirect to another URL - * - * @access public - * @param string $url Redirection URL - * @param boolean $self If Ajax request and true: refresh the current page - */ - public function redirect($url, $self = false) - { - if ($this->request->isAjax()) { - $this->withHeader('X-Ajax-Redirect', $self ? 'self' : $url); - } else { - $this->withHeader('Location', $url); - } - - $this->send(); - } - - /** - * Send a HTML response - * - * @access public - * @param string $data - * @param integer $statusCode - */ - public function html($data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withContentType('text/html; charset=utf-8'); - $this->withBody($data); - $this->send(); - } - - /** - * Send a text response - * - * @access public - * @param string $data - * @param integer $statusCode - */ - public function text($data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withContentType('text/plain; charset=utf-8'); - $this->withBody($data); - $this->send(); - } - - /** - * Send a CSV response - * - * @access public - * @param array $data Data to serialize in csv - */ - public function csv(array $data) - { - $this->withoutCache(); - $this->withContentType('text/csv; charset=utf-8'); - $this->send(); - Csv::output($data); - } - - /** - * Send a Json response - * - * @access public - * @param array $data Data to serialize in json - * @param integer $statusCode HTTP status code - */ - public function json(array $data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withContentType('application/json'); - $this->withoutCache(); - $this->withBody(json_encode($data)); - $this->send(); - } - - /** - * Send a XML response - * - * @access public - * @param string $data - * @param integer $statusCode - */ - public function xml($data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withContentType('text/xml; charset=utf-8'); - $this->withoutCache(); - $this->withBody($data); - $this->send(); - } - - /** - * Send a javascript response - * - * @access public - * @param string $data - * @param integer $statusCode - */ - public function js($data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withContentType('text/javascript; charset=utf-8'); - $this->withBody($data); - $this->send(); - } - - /** - * Send a css response - * - * @access public - * @param string $data - * @param integer $statusCode - */ - public function css($data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withContentType('text/css; charset=utf-8'); - $this->withBody($data); - $this->send(); - } - - /** - * Send a binary response - * - * @access public - * @param string $data - * @param integer $statusCode - */ - public function binary($data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withoutCache(); - $this->withHeader('Content-Transfer-Encoding', 'binary'); - $this->withContentType('application/octet-stream'); - $this->withBody($data); - $this->send(); - } - - /** - * Send a iCal response - * - * @access public - * @param string $data - * @param integer $statusCode - */ - public function ical($data, $statusCode = 200) - { - $this->withStatusCode($statusCode); - $this->withContentType('text/calendar; charset=utf-8'); - $this->withBody($data); - $this->send(); - } -} diff --git a/sources/app/Core/Http/Route.php b/sources/app/Core/Http/Route.php deleted file mode 100644 index 9b45b72..0000000 --- a/sources/app/Core/Http/Route.php +++ /dev/null @@ -1,187 +0,0 @@ -activated = true; - return $this; - } - - /** - * Add route - * - * @access public - * @param string $path - * @param string $controller - * @param string $action - * @param string $plugin - * @return Route - */ - public function addRoute($path, $controller, $action, $plugin = '') - { - if ($this->activated) { - $path = ltrim($path, '/'); - $items = explode('/', $path); - $params = $this->findParams($items); - - $this->paths[] = array( - 'items' => $items, - 'count' => count($items), - 'controller' => $controller, - 'action' => $action, - 'plugin' => $plugin, - ); - - $this->urls[$plugin][$controller][$action][] = array( - 'path' => $path, - 'params' => $params, - 'count' => count($params), - ); - } - - return $this; - } - - /** - * Find a route according to the given path - * - * @access public - * @param string $path - * @return array - */ - public function findRoute($path) - { - $items = explode('/', ltrim($path, '/')); - $count = count($items); - - foreach ($this->paths as $route) { - if ($count === $route['count']) { - $params = array(); - - for ($i = 0; $i < $count; $i++) { - if ($route['items'][$i]{0} === ':') { - $params[substr($route['items'][$i], 1)] = $items[$i]; - } elseif ($route['items'][$i] !== $items[$i]) { - break; - } - } - - if ($i === $count) { - $this->request->setParams($params); - return array( - 'controller' => $route['controller'], - 'action' => $route['action'], - 'plugin' => $route['plugin'], - ); - } - } - } - - return array( - 'controller' => 'DashboardController', - 'action' => 'show', - 'plugin' => '', - ); - } - - /** - * Find route url - * - * @access public - * @param string $controller - * @param string $action - * @param array $params - * @param string $plugin - * @return string - */ - public function findUrl($controller, $action, array $params = array(), $plugin = '') - { - if ($plugin === '' && isset($params['plugin'])) { - $plugin = $params['plugin']; - unset($params['plugin']); - } - - if (! isset($this->urls[$plugin][$controller][$action])) { - return ''; - } - - foreach ($this->urls[$plugin][$controller][$action] as $route) { - if (array_diff_key($params, $route['params']) === array()) { - $url = $route['path']; - $i = 0; - - foreach ($params as $variable => $value) { - $url = str_replace(':'.$variable, $value, $url); - $i++; - } - - if ($i === $route['count']) { - return $url; - } - } - } - - return ''; - } - - /** - * Find url params - * - * @access public - * @param array $items - * @return array - */ - public function findParams(array $items) - { - $params = array(); - - foreach ($items as $item) { - if ($item !== '' && $item{0} === ':') { - $params[substr($item, 1)] = true; - } - } - - return $params; - } -} diff --git a/sources/app/Core/Http/Router.php b/sources/app/Core/Http/Router.php deleted file mode 100644 index 4de276a..0000000 --- a/sources/app/Core/Http/Router.php +++ /dev/null @@ -1,131 +0,0 @@ -currentPluginName; - } - - /** - * Get controller - * - * @access public - * @return string - */ - public function getController() - { - return $this->currentControllerName; - } - - /** - * Get action - * - * @access public - * @return string - */ - public function getAction() - { - return $this->currentActionName; - } - - /** - * Get the path to compare patterns - * - * @access public - * @return string - */ - public function getPath() - { - $path = substr($this->request->getUri(), strlen($this->helper->url->dir())); - - if ($this->request->getQueryString() !== '') { - $path = substr($path, 0, - strlen($this->request->getQueryString()) - 1); - } - - if ($path !== '' && $path{0} === '/') { - $path = substr($path, 1); - } - - return $path; - } - - /** - * Find controller/action from the route table or from get arguments - * - * @access public - */ - public function dispatch() - { - $controller = $this->request->getStringParam('controller'); - $action = $this->request->getStringParam('action'); - $plugin = $this->request->getStringParam('plugin'); - - if ($controller === '') { - $route = $this->route->findRoute($this->getPath()); - $controller = $route['controller']; - $action = $route['action']; - $plugin = $route['plugin']; - } - - $this->currentControllerName = ucfirst($this->sanitize($controller, self::DEFAULT_CONTROLLER)); - $this->currentActionName = $this->sanitize($action, self::DEFAULT_METHOD); - $this->currentPluginName = ucfirst($this->sanitize($plugin)); - } - - /** - * Check controller and action parameter - * - * @access public - * @param string $value - * @param string $default - * @return string - */ - public function sanitize($value, $default = '') - { - return preg_match('/^[a-zA-Z_0-9]+$/', $value) ? $value : $default; - } -} diff --git a/sources/app/Core/Ldap/Client.php b/sources/app/Core/Ldap/Client.php deleted file mode 100644 index 867d67f..0000000 --- a/sources/app/Core/Ldap/Client.php +++ /dev/null @@ -1,212 +0,0 @@ -open($client->getLdapServer()); - $username = $username ?: $client->getLdapUsername(); - $password = $password ?: $client->getLdapPassword(); - - if (empty($username) && empty($password)) { - $client->useAnonymousAuthentication(); - } else { - $client->authenticate($username, $password); - } - - return $client; - } - - /** - * Get server connection - * - * @access public - * @return resource - */ - public function getConnection() - { - return $this->ldap; - } - - /** - * Establish server connection - * - * @access public - * @throws ClientException - * @param string $server LDAP server hostname or IP - * @param integer $port LDAP port - * @param boolean $tls Start TLS - * @param boolean $verify Skip SSL certificate verification - * @return Client - */ - public function open($server, $port = LDAP_PORT, $tls = LDAP_START_TLS, $verify = LDAP_SSL_VERIFY) - { - if (! function_exists('ldap_connect')) { - throw new ClientException('LDAP: The PHP LDAP extension is required'); - } - - if (! $verify) { - putenv('LDAPTLS_REQCERT=never'); - } - - $this->ldap = ldap_connect($server, $port); - - if ($this->ldap === false) { - throw new ClientException('LDAP: Unable to connect to the LDAP server'); - } - - ldap_set_option($this->ldap, LDAP_OPT_PROTOCOL_VERSION, 3); - ldap_set_option($this->ldap, LDAP_OPT_REFERRALS, 0); - ldap_set_option($this->ldap, LDAP_OPT_NETWORK_TIMEOUT, 1); - ldap_set_option($this->ldap, LDAP_OPT_TIMELIMIT, 1); - - if ($tls && ! @ldap_start_tls($this->ldap)) { - throw new ClientException('LDAP: Unable to start TLS'); - } - - return $this; - } - - /** - * Anonymous authentication - * - * @access public - * @throws ClientException - * @return boolean - */ - public function useAnonymousAuthentication() - { - if (! @ldap_bind($this->ldap)) { - throw new ClientException('Unable to perform anonymous binding'); - } - - return true; - } - - /** - * Authentication with username/password - * - * @access public - * @throws ClientException - * @param string $bind_rdn - * @param string $bind_password - * @return boolean - */ - public function authenticate($bind_rdn, $bind_password) - { - if (! @ldap_bind($this->ldap, $bind_rdn, $bind_password)) { - throw new ClientException('LDAP authentication failure for "'.$bind_rdn.'"'); - } - - return true; - } - - /** - * Get LDAP server name - * - * @access public - * @return string - */ - public function getLdapServer() - { - if (! LDAP_SERVER) { - throw new LogicException('LDAP server not configured, check the parameter LDAP_SERVER'); - } - - return LDAP_SERVER; - } - - /** - * Get LDAP username (proxy auth) - * - * @access public - * @return string - */ - public function getLdapUsername() - { - return LDAP_USERNAME; - } - - /** - * Get LDAP password (proxy auth) - * - * @access public - * @return string - */ - public function getLdapPassword() - { - return LDAP_PASSWORD; - } - - /** - * Set logger - * - * @access public - * @param LoggerInterface $logger - * @return Client - */ - public function setLogger(LoggerInterface $logger) - { - $this->logger = $logger; - return $this; - } - - /** - * Get logger - * - * @access public - * @return LoggerInterface - */ - public function getLogger() - { - return $this->logger; - } - - /** - * Test if a logger is defined - * - * @access public - * @return boolean - */ - public function hasLogger() - { - return $this->logger !== null; - } -} diff --git a/sources/app/Core/Ldap/ClientException.php b/sources/app/Core/Ldap/ClientException.php deleted file mode 100644 index a0f9f84..0000000 --- a/sources/app/Core/Ldap/ClientException.php +++ /dev/null @@ -1,15 +0,0 @@ -entries = $entries; - } - - /** - * Get all entries - * - * @access public - * @return Entry[] - */ - public function getAll() - { - $entities = array(); - - if (! isset($this->entries['count'])) { - return $entities; - } - - for ($i = 0; $i < $this->entries['count']; $i++) { - $entities[] = new Entry($this->entries[$i]); - } - - return $entities; - } - - /** - * Get first entry - * - * @access public - * @return Entry - */ - public function getFirstEntry() - { - return new Entry(isset($this->entries[0]) ? $this->entries[0] : array()); - } -} diff --git a/sources/app/Core/Ldap/Entry.php b/sources/app/Core/Ldap/Entry.php deleted file mode 100644 index 0b99a58..0000000 --- a/sources/app/Core/Ldap/Entry.php +++ /dev/null @@ -1,91 +0,0 @@ -entry = $entry; - } - - /** - * Get all attribute values - * - * @access public - * @param string $attribute - * @return string[] - */ - public function getAll($attribute) - { - $attributes = array(); - - if (! isset($this->entry[$attribute]['count'])) { - return $attributes; - } - - for ($i = 0; $i < $this->entry[$attribute]['count']; $i++) { - $attributes[] = $this->entry[$attribute][$i]; - } - - return $attributes; - } - - /** - * Get first attribute value - * - * @access public - * @param string $attribute - * @param string $default - * @return string - */ - public function getFirstValue($attribute, $default = '') - { - return isset($this->entry[$attribute][0]) ? $this->entry[$attribute][0] : $default; - } - - /** - * Get entry distinguished name - * - * @access public - * @return string - */ - public function getDn() - { - return isset($this->entry['dn']) ? $this->entry['dn'] : ''; - } - - /** - * Return true if the given value exists in attribute list - * - * @access public - * @param string $attribute - * @param string $value - * @return boolean - */ - public function hasValue($attribute, $value) - { - $attributes = $this->getAll($attribute); - return in_array($value, $attributes); - } -} diff --git a/sources/app/Core/Ldap/Group.php b/sources/app/Core/Ldap/Group.php deleted file mode 100644 index e1f60ab..0000000 --- a/sources/app/Core/Ldap/Group.php +++ /dev/null @@ -1,130 +0,0 @@ -query = $query; - } - - /** - * Get groups - * - * @static - * @access public - * @param Client $client - * @param string $query - * @return LdapGroupProvider[] - */ - public static function getGroups(Client $client, $query) - { - $self = new static(new Query($client)); - return $self->find($query); - } - - /** - * Find groups - * - * @access public - * @param string $query - * @return array - */ - public function find($query) - { - $this->query->execute($this->getBasDn(), $query, $this->getAttributes()); - $groups = array(); - - if ($this->query->hasResult()) { - $groups = $this->build(); - } - - return $groups; - } - - /** - * Build groups list - * - * @access protected - * @return array - */ - protected function build() - { - $groups = array(); - - foreach ($this->query->getEntries()->getAll() as $entry) { - $groups[] = new LdapGroupProvider($entry->getDn(), $entry->getFirstValue($this->getAttributeName())); - } - - return $groups; - } - - /** - * Ge the list of attributes to fetch when reading the LDAP group entry - * - * Must returns array with index that start at 0 otherwise ldap_search returns a warning "Array initialization wrong" - * - * @access public - * @return array - */ - public function getAttributes() - { - return array_values(array_filter(array( - $this->getAttributeName(), - ))); - } - - /** - * Get LDAP group name attribute - * - * @access public - * @return string - */ - public function getAttributeName() - { - if (! LDAP_GROUP_ATTRIBUTE_NAME) { - throw new LogicException('LDAP full name attribute empty, check the parameter LDAP_GROUP_ATTRIBUTE_NAME'); - } - - return strtolower(LDAP_GROUP_ATTRIBUTE_NAME); - } - - /** - * Get LDAP group base DN - * - * @access public - * @return string - */ - public function getBasDn() - { - if (! LDAP_GROUP_BASE_DN) { - throw new LogicException('LDAP group base DN empty, check the parameter LDAP_GROUP_BASE_DN'); - } - - return LDAP_GROUP_BASE_DN; - } -} diff --git a/sources/app/Core/Ldap/Query.php b/sources/app/Core/Ldap/Query.php deleted file mode 100644 index 0f9abb5..0000000 --- a/sources/app/Core/Ldap/Query.php +++ /dev/null @@ -1,97 +0,0 @@ -client = $client; - } - - /** - * Execute query - * - * @access public - * @param string $baseDn - * @param string $filter - * @param array $attributes - * @return Query - */ - public function execute($baseDn, $filter, array $attributes) - { - if (DEBUG && $this->client->hasLogger()) { - $this->client->getLogger()->debug('BaseDN='.$baseDn); - $this->client->getLogger()->debug('Filter='.$filter); - $this->client->getLogger()->debug('Attributes='.implode(', ', $attributes)); - } - - $sr = ldap_search($this->client->getConnection(), $baseDn, $filter, $attributes); - if ($sr === false) { - return $this; - } - - $entries = ldap_get_entries($this->client->getConnection(), $sr); - if ($entries === false || count($entries) === 0 || $entries['count'] == 0) { - return $this; - } - - $this->entries = $entries; - - if (DEBUG && $this->client->hasLogger()) { - $this->client->getLogger()->debug('NbEntries='.$entries['count']); - } - - return $this; - } - - /** - * Return true if the query returned a result - * - * @access public - * @return boolean - */ - public function hasResult() - { - return ! empty($this->entries); - } - - /** - * Get LDAP Entries - * - * @access public - * @return Entries - */ - public function getEntries() - { - return new Entries($this->entries); - } -} diff --git a/sources/app/Core/Ldap/User.php b/sources/app/Core/Ldap/User.php deleted file mode 100644 index 4bc1f5f..0000000 --- a/sources/app/Core/Ldap/User.php +++ /dev/null @@ -1,344 +0,0 @@ -query = $query; - $this->group = $group; - } - - /** - * Get user profile - * - * @static - * @access public - * @param Client $client - * @param string $username - * @return LdapUserProvider - */ - public static function getUser(Client $client, $username) - { - $self = new static(new Query($client), new Group(new Query($client))); - return $self->find($self->getLdapUserPattern($username)); - } - - /** - * Find user - * - * @access public - * @param string $query - * @return LdapUserProvider - */ - public function find($query) - { - $this->query->execute($this->getBasDn(), $query, $this->getAttributes()); - $user = null; - - if ($this->query->hasResult()) { - $user = $this->build(); - } - - return $user; - } - - /** - * Get user groupIds (DN) - * - * 1) If configured, use memberUid and posixGroup - * 2) Otherwise, use memberOf - * - * @access protected - * @param Entry $entry - * @param string $username - * @return string[] - */ - protected function getGroups(Entry $entry, $username) - { - $groupIds = array(); - - if (! empty($username) && $this->group !== null && $this->hasGroupUserFilter()) { - $groups = $this->group->find(sprintf($this->getGroupUserFilter(), $username)); - - foreach ($groups as $group) { - $groupIds[] = $group->getExternalId(); - } - } else { - $groupIds = $entry->getAll($this->getAttributeGroup()); - } - - return $groupIds; - } - - /** - * Get role from LDAP groups - * - * Note: Do not touch the current role if groups are not configured - * - * @access protected - * @param string[] $groupIds - * @return string - */ - protected function getRole(array $groupIds) - { - if (! $this->hasGroupsConfigured()) { - return null; - } - - foreach ($groupIds as $groupId) { - $groupId = strtolower($groupId); - - if ($groupId === strtolower($this->getGroupAdminDn())) { - return Role::APP_ADMIN; - } elseif ($groupId === strtolower($this->getGroupManagerDn())) { - return Role::APP_MANAGER; - } - } - - return Role::APP_USER; - } - - /** - * Build user profile - * - * @access protected - * @return LdapUserProvider - */ - protected function build() - { - $entry = $this->query->getEntries()->getFirstEntry(); - $username = $entry->getFirstValue($this->getAttributeUsername()); - $groupIds = $this->getGroups($entry, $username); - - return new LdapUserProvider( - $entry->getDn(), - $username, - $entry->getFirstValue($this->getAttributeName()), - $entry->getFirstValue($this->getAttributeEmail()), - $this->getRole($groupIds), - $groupIds, - $entry->getFirstValue($this->getAttributePhoto()), - $entry->getFirstValue($this->getAttributeLanguage()) - ); - } - - /** - * Ge the list of attributes to fetch when reading the LDAP user entry - * - * Must returns array with index that start at 0 otherwise ldap_search returns a warning "Array initialization wrong" - * - * @access public - * @return array - */ - public function getAttributes() - { - return array_values(array_filter(array( - $this->getAttributeUsername(), - $this->getAttributeName(), - $this->getAttributeEmail(), - $this->getAttributeGroup(), - $this->getAttributePhoto(), - $this->getAttributeLanguage(), - ))); - } - - /** - * Get LDAP account id attribute - * - * @access public - * @return string - */ - public function getAttributeUsername() - { - if (! LDAP_USER_ATTRIBUTE_USERNAME) { - throw new LogicException('LDAP username attribute empty, check the parameter LDAP_USER_ATTRIBUTE_USERNAME'); - } - - return strtolower(LDAP_USER_ATTRIBUTE_USERNAME); - } - - /** - * Get LDAP user name attribute - * - * @access public - * @return string - */ - public function getAttributeName() - { - if (! LDAP_USER_ATTRIBUTE_FULLNAME) { - throw new LogicException('LDAP full name attribute empty, check the parameter LDAP_USER_ATTRIBUTE_FULLNAME'); - } - - return strtolower(LDAP_USER_ATTRIBUTE_FULLNAME); - } - - /** - * Get LDAP account email attribute - * - * @access public - * @return string - */ - public function getAttributeEmail() - { - if (! LDAP_USER_ATTRIBUTE_EMAIL) { - throw new LogicException('LDAP email attribute empty, check the parameter LDAP_USER_ATTRIBUTE_EMAIL'); - } - - return strtolower(LDAP_USER_ATTRIBUTE_EMAIL); - } - - /** - * Get LDAP account memberOf attribute - * - * @access public - * @return string - */ - public function getAttributeGroup() - { - return strtolower(LDAP_USER_ATTRIBUTE_GROUPS); - } - - /** - * Get LDAP profile photo attribute - * - * @access public - * @return string - */ - public function getAttributePhoto() - { - return strtolower(LDAP_USER_ATTRIBUTE_PHOTO); - } - - /** - * Get LDAP language attribute - * - * @access public - * @return string - */ - public function getAttributeLanguage() - { - return strtolower(LDAP_USER_ATTRIBUTE_LANGUAGE); - } - - /** - * Get LDAP Group User filter - * - * @access public - * @return string - */ - public function getGroupUserFilter() - { - return LDAP_GROUP_USER_FILTER; - } - - /** - * Return true if LDAP Group User filter is defined - * - * @access public - * @return string - */ - public function hasGroupUserFilter() - { - return $this->getGroupUserFilter() !== '' && $this->getGroupUserFilter() !== null; - } - - /** - * Return true if LDAP Group mapping are configured - * - * @access public - * @return boolean - */ - public function hasGroupsConfigured() - { - return $this->getGroupAdminDn() || $this->getGroupManagerDn(); - } - - /** - * Get LDAP admin group DN - * - * @access public - * @return string - */ - public function getGroupAdminDn() - { - return strtolower(LDAP_GROUP_ADMIN_DN); - } - - /** - * Get LDAP application manager group DN - * - * @access public - * @return string - */ - public function getGroupManagerDn() - { - return LDAP_GROUP_MANAGER_DN; - } - - /** - * Get LDAP user base DN - * - * @access public - * @return string - */ - public function getBasDn() - { - if (! LDAP_USER_BASE_DN) { - throw new LogicException('LDAP user base DN empty, check the parameter LDAP_USER_BASE_DN'); - } - - return LDAP_USER_BASE_DN; - } - - /** - * Get LDAP user pattern - * - * @access public - * @param string $username - * @param string $filter - * @return string - */ - public function getLdapUserPattern($username, $filter = LDAP_USER_FILTER) - { - if (! $filter) { - throw new LogicException('LDAP user filter empty, check the parameter LDAP_USER_FILTER'); - } - - return str_replace('%s', $username, $filter); - } -} diff --git a/sources/app/Core/Mail/Client.php b/sources/app/Core/Mail/Client.php deleted file mode 100644 index ee3bdea..0000000 --- a/sources/app/Core/Mail/Client.php +++ /dev/null @@ -1,117 +0,0 @@ -transports = new Container; - } - - /** - * Send a HTML email - * - * @access public - * @param string $email - * @param string $name - * @param string $subject - * @param string $html - * @return Client - */ - public function send($email, $name, $subject, $html) - { - if (! empty($email)) { - $this->queueManager->push(EmailJob::getInstance($this->container) - ->withParams($email, $name, $subject, $html, $this->getAuthor()) - ); - } - - return $this; - } - - /** - * Get email author - * - * @access public - * @return string - */ - public function getAuthor() - { - $author = 'Kanboard'; - - if ($this->userSession->isLogged()) { - $author = e('%s via Kanboard', $this->helper->user->getFullname()); - } - - return $author; - } - - /** - * Get mail transport instance - * - * @access public - * @param string $transport - * @return ClientInterface - */ - public function getTransport($transport) - { - return $this->transports[$transport]; - } - - /** - * Add a new mail transport - * - * @access public - * @param string $transport - * @param string $class - * @return Client - */ - public function setTransport($transport, $class) - { - $container = $this->container; - - $this->transports[$transport] = function () use ($class, $container) { - return new $class($container); - }; - - return $this; - } - - /** - * Return the list of registered transports - * - * @access public - * @return array - */ - public function getAvailableTransports() - { - $availableTransports = $this->transports->keys(); - return array_combine($availableTransports, $availableTransports); - } -} diff --git a/sources/app/Core/Mail/ClientInterface.php b/sources/app/Core/Mail/ClientInterface.php deleted file mode 100644 index 66263a9..0000000 --- a/sources/app/Core/Mail/ClientInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -setSubject($subject) - ->setFrom(array($this->helper->mail->getMailSenderAddress() => $author)) - ->setBody($html, 'text/html') - ->setTo(array($email => $name)); - - Swift_Mailer::newInstance($this->getTransport())->send($message); - } catch (Swift_TransportException $e) { - $this->logger->error($e->getMessage()); - } - } - - /** - * Get SwiftMailer transport - * - * @access protected - * @return \Swift_Transport|\Swift_MailTransport|\Swift_SmtpTransport|\Swift_SendmailTransport - */ - protected function getTransport() - { - return Swift_MailTransport::newInstance(); - } -} diff --git a/sources/app/Core/Mail/Transport/Sendmail.php b/sources/app/Core/Mail/Transport/Sendmail.php deleted file mode 100644 index 039be70..0000000 --- a/sources/app/Core/Mail/Transport/Sendmail.php +++ /dev/null @@ -1,25 +0,0 @@ -setUsername(MAIL_SMTP_USERNAME); - $transport->setPassword(MAIL_SMTP_PASSWORD); - $transport->setEncryption(MAIL_SMTP_ENCRYPTION); - - return $transport; - } -} diff --git a/sources/app/Core/Markdown.php b/sources/app/Core/Markdown.php deleted file mode 100644 index b5abe5e..0000000 --- a/sources/app/Core/Markdown.php +++ /dev/null @@ -1,141 +0,0 @@ -isPublicLink = $isPublicLink; - $this->container = $container; - $this->InlineTypes['#'][] = 'TaskLink'; - $this->InlineTypes['@'][] = 'UserLink'; - $this->inlineMarkerList .= '#@'; - } - - /** - * Handle Task Links - * - * Replace "#123" by a link to the task - * - * @access public - * @param array $Excerpt - * @return array|null - */ - protected function inlineTaskLink(array $Excerpt) - { - if (preg_match('!#(\d+)!i', $Excerpt['text'], $matches)) { - $link = $this->buildTaskLink($matches[1]); - - if (! empty($link)) { - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'a', - 'text' => $matches[0], - 'attributes' => array('href' => $link), - ), - ); - } - } - - return null; - } - - /** - * Handle User Mentions - * - * Replace "@username" by a link to the user - * - * @access public - * @param array $Excerpt - * @return array|null - */ - protected function inlineUserLink(array $Excerpt) - { - if (! $this->isPublicLink && preg_match('/^@([^\s]+)/', $Excerpt['text'], $matches)) { - $user_id = $this->container['userModel']->getIdByUsername($matches[1]); - - if (! empty($user_id)) { - $url = $this->container['helper']->url->href('UserViewController', 'profile', array('user_id' => $user_id)); - - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'a', - 'text' => $matches[0], - 'attributes' => array('href' => $url, 'class' => 'user-mention-link'), - ), - ); - } - } - - return null; - } - - /** - * Build task link - * - * @access private - * @param integer $task_id - * @return string - */ - private function buildTaskLink($task_id) - { - if ($this->isPublicLink) { - $token = $this->container['memoryCache']->proxy($this->container['taskFinderModel'], 'getProjectToken', $task_id); - - if (! empty($token)) { - return $this->container['helper']->url->href( - 'TaskViewController', - 'readonly', - array( - 'token' => $token, - 'task_id' => $task_id, - ) - ); - } - - return ''; - } - - return $this->container['helper']->url->href( - 'TaskViewController', - 'show', - array('task_id' => $task_id) - ); - } -} diff --git a/sources/app/Core/Notification/NotificationInterface.php b/sources/app/Core/Notification/NotificationInterface.php deleted file mode 100644 index d336983..0000000 --- a/sources/app/Core/Notification/NotificationInterface.php +++ /dev/null @@ -1,32 +0,0 @@ -path = $path; - } - - /** - * Fetch object contents - * - * @access public - * @throws ObjectStorageException - * @param string $key - * @return string - */ - public function get($key) - { - $filename = $this->path.DIRECTORY_SEPARATOR.$key; - - if (! file_exists($filename)) { - throw new ObjectStorageException('File not found: '.$filename); - } - - return file_get_contents($filename); - } - - /** - * Save object - * - * @access public - * @throws ObjectStorageException - * @param string $key - * @param string $blob - */ - public function put($key, &$blob) - { - $this->createFolder($key); - - if (file_put_contents($this->path.DIRECTORY_SEPARATOR.$key, $blob) === false) { - throw new ObjectStorageException('Unable to write the file: '.$this->path.DIRECTORY_SEPARATOR.$key); - } - } - - /** - * Output directly object content - * - * @access public - * @throws ObjectStorageException - * @param string $key - */ - public function output($key) - { - $filename = $this->path.DIRECTORY_SEPARATOR.$key; - - if (! file_exists($filename)) { - throw new ObjectStorageException('File not found: '.$filename); - } - - readfile($filename); - } - - /** - * Move local file to object storage - * - * @access public - * @throws ObjectStorageException - * @param string $src_filename - * @param string $key - * @return boolean - */ - public function moveFile($src_filename, $key) - { - $this->createFolder($key); - $dst_filename = $this->path.DIRECTORY_SEPARATOR.$key; - - if (! rename($src_filename, $dst_filename)) { - throw new ObjectStorageException('Unable to move the file: '.$src_filename.' to '.$dst_filename); - } - - return true; - } - - /** - * Move uploaded file to object storage - * - * @access public - * @param string $filename - * @param string $key - * @return boolean - */ - public function moveUploadedFile($filename, $key) - { - $this->createFolder($key); - return move_uploaded_file($filename, $this->path.DIRECTORY_SEPARATOR.$key); - } - - /** - * Remove object - * - * @access public - * @param string $key - * @return boolean - */ - public function remove($key) - { - $filename = $this->path.DIRECTORY_SEPARATOR.$key; - - if (file_exists($filename)) { - return unlink($filename); - } - - return false; - } - - /** - * Create object folder - * - * @access private - * @throws ObjectStorageException - * @param string $key - */ - private function createFolder($key) - { - $folder = strpos($key, DIRECTORY_SEPARATOR) !== false ? $this->path.DIRECTORY_SEPARATOR.dirname($key) : $this->path; - - if (! is_dir($folder) && ! mkdir($folder, 0755, true)) { - throw new ObjectStorageException('Unable to create folder: '.$folder); - } - } -} diff --git a/sources/app/Core/ObjectStorage/ObjectStorageException.php b/sources/app/Core/ObjectStorage/ObjectStorageException.php deleted file mode 100644 index 9e98ff5..0000000 --- a/sources/app/Core/ObjectStorage/ObjectStorageException.php +++ /dev/null @@ -1,9 +0,0 @@ -container = $container; - } - - /** - * Set a PicoDb query - * - * @access public - * @param \PicoDb\Table - * @return Paginator - */ - public function setQuery(Table $query) - { - $this->query = $query; - $this->total = $this->query->count(); - return $this; - } - - /** - * Execute a PicoDb query - * - * @access public - * @return array - */ - public function executeQuery() - { - if ($this->query !== null) { - return $this->query - ->offset($this->offset) - ->limit($this->limit) - ->orderBy($this->order, $this->direction) - ->findAll(); - } - - return array(); - } - - /** - * Set url parameters - * - * @access public - * @param string $controller - * @param string $action - * @param array $params - * @return Paginator - */ - public function setUrl($controller, $action, array $params = array()) - { - $this->controller = $controller; - $this->action = $action; - $this->params = $params; - return $this; - } - - /** - * Add manually items - * - * @access public - * @param array $items - * @return Paginator - */ - public function setCollection(array $items) - { - $this->items = $items; - return $this; - } - - /** - * Return the items - * - * @access public - * @return array - */ - public function getCollection() - { - return $this->items ?: $this->executeQuery(); - } - - /** - * Set the total number of items - * - * @access public - * @param integer $total - * @return Paginator - */ - public function setTotal($total) - { - $this->total = $total; - return $this; - } - - /** - * Get the total number of items - * - * @access public - * @return integer - */ - public function getTotal() - { - return $this->total; - } - - /** - * Set the default page number - * - * @access public - * @param integer $page - * @return Paginator - */ - public function setPage($page) - { - $this->page = $page; - return $this; - } - - /** - * Set the default column order - * - * @access public - * @param string $order - * @return Paginator - */ - public function setOrder($order) - { - $this->order = $order; - return $this; - } - - /** - * Set the default sorting direction - * - * @access public - * @param string $direction - * @return Paginator - */ - public function setDirection($direction) - { - $this->direction = $direction; - return $this; - } - - /** - * Set the maximum number of items per page - * - * @access public - * @param integer $limit - * @return Paginator - */ - public function setMax($limit) - { - $this->limit = $limit; - return $this; - } - - /** - * Return true if the collection is empty - * - * @access public - * @return boolean - */ - public function isEmpty() - { - return $this->total === 0; - } - - /** - * Execute the offset calculation only if the $condition is true - * - * @access public - * @param boolean $condition - * @return Paginator - */ - public function calculateOnlyIf($condition) - { - if ($condition) { - $this->calculate(); - } - - return $this; - } - - /** - * Calculate the offset value accoring to url params and the page number - * - * @access public - * @return Paginator - */ - public function calculate() - { - $this->page = $this->container['request']->getIntegerParam('page', 1); - $this->direction = $this->container['request']->getStringParam('direction', $this->direction); - $this->order = $this->container['request']->getStringParam('order', $this->order); - - if ($this->page < 1) { - $this->page = 1; - } - - $this->offset = (int) (($this->page - 1) * $this->limit); - - return $this; - } - - /** - * Get url params for link generation - * - * @access public - * @param integer $page - * @param string $order - * @param string $direction - * @return string - */ - public function getUrlParams($page, $order, $direction) - { - $params = array( - 'page' => $page, - 'order' => $order, - 'direction' => $direction, - ); - - return array_merge($this->params, $params); - } - - /** - * Generate the previous link - * - * @access public - * @return string - */ - public function generatePreviousLink() - { - $html = ''; - - if ($this->offset > 0) { - $html .= $this->container['helper']->url->link( - '← '.t('Previous'), - $this->controller, - $this->action, - $this->getUrlParams($this->page - 1, $this->order, $this->direction) - ); - } else { - $html .= '← '.t('Previous'); - } - - $html .= ''; - - return $html; - } - - /** - * Generate the next link - * - * @access public - * @return string - */ - public function generateNextLink() - { - $html = ''; - - if (($this->total - $this->offset) > $this->limit) { - $html .= $this->container['helper']->url->link( - t('Next').' →', - $this->controller, - $this->action, - $this->getUrlParams($this->page + 1, $this->order, $this->direction) - ); - } else { - $html .= t('Next').' →'; - } - - $html .= ''; - - return $html; - } - - /** - * Return true if there is no pagination to show - * - * @access public - * @return boolean - */ - public function hasNothingtoShow() - { - return $this->offset === 0 && ($this->total - $this->offset) <= $this->limit; - } - - /** - * Generation pagination links - * - * @access public - * @return string - */ - public function toHtml() - { - $html = ''; - - if (! $this->hasNothingtoShow()) { - $html .= ''; - } - - return $html; - } - - /** - * Magic method to output pagination links - * - * @access public - * @return string - */ - public function __toString() - { - return $this->toHtml(); - } - - /** - * Column sorting - * - * @param string $label Column title - * @param string $column SQL column name - * @return string - */ - public function order($label, $column) - { - $prefix = ''; - $direction = 'ASC'; - - if ($this->order === $column) { - $prefix = $this->direction === 'DESC' ? '▼ ' : '▲ '; - $direction = $this->direction === 'DESC' ? 'ASC' : 'DESC'; - } - - return $prefix.$this->container['helper']->url->link( - $label, - $this->controller, - $this->action, - $this->getUrlParams($this->page, $column, $direction) - ); - } -} diff --git a/sources/app/Core/Plugin/Base.php b/sources/app/Core/Plugin/Base.php deleted file mode 100644 index 9d8167a..0000000 --- a/sources/app/Core/Plugin/Base.php +++ /dev/null @@ -1,134 +0,0 @@ -container['cspRules'] = $rules; - } - - /** - * Returns all classes that needs to be stored in the DI container - * - * @access public - * @return array - */ - public function getClasses() - { - return array(); - } - - /** - * Returns all helper classes that needs to be stored in the DI container - * - * @access public - * @return array - */ - public function getHelpers() - { - return array(); - } - - /** - * Listen on internal events - * - * @access public - * @param string $event - * @param callable $callback - */ - public function on($event, $callback) - { - $container = $this->container; - - $this->dispatcher->addListener($event, function () use ($container, $callback) { - call_user_func($callback, $container); - }); - } - - /** - * Get plugin name - * - * This method should be overridden by your Plugin class - * - * @access public - * @return string - */ - public function getPluginName() - { - return ucfirst(substr(get_called_class(), 16, -7)); - } - - /** - * Get plugin description - * - * This method should be overridden by your Plugin class - * - * @access public - * @return string - */ - public function getPluginDescription() - { - return ''; - } - - /** - * Get plugin author - * - * This method should be overridden by your Plugin class - * - * @access public - * @return string - */ - public function getPluginAuthor() - { - return '?'; - } - - /** - * Get plugin version - * - * This method should be overridden by your Plugin class - * - * @access public - * @return string - */ - public function getPluginVersion() - { - return '?'; - } - - /** - * Get plugin homepage - * - * This method should be overridden by your Plugin class - * - * @access public - * @return string - */ - public function getPluginHomepage() - { - return ''; - } -} diff --git a/sources/app/Core/Plugin/Directory.php b/sources/app/Core/Plugin/Directory.php deleted file mode 100644 index 21f11ca..0000000 --- a/sources/app/Core/Plugin/Directory.php +++ /dev/null @@ -1,56 +0,0 @@ -httpClient->getJson($url); - $plugins = array_filter($plugins, array($this, 'isCompatible')); - $plugins = array_filter($plugins, array($this, 'isInstallable')); - return $plugins; - } - - /** - * Filter plugins - * - * @param array $plugin - * @param string $appVersion - * @return bool - */ - public function isCompatible(array $plugin, $appVersion = APP_VERSION) - { - if (strpos($appVersion, 'master') !== false) { - return true; - } - - return $plugin['compatible_version'] === $appVersion; - } - - /** - * Filter plugins - * - * @param array $plugin - * @return bool - */ - public function isInstallable(array $plugin) - { - return $plugin['remote_install']; - } -} diff --git a/sources/app/Core/Plugin/Hook.php b/sources/app/Core/Plugin/Hook.php deleted file mode 100644 index ade6915..0000000 --- a/sources/app/Core/Plugin/Hook.php +++ /dev/null @@ -1,99 +0,0 @@ -hooks[$hook])) { - $this->hooks[$hook] = array(); - } - - $this->hooks[$hook][] = $value; - } - - /** - * Get all bindings for a hook - * - * @access public - * @param string $hook - * @return array - */ - public function getListeners($hook) - { - return isset($this->hooks[$hook]) ? $this->hooks[$hook] : array(); - } - - /** - * Return true if the hook is used - * - * @access public - * @param string $hook - * @return boolean - */ - public function exists($hook) - { - return isset($this->hooks[$hook]); - } - - /** - * Merge listener results with input array - * - * @access public - * @param string $hook - * @param array $values - * @param array $params - * @return array - */ - public function merge($hook, array &$values, array $params = array()) - { - foreach ($this->getListeners($hook) as $listener) { - $result = call_user_func_array($listener, $params); - - if (is_array($result) && ! empty($result)) { - $values = array_merge($values, $result); - } - } - - return $values; - } - - /** - * Execute only first listener - * - * @access public - * @param string $hook - * @param array $params - * @return mixed - */ - public function first($hook, array $params = array()) - { - foreach ($this->getListeners($hook) as $listener) { - return call_user_func_array($listener, $params); - } - - return null; - } -} diff --git a/sources/app/Core/Plugin/Installer.php b/sources/app/Core/Plugin/Installer.php deleted file mode 100644 index 48c4d97..0000000 --- a/sources/app/Core/Plugin/Installer.php +++ /dev/null @@ -1,162 +0,0 @@ -downloadPluginArchive($archiveUrl); - - if (! $zip->extractTo(PLUGINS_DIR)) { - $this->cleanupArchive($zip); - throw new PluginInstallerException(t('Unable to extract plugin archive.')); - } - - $this->cleanupArchive($zip); - } - - /** - * Uninstall a plugin - * - * @access public - * @param string $pluginId - * @throws PluginInstallerException - */ - public function uninstall($pluginId) - { - $pluginFolder = PLUGINS_DIR.DIRECTORY_SEPARATOR.basename($pluginId); - - if (! file_exists($pluginFolder)) { - throw new PluginInstallerException(t('Plugin not found.')); - } - - if (! is_writable($pluginFolder)) { - throw new PluginInstallerException(e('You don\'t have the permission to remove this plugin.')); - } - - $this->removeAllDirectories($pluginFolder); - } - - /** - * Update a plugin - * - * @access public - * @param string $archiveUrl - * @throws PluginInstallerException - */ - public function update($archiveUrl) - { - $zip = $this->downloadPluginArchive($archiveUrl); - - $firstEntry = $zip->statIndex(0); - $this->uninstall($firstEntry['name']); - - if (! $zip->extractTo(PLUGINS_DIR)) { - $this->cleanupArchive($zip); - throw new PluginInstallerException(t('Unable to extract plugin archive.')); - } - - $this->cleanupArchive($zip); - } - - /** - * Download archive from URL - * - * @access protected - * @param string $archiveUrl - * @return ZipArchive - * @throws PluginInstallerException - */ - protected function downloadPluginArchive($archiveUrl) - { - $zip = new ZipArchive(); - $archiveData = $this->httpClient->get($archiveUrl); - $archiveFile = tempnam(sys_get_temp_dir(), 'kb_plugin'); - - if (empty($archiveData)) { - unlink($archiveFile); - throw new PluginInstallerException(t('Unable to download plugin archive.')); - } - - if (file_put_contents($archiveFile, $archiveData) === false) { - unlink($archiveFile); - throw new PluginInstallerException(t('Unable to write temporary file for plugin.')); - } - - if ($zip->open($archiveFile) !== true) { - unlink($archiveFile); - throw new PluginInstallerException(t('Unable to open plugin archive.')); - } - - if ($zip->numFiles === 0) { - unlink($archiveFile); - throw new PluginInstallerException(t('There is no file in the plugin archive.')); - } - - return $zip; - } - - /** - * Remove archive file - * - * @access protected - * @param ZipArchive $zip - */ - protected function cleanupArchive(ZipArchive $zip) - { - unlink($zip->filename); - $zip->close(); - } - - /** - * Remove recursively a directory - * - * @access protected - * @param string $directory - */ - protected function removeAllDirectories($directory) - { - $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS); - $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); - - foreach ($files as $file) { - if ($file->isDir()) { - rmdir($file->getRealPath()); - } else { - unlink($file->getRealPath()); - } - } - - rmdir($directory); - } -} diff --git a/sources/app/Core/Plugin/Loader.php b/sources/app/Core/Plugin/Loader.php deleted file mode 100644 index f2f6add..0000000 --- a/sources/app/Core/Plugin/Loader.php +++ /dev/null @@ -1,113 +0,0 @@ -plugins; - } - - /** - * Scan plugin folder and load plugins - * - * @access public - */ - public function scan() - { - if (file_exists(PLUGINS_DIR)) { - $loader = new ClassLoader(); - $loader->addPsr4('Kanboard\Plugin\\', PLUGINS_DIR); - $loader->register(); - - $dir = new DirectoryIterator(PLUGINS_DIR); - - foreach ($dir as $fileInfo) { - if ($fileInfo->isDir() && substr($fileInfo->getFilename(), 0, 1) !== '.') { - $pluginName = $fileInfo->getFilename(); - $this->loadSchema($pluginName); - $this->initializePlugin($pluginName, $this->loadPlugin($pluginName)); - } - } - } - } - - /** - * Load plugin schema - * - * @access public - * @param string $pluginName - */ - public function loadSchema($pluginName) - { - if (SchemaHandler::hasSchema($pluginName)) { - $schemaHandler = new SchemaHandler($this->container); - $schemaHandler->loadSchema($pluginName); - } - } - - /** - * Load plugin - * - * @access public - * @throws LogicException - * @param string $pluginName - * @return Base - */ - public function loadPlugin($pluginName) - { - $className = '\Kanboard\Plugin\\'.$pluginName.'\\Plugin'; - - if (! class_exists($className)) { - throw new LogicException('Unable to load this plugin class '.$className); - } - - return new $className($this->container); - } - - /** - * Initialize plugin - * - * @access public - * @param string $pluginName - * @param Base $plugin - */ - public function initializePlugin($pluginName, Base $plugin) - { - if (method_exists($plugin, 'onStartup')) { - $this->dispatcher->addListener('app.bootstrap', array($plugin, 'onStartup')); - } - - Tool::buildDIC($this->container, $plugin->getClasses()); - Tool::buildDICHelpers($this->container, $plugin->getHelpers()); - - $plugin->initialize(); - $this->plugins[$pluginName] = $plugin; - } -} diff --git a/sources/app/Core/Plugin/PluginInstallerException.php b/sources/app/Core/Plugin/PluginInstallerException.php deleted file mode 100644 index 7d356c9..0000000 --- a/sources/app/Core/Plugin/PluginInstallerException.php +++ /dev/null @@ -1,15 +0,0 @@ -migrateSchema($pluginName); - } - - /** - * Execute plugin schema migrations - * - * @access public - * @param string $pluginName - */ - public function migrateSchema($pluginName) - { - $lastVersion = constant('\Kanboard\Plugin\\'.$pluginName.'\Schema\VERSION'); - $currentVersion = $this->getSchemaVersion($pluginName); - - try { - $this->db->startTransaction(); - $this->db->getDriver()->disableForeignKeys(); - - for ($i = $currentVersion + 1; $i <= $lastVersion; $i++) { - $functionName = '\Kanboard\Plugin\\'.$pluginName.'\Schema\version_'.$i; - - if (function_exists($functionName)) { - call_user_func($functionName, $this->db->getConnection()); - } - } - - $this->db->getDriver()->enableForeignKeys(); - $this->db->closeTransaction(); - $this->setSchemaVersion($pluginName, $i - 1); - } catch (PDOException $e) { - $this->db->cancelTransaction(); - $this->db->getDriver()->enableForeignKeys(); - throw new RuntimeException('Unable to migrate schema for the plugin: '.$pluginName.' => '.$e->getMessage()); - } - } - - /** - * Get current plugin schema version - * - * @access public - * @param string $plugin - * @return integer - */ - public function getSchemaVersion($plugin) - { - return (int) $this->db->table(self::TABLE_SCHEMA)->eq('plugin', strtolower($plugin))->findOneColumn('version'); - } - - /** - * Save last plugin schema version - * - * @access public - * @param string $plugin - * @param integer $version - * @return boolean - */ - public function setSchemaVersion($plugin, $version) - { - $dictionary = array( - strtolower($plugin) => $version - ); - - return $this->db->getDriver()->upsert(self::TABLE_SCHEMA, 'plugin', 'version', $dictionary); - } -} diff --git a/sources/app/Core/Queue/JobHandler.php b/sources/app/Core/Queue/JobHandler.php deleted file mode 100644 index 7ca3632..0000000 --- a/sources/app/Core/Queue/JobHandler.php +++ /dev/null @@ -1,70 +0,0 @@ - get_class($job), - 'params' => $job->getJobParams(), - 'user_id' => $this->userSession->getId(), - )); - } - - /** - * Execute a job - * - * @access public - * @param Job $job - */ - public function executeJob(Job $job) - { - $payload = $job->getBody(); - $className = $payload['class']; - $this->memoryCache->flush(); - $this->prepareJobSession($payload['user_id']); - - if (DEBUG) { - $this->logger->debug(__METHOD__.' Received job => '.$className.' ('.getmypid().')'); - } - - $worker = new $className($this->container); - call_user_func_array(array($worker, 'execute'), $payload['params']); - } - - /** - * Create the session for the job - * - * @access protected - * @param integer $user_id - */ - protected function prepareJobSession($user_id) - { - $session = array(); - $this->sessionStorage->setStorage($session); - - if ($user_id > 0) { - $user = $this->userModel->getById($user_id); - $this->userSession->initialize($user); - } - } -} diff --git a/sources/app/Core/Queue/QueueManager.php b/sources/app/Core/Queue/QueueManager.php deleted file mode 100644 index f34cb22..0000000 --- a/sources/app/Core/Queue/QueueManager.php +++ /dev/null @@ -1,71 +0,0 @@ -queue = $queue; - return $this; - } - - /** - * Send a new job to the queue - * - * @access public - * @param BaseJob $job - * @return $this - */ - public function push(BaseJob $job) - { - if ($this->queue !== null) { - $this->queue->push(JobHandler::getInstance($this->container)->serializeJob($job)); - } else { - call_user_func_array(array($job, 'execute'), $job->getJobParams()); - } - - return $this; - } - - /** - * Wait for new jobs - * - * @access public - * @throws LogicException - */ - public function listen() - { - if ($this->queue === null) { - throw new LogicException('No Queue Driver defined!'); - } - - while ($job = $this->queue->pull()) { - JobHandler::getInstance($this->container)->executeJob($job); - $this->queue->completed($job); - } - } -} diff --git a/sources/app/Core/Security/AccessMap.php b/sources/app/Core/Security/AccessMap.php deleted file mode 100644 index 2431a92..0000000 --- a/sources/app/Core/Security/AccessMap.php +++ /dev/null @@ -1,175 +0,0 @@ -defaultRole = $role; - return $this; - } - - /** - * Define role hierarchy - * - * @access public - * @param string $role - * @param array $subroles - * @return AccessMap - */ - public function setRoleHierarchy($role, array $subroles) - { - foreach ($subroles as $subrole) { - if (isset($this->hierarchy[$subrole])) { - $this->hierarchy[$subrole][] = $role; - } else { - $this->hierarchy[$subrole] = array($role); - } - } - - return $this; - } - - /** - * Get computed role hierarchy - * - * @access public - * @param string $role - * @return array - */ - public function getRoleHierarchy($role) - { - $roles = array($role); - - if (isset($this->hierarchy[$role])) { - $roles = array_merge($roles, $this->hierarchy[$role]); - } - - return $roles; - } - - /** - * Get the highest role from a list - * - * @access public - * @param array $roles - * @return string - */ - public function getHighestRole(array $roles) - { - $rank = array(); - - foreach ($roles as $role) { - $rank[$role] = count($this->getRoleHierarchy($role)); - } - - asort($rank); - - return key($rank); - } - - /** - * Add new access rules - * - * @access public - * @param string $controller Controller class name - * @param mixed $methods List of method name or just one method - * @param string $role Lowest role required - * @return AccessMap - */ - public function add($controller, $methods, $role) - { - if (is_array($methods)) { - foreach ($methods as $method) { - $this->addRule($controller, $method, $role); - } - } else { - $this->addRule($controller, $methods, $role); - } - - return $this; - } - - /** - * Add new access rule - * - * @access private - * @param string $controller - * @param string $method - * @param string $role - * @return AccessMap - */ - private function addRule($controller, $method, $role) - { - $controller = strtolower($controller); - $method = strtolower($method); - - if (! isset($this->map[$controller])) { - $this->map[$controller] = array(); - } - - $this->map[$controller][$method] = $role; - - return $this; - } - - /** - * Get roles that match the given controller/method - * - * @access public - * @param string $controller - * @param string $method - * @return array - */ - public function getRoles($controller, $method) - { - $controller = strtolower($controller); - $method = strtolower($method); - - foreach (array($method, '*') as $key) { - if (isset($this->map[$controller][$key])) { - return $this->getRoleHierarchy($this->map[$controller][$key]); - } - } - - return $this->getRoleHierarchy($this->defaultRole); - } -} diff --git a/sources/app/Core/Security/AuthenticationManager.php b/sources/app/Core/Security/AuthenticationManager.php deleted file mode 100644 index b1ba76c..0000000 --- a/sources/app/Core/Security/AuthenticationManager.php +++ /dev/null @@ -1,187 +0,0 @@ -providers[$provider->getName()] = $provider; - return $this; - } - - /** - * Register a new authentication provider - * - * @access public - * @param string $name - * @return AuthenticationProviderInterface|OAuthAuthenticationProviderInterface|PasswordAuthenticationProviderInterface|PreAuthenticationProviderInterface|OAuthAuthenticationProviderInterface - */ - public function getProvider($name) - { - if (! isset($this->providers[$name])) { - throw new LogicException('Authentication provider not found: '.$name); - } - - return $this->providers[$name]; - } - - /** - * Execute providers that are able to validate the current session - * - * @access public - * @return boolean - */ - public function checkCurrentSession() - { - if ($this->userSession->isLogged()) { - foreach ($this->filterProviders('SessionCheckProviderInterface') as $provider) { - if (! $provider->isValidSession()) { - $this->logger->debug('Invalidate session for '.$this->userSession->getUsername()); - $this->sessionStorage->flush(); - $this->preAuthentication(); - return false; - } - } - } - - return true; - } - - /** - * Execute pre-authentication providers - * - * @access public - * @return boolean - */ - public function preAuthentication() - { - foreach ($this->filterProviders('PreAuthenticationProviderInterface') as $provider) { - if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { - $this->dispatcher->dispatch(self::EVENT_SUCCESS, new AuthSuccessEvent($provider->getName())); - return true; - } - } - - return false; - } - - /** - * Execute username/password authentication providers - * - * @access public - * @param string $username - * @param string $password - * @param boolean $fireEvent - * @return boolean - */ - public function passwordAuthentication($username, $password, $fireEvent = true) - { - foreach ($this->filterProviders('PasswordAuthenticationProviderInterface') as $provider) { - $provider->setUsername($username); - $provider->setPassword($password); - - if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { - if ($fireEvent) { - $this->dispatcher->dispatch(self::EVENT_SUCCESS, new AuthSuccessEvent($provider->getName())); - } - - return true; - } - } - - if ($fireEvent) { - $this->dispatcher->dispatch(self::EVENT_FAILURE, new AuthFailureEvent($username)); - } - - return false; - } - - /** - * Perform OAuth2 authentication - * - * @access public - * @param string $name - * @return boolean - */ - public function oauthAuthentication($name) - { - $provider = $this->getProvider($name); - - if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { - $this->dispatcher->dispatch(self::EVENT_SUCCESS, new AuthSuccessEvent($provider->getName())); - return true; - } - - $this->dispatcher->dispatch(self::EVENT_FAILURE, new AuthFailureEvent); - - return false; - } - - /** - * Get the last Post-Authentication provider - * - * @access public - * @return PostAuthenticationProviderInterface - */ - public function getPostAuthenticationProvider() - { - $providers = $this->filterProviders('PostAuthenticationProviderInterface'); - - if (empty($providers)) { - throw new LogicException('You must have at least one Post-Authentication Provider configured'); - } - - return array_pop($providers); - } - - /** - * Filter registered providers by interface type - * - * @access private - * @param string $interface - * @return array - */ - private function filterProviders($interface) - { - $interface = '\Kanboard\Core\Security\\'.$interface; - - return array_filter($this->providers, function(AuthenticationProviderInterface $provider) use ($interface) { - return is_a($provider, $interface); - }); - } -} diff --git a/sources/app/Core/Security/AuthenticationProviderInterface.php b/sources/app/Core/Security/AuthenticationProviderInterface.php deleted file mode 100644 index 828e272..0000000 --- a/sources/app/Core/Security/AuthenticationProviderInterface.php +++ /dev/null @@ -1,28 +0,0 @@ -accessMap = $accessMap; - } - - /** - * Check if the given role is allowed to access to the specified resource - * - * @access public - * @param string $controller - * @param string $method - * @param string $role - * @return boolean - */ - public function isAllowed($controller, $method, $role) - { - $roles = $this->accessMap->getRoles($controller, $method); - return in_array($role, $roles); - } -} diff --git a/sources/app/Core/Security/OAuthAuthenticationProviderInterface.php b/sources/app/Core/Security/OAuthAuthenticationProviderInterface.php deleted file mode 100644 index 3092672..0000000 --- a/sources/app/Core/Security/OAuthAuthenticationProviderInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - t('Administrator'), - self::APP_MANAGER => t('Manager'), - self::APP_USER => t('User'), - ); - } - - /** - * Get project roles - * - * @access public - * @return array - */ - public function getProjectRoles() - { - return array( - self::PROJECT_MANAGER => t('Project Manager'), - self::PROJECT_MEMBER => t('Project Member'), - self::PROJECT_VIEWER => t('Project Viewer'), - ); - } - - /** - * Get role name - * - * @access public - * @param string $role - * @return string - */ - public function getRoleName($role) - { - $roles = $this->getApplicationRoles() + $this->getProjectRoles(); - return isset($roles[$role]) ? $roles[$role] : t('Unknown'); - } -} diff --git a/sources/app/Core/Security/SessionCheckProviderInterface.php b/sources/app/Core/Security/SessionCheckProviderInterface.php deleted file mode 100644 index 232fe1d..0000000 --- a/sources/app/Core/Security/SessionCheckProviderInterface.php +++ /dev/null @@ -1,20 +0,0 @@ -sessionStorage->csrf)) { - $this->sessionStorage->csrf = array(); - } - - $nonce = self::getToken(); - $this->sessionStorage->csrf[$nonce] = true; - - return $nonce; - } - - /** - * Check if the token exists for the current session (a token can be used only one time) - * - * @access public - * @param string $token CSRF token - * @return bool - */ - public function validateCSRFToken($token) - { - if (isset($this->sessionStorage->csrf[$token])) { - unset($this->sessionStorage->csrf[$token]); - return true; - } - - return false; - } -} diff --git a/sources/app/Core/Session/FlashMessage.php b/sources/app/Core/Session/FlashMessage.php deleted file mode 100644 index e02d056..0000000 --- a/sources/app/Core/Session/FlashMessage.php +++ /dev/null @@ -1,71 +0,0 @@ -setMessage('success', $message); - } - - /** - * Add failure message - * - * @access public - * @param string $message - */ - public function failure($message) - { - $this->setMessage('failure', $message); - } - - /** - * Add new flash message - * - * @access public - * @param string $key - * @param string $message - */ - public function setMessage($key, $message) - { - if (! isset($this->sessionStorage->flash)) { - $this->sessionStorage->flash = array(); - } - - $this->sessionStorage->flash[$key] = $message; - } - - /** - * Get flash message - * - * @access public - * @param string $key - * @return string - */ - public function getMessage($key) - { - $message = ''; - - if (isset($this->sessionStorage->flash[$key])) { - $message = $this->sessionStorage->flash[$key]; - unset($this->sessionStorage->flash[$key]); - } - - return $message; - } -} diff --git a/sources/app/Core/Session/SessionManager.php b/sources/app/Core/Session/SessionManager.php deleted file mode 100644 index 4f9f2c0..0000000 --- a/sources/app/Core/Session/SessionManager.php +++ /dev/null @@ -1,110 +0,0 @@ -configure(); - - if (ini_get('session.auto_start') == 1) { - session_destroy(); - } - - session_name('KB_SID'); - session_start(); - - $this->sessionStorage->setStorage($_SESSION); - } - - /** - * Destroy the session - * - * @access public - */ - public function close() - { - $this->dispatcher->dispatch(self::EVENT_DESTROY); - - // Destroy the session cookie - $params = session_get_cookie_params(); - - setcookie( - session_name(), - '', - time() - 42000, - $params['path'], - $params['domain'], - $params['secure'], - $params['httponly'] - ); - - session_unset(); - session_destroy(); - } - - /** - * Define session settings - * - * @access private - */ - private function configure() - { - // Session cookie: HttpOnly and secure flags - session_set_cookie_params( - SESSION_DURATION, - $this->helper->url->dir() ?: '/', - null, - $this->request->isHTTPS(), - true - ); - - // Avoid session id in the URL - ini_set('session.use_only_cookies', '1'); - ini_set('session.use_trans_sid', '0'); - - // Enable strict mode - ini_set('session.use_strict_mode', '1'); - - // Better session hash - ini_set('session.hash_function', '1'); // 'sha512' is not compatible with FreeBSD, only MD5 '0' and SHA-1 '1' seems to work - ini_set('session.hash_bits_per_character', 6); - - // Set an additional entropy - ini_set('session.entropy_file', '/dev/urandom'); - ini_set('session.entropy_length', '256'); - } -} diff --git a/sources/app/Core/Session/SessionStorage.php b/sources/app/Core/Session/SessionStorage.php deleted file mode 100644 index 9e93602..0000000 --- a/sources/app/Core/Session/SessionStorage.php +++ /dev/null @@ -1,91 +0,0 @@ -storage =& $storage; - - // Load dynamically existing session variables into object properties - foreach ($storage as $key => $value) { - $this->$key = $value; - } - } - - /** - * Get all session variables - * - * @access public - * @return array - */ - public function getAll() - { - $session = get_object_vars($this); - unset($session['storage']); - - return $session; - } - - /** - * Flush session data - * - * @access public - */ - public function flush() - { - $session = get_object_vars($this); - unset($session['storage']); - - foreach (array_keys($session) as $property) { - unset($this->$property); - } - } - - /** - * Copy class properties to external storage - * - * @access public - */ - public function __destruct() - { - $this->storage = $this->getAll(); - } -} diff --git a/sources/app/Core/Template.php b/sources/app/Core/Template.php deleted file mode 100644 index d3ec26d..0000000 --- a/sources/app/Core/Template.php +++ /dev/null @@ -1,124 +0,0 @@ -helper = $helper; - } - - /** - * Expose helpers with magic getter - * - * @access public - * @param string $helper - * @return mixed - */ - public function __get($helper) - { - return $this->helper->getHelper($helper); - } - - /** - * Render a template - * - * Example: - * - * $template->render('template_name', ['bla' => 'value']); - * - * @access public - * @param string $__template_name Template name - * @param array $__template_args Key/Value map of template variables - * @return string - */ - public function render($__template_name, array $__template_args = array()) - { - extract($__template_args); - ob_start(); - include $this->getTemplateFile($__template_name); - return ob_get_clean(); - } - - /** - * Define a new template override - * - * @access public - * @param string $original_template - * @param string $new_template - */ - public function setTemplateOverride($original_template, $new_template) - { - $this->overrides[$original_template] = $new_template; - } - - /** - * Find template filename - * - * Core template: 'task/show' or 'kanboard:task/show' - * Plugin template: 'myplugin:task/show' - * - * @access public - * @param string $template - * @return string - */ - public function getTemplateFile($template) - { - $plugin = ''; - $template = isset($this->overrides[$template]) ? $this->overrides[$template] : $template; - - if (strpos($template, ':') !== false) { - list($plugin, $template) = explode(':', $template); - } - - if ($plugin !== 'kanboard' && $plugin !== '') { - return implode(DIRECTORY_SEPARATOR, array(PLUGINS_DIR, ucfirst($plugin), 'Template', $template.'.php')); - } - - return implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'Template', $template.'.php')); - } -} diff --git a/sources/app/Core/Thumbnail.php b/sources/app/Core/Thumbnail.php deleted file mode 100644 index 733d3a3..0000000 --- a/sources/app/Core/Thumbnail.php +++ /dev/null @@ -1,172 +0,0 @@ -fromFile($filename); - return $self; - } - - /** - * Create a thumbnail from a string - * - * @static - * @access public - * @param string $blob - * @return Thumbnail - */ - public static function createFromString($blob) - { - $self = new static(); - $self->fromString($blob); - return $self; - } - - /** - * Load the local image file in memory with GD - * - * @access public - * @param string $filename - * @return Thumbnail - */ - public function fromFile($filename) - { - $this->metadata = getimagesize($filename); - $this->srcImage = imagecreatefromstring(file_get_contents($filename)); - return $this; - } - - /** - * Load the image blob in memory with GD - * - * @access public - * @param string $blob - * @return Thumbnail - */ - public function fromString($blob) - { - if (!function_exists('getimagesizefromstring')) { - $uri = 'data://application/octet-stream;base64,' . base64_encode($blob); - $this->metadata = getimagesize($uri); - } else { - $this->metadata = getimagesizefromstring($blob); - } - - $this->srcImage = imagecreatefromstring($blob); - return $this; - } - - /** - * Resize the image - * - * @access public - * @param int $width - * @param int $height - * @return Thumbnail - */ - public function resize($width = 250, $height = 100) - { - $srcWidth = $this->metadata[0]; - $srcHeight = $this->metadata[1]; - $dstX = 0; - $dstY = 0; - - if ($width == 0 && $height == 0) { - $width = 100; - $height = 100; - } - - if ($width > 0 && $height == 0) { - $dstWidth = $width; - $dstHeight = floor($srcHeight * ($width / $srcWidth)); - $this->dstImage = imagecreatetruecolor($dstWidth, $dstHeight); - } elseif ($width == 0 && $height > 0) { - $dstWidth = floor($srcWidth * ($height / $srcHeight)); - $dstHeight = $height; - $this->dstImage = imagecreatetruecolor($dstWidth, $dstHeight); - } else { - $srcRatio = $srcWidth / $srcHeight; - $resizeRatio = $width / $height; - - if ($srcRatio <= $resizeRatio) { - $dstWidth = $width; - $dstHeight = floor($srcHeight * ($width / $srcWidth)); - $dstY = ($dstHeight - $height) / 2 * (-1); - } else { - $dstWidth = floor($srcWidth * ($height / $srcHeight)); - $dstHeight = $height; - $dstX = ($dstWidth - $width) / 2 * (-1); - } - - $this->dstImage = imagecreatetruecolor($width, $height); - } - - imagecopyresampled($this->dstImage, $this->srcImage, $dstX, $dstY, 0, 0, $dstWidth, $dstHeight, $srcWidth, $srcHeight); - - return $this; - } - - /** - * Save the thumbnail to a local file - * - * @access public - * @param string $filename - * @return Thumbnail - */ - public function toFile($filename) - { - imagejpeg($this->dstImage, $filename); - imagedestroy($this->dstImage); - imagedestroy($this->srcImage); - return $this; - } - - /** - * Return the thumbnail as a string - * - * @access public - * @return string - */ - public function toString() - { - ob_start(); - imagejpeg($this->dstImage, null); - imagedestroy($this->dstImage); - imagedestroy($this->srcImage); - return ob_get_clean(); - } - - /** - * Output the thumbnail directly to the browser or stdout - * - * @access public - */ - public function toOutput() - { - imagejpeg($this->dstImage, null); - imagedestroy($this->dstImage); - imagedestroy($this->srcImage); - } -} diff --git a/sources/app/Core/Tool.php b/sources/app/Core/Tool.php deleted file mode 100644 index bfa6c95..0000000 --- a/sources/app/Core/Tool.php +++ /dev/null @@ -1,58 +0,0 @@ - $classes) { - foreach ($classes as $name) { - $class = '\\Kanboard\\'.$namespace.'\\'.$name; - $container[lcfirst($name)] = function ($c) use ($class) { - return new $class($c); - }; - } - } - - return $container; - } - - /** - * Build dependency injection container for custom helpers from an array - * - * @static - * @access public - * @param Container $container - * @param array $namespaces - * @return Container - */ - public static function buildDICHelpers(Container $container, array $namespaces) - { - foreach ($namespaces as $namespace => $classes) { - foreach ($classes as $name) { - $class = '\\Kanboard\\'.$namespace.'\\'.$name; - $container['helper']->register($name, $class); - } - } - - return $container; - } -} diff --git a/sources/app/Core/Translator.php b/sources/app/Core/Translator.php deleted file mode 100644 index 113c0dc..0000000 --- a/sources/app/Core/Translator.php +++ /dev/null @@ -1,193 +0,0 @@ -translate('I have %d kids', 5); - * - * @access public - * @param string $identifier Default string - * @return string - */ - public function translate($identifier) - { - $args = func_get_args(); - - array_shift($args); - array_unshift($args, $this->get($identifier, $identifier)); - - foreach ($args as &$arg) { - $arg = htmlspecialchars($arg, ENT_QUOTES, 'UTF-8', false); - } - - return call_user_func_array( - 'sprintf', - $args - ); - } - - /** - * Get a translation with no HTML escaping - * - * $translator->translateNoEscaping('I have %d kids', 5); - * - * @access public - * @param string $identifier Default string - * @return string - */ - public function translateNoEscaping($identifier) - { - $args = func_get_args(); - - array_shift($args); - array_unshift($args, $this->get($identifier, $identifier)); - - return call_user_func_array( - 'sprintf', - $args - ); - } - - /** - * Get a formatted number - * - * $translator->number(1234.56); - * - * @access public - * @param float $number Number to format - * @return string - */ - public function number($number) - { - return number_format( - $number, - $this->get('number.decimals', 2), - $this->get('number.decimals_separator', '.'), - $this->get('number.thousands_separator', ',') - ); - } - - /** - * Get a formatted currency number - * - * $translator->currency(1234.56); - * - * @access public - * @param float $amount Number to format - * @return string - */ - public function currency($amount) - { - $position = $this->get('currency.position', 'before'); - $symbol = $this->get('currency.symbol', '$'); - $str = ''; - - if ($position === 'before') { - $str .= $symbol; - } - - $str .= $this->number($amount); - - if ($position === 'after') { - $str .= ' '.$symbol; - } - - return $str; - } - - /** - * Get an identifier from the translations or return the default - * - * @access public - * @param string $identifier Locale identifier - * @param string $default Default value - * @return string - */ - public function get($identifier, $default = '') - { - if (isset(self::$locales[$identifier])) { - return self::$locales[$identifier]; - } else { - return $default; - } - } - - /** - * Load translations - * - * @static - * @access public - * @param string $language Locale code: fr_FR - * @param string $path Locale folder - */ - public static function load($language, $path = self::PATH) - { - $filename = $path.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'translations.php'; - - if (file_exists($filename)) { - self::$locales = array_merge(self::$locales, require($filename)); - } - } - - /** - * Clear locales stored in memory - * - * @static - * @access public - */ - public static function unload() - { - self::$locales = array(); - } -} diff --git a/sources/app/Core/User/Avatar/AvatarManager.php b/sources/app/Core/User/Avatar/AvatarManager.php deleted file mode 100644 index 5b61cbd..0000000 --- a/sources/app/Core/User/Avatar/AvatarManager.php +++ /dev/null @@ -1,93 +0,0 @@ -providers[] = $provider; - return $this; - } - - /** - * Render avatar HTML element - * - * @access public - * @param string $user_id - * @param string $username - * @param string $name - * @param string $email - * @param string $avatar_path - * @param int $size - * @return string - */ - public function render($user_id, $username, $name, $email, $avatar_path, $size) - { - $user = array( - 'id' => $user_id, - 'username' => $username, - 'name' => $name, - 'email' => $email, - 'avatar_path' => $avatar_path, - ); - - krsort($this->providers); - - foreach ($this->providers as $provider) { - if ($provider->isActive($user)) { - return $provider->render($user, $size); - } - } - - return ''; - } - - /** - * Render default provider for unknown users (first provider registered) - * - * @access public - * @param integer $size - * @return string - */ - public function renderDefault($size) - { - if (count($this->providers) > 0) { - ksort($this->providers); - $provider = current($this->providers); - - $user = array( - 'id' => 0, - 'username' => '', - 'name' => '?', - 'email' => '', - 'avatar_path' => '', - ); - - return $provider->render($user, $size); - } - - return ''; - } -} diff --git a/sources/app/Core/User/Avatar/AvatarProviderInterface.php b/sources/app/Core/User/Avatar/AvatarProviderInterface.php deleted file mode 100644 index e0375d2..0000000 --- a/sources/app/Core/User/Avatar/AvatarProviderInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -groupMemberModel->getGroups($userId); - $this->addGroups($userId, $userGroups, $externalGroupIds); - $this->removeGroups($userId, $userGroups, $externalGroupIds); - } - - /** - * Add missing groups to the user - * - * @access protected - * @param integer $userId - * @param array $userGroups - * @param array $externalGroupIds - */ - protected function addGroups($userId, array $userGroups, array $externalGroupIds) - { - $userGroupIds = array_column($userGroups, 'external_id', 'external_id'); - - foreach ($externalGroupIds as $externalGroupId) { - if (! isset($userGroupIds[$externalGroupId])) { - $group = $this->groupModel->getByExternalId($externalGroupId); - - if (! empty($group)) { - $this->groupMemberModel->addUser($group['id'], $userId); - } - } - } - } - - /** - * Remove groups from the user - * - * @access protected - * @param integer $userId - * @param array $userGroups - * @param array $externalGroupIds - */ - protected function removeGroups($userId, array $userGroups, array $externalGroupIds) - { - foreach ($userGroups as $userGroup) { - if (! empty($userGroup['external_id']) && ! in_array($userGroup['external_id'], $externalGroupIds)) { - $this->groupMemberModel->removeUser($userGroup['id'], $userId); - } - } - } -} diff --git a/sources/app/Core/User/UserProfile.php b/sources/app/Core/User/UserProfile.php deleted file mode 100644 index 8b9ebb7..0000000 --- a/sources/app/Core/User/UserProfile.php +++ /dev/null @@ -1,66 +0,0 @@ -userModel->getById($userId); - - $values = UserProperty::filterProperties($profile, UserProperty::getProperties($user)); - $values['id'] = $userId; - - if ($this->userModel->update($values)) { - $profile = array_merge($profile, $values); - $this->userSession->initialize($profile); - return true; - } - - return false; - } - - /** - * Synchronize user properties with the local database and create the user session - * - * @access public - * @param UserProviderInterface $user - * @return boolean - */ - public function initialize(UserProviderInterface $user) - { - if ($user->getInternalId()) { - $profile = $this->userModel->getById($user->getInternalId()); - } elseif ($user->getExternalIdColumn() && $user->getExternalId()) { - $profile = $this->userSync->synchronize($user); - $this->groupSync->synchronize($profile['id'], $user->getExternalGroupIds()); - } - - if (! empty($profile) && $profile['is_active'] == 1) { - $this->userSession->initialize($profile); - $this->dispatcher->dispatch(self::EVENT_USER_PROFILE_AFTER_SYNC, new UserProfileSyncEvent($profile, $user)); - return true; - } - - return false; - } -} diff --git a/sources/app/Core/User/UserProperty.php b/sources/app/Core/User/UserProperty.php deleted file mode 100644 index 348bd7f..0000000 --- a/sources/app/Core/User/UserProperty.php +++ /dev/null @@ -1,74 +0,0 @@ - $user->getUsername(), - 'name' => $user->getName(), - 'email' => $user->getEmail(), - 'role' => $user->getRole(), - $user->getExternalIdColumn() => $user->getExternalId(), - ); - - $properties = array_merge($properties, $user->getExtraAttributes()); - - return array_filter($properties, array(__NAMESPACE__.'\UserProperty', 'isNotEmptyValue')); - } - - /** - * Filter user properties compared to existing user profile - * - * @static - * @access public - * @param array $profile - * @param array $properties - * @return array - */ - public static function filterProperties(array $profile, array $properties) - { - $excludedProperties = array('username'); - $values = array(); - - foreach ($properties as $property => $value) { - if (self::isNotEmptyValue($value) && - ! in_array($property, $excludedProperties) && - array_key_exists($property, $profile) && - $value !== $profile[$property]) { - $values[$property] = $value; - } - } - - return $values; - } - - /** - * Check if a value is not empty - * - * @static - * @access public - * @param string $value - * @return boolean - */ - public static function isNotEmptyValue($value) - { - return $value !== null && $value !== ''; - } -} diff --git a/sources/app/Core/User/UserProviderInterface.php b/sources/app/Core/User/UserProviderInterface.php deleted file mode 100644 index 07e01f4..0000000 --- a/sources/app/Core/User/UserProviderInterface.php +++ /dev/null @@ -1,103 +0,0 @@ -getId() == $user_id) { - $this->initialize($this->userModel->getById($user_id)); - } - } - - /** - * Update user session - * - * @access public - * @param array $user - */ - public function initialize(array $user) - { - foreach (array('password', 'is_admin', 'is_project_admin', 'twofactor_secret') as $column) { - if (isset($user[$column])) { - unset($user[$column]); - } - } - - $user['id'] = (int) $user['id']; - $user['is_ldap_user'] = isset($user['is_ldap_user']) ? (bool) $user['is_ldap_user'] : false; - $user['twofactor_activated'] = isset($user['twofactor_activated']) ? (bool) $user['twofactor_activated'] : false; - - $this->sessionStorage->user = $user; - $this->sessionStorage->postAuthenticationValidated = false; - } - - /** - * Get user properties - * - * @access public - * @return array - */ - public function getAll() - { - return $this->sessionStorage->user; - } - - /** - * Get user application role - * - * @access public - * @return string - */ - public function getRole() - { - return $this->sessionStorage->user['role']; - } - - /** - * Return true if the user has validated the 2FA key - * - * @access public - * @return bool - */ - public function isPostAuthenticationValidated() - { - return isset($this->sessionStorage->postAuthenticationValidated) && $this->sessionStorage->postAuthenticationValidated === true; - } - - /** - * Validate 2FA for the current session - * - * @access public - */ - public function validatePostAuthentication() - { - $this->sessionStorage->postAuthenticationValidated = true; - } - - /** - * Return true if the user has 2FA enabled - * - * @access public - * @return bool - */ - public function hasPostAuthentication() - { - return isset($this->sessionStorage->user['twofactor_activated']) && $this->sessionStorage->user['twofactor_activated'] === true; - } - - /** - * Disable 2FA for the current session - * - * @access public - */ - public function disablePostAuthentication() - { - $this->sessionStorage->user['twofactor_activated'] = false; - } - - /** - * Return true if the logged user is admin - * - * @access public - * @return bool - */ - public function isAdmin() - { - return isset($this->sessionStorage->user['role']) && $this->sessionStorage->user['role'] === Role::APP_ADMIN; - } - - /** - * Get the connected user id - * - * @access public - * @return integer - */ - public function getId() - { - return isset($this->sessionStorage->user['id']) ? (int) $this->sessionStorage->user['id'] : 0; - } - - /** - * Get username - * - * @access public - * @return string - */ - public function getUsername() - { - return isset($this->sessionStorage->user['username']) ? $this->sessionStorage->user['username'] : ''; - } - - /** - * Check is the user is connected - * - * @access public - * @return bool - */ - public function isLogged() - { - return isset($this->sessionStorage->user) && ! empty($this->sessionStorage->user); - } - - /** - * Get project filters from the session - * - * @access public - * @param integer $project_id - * @return string - */ - public function getFilters($project_id) - { - return ! empty($this->sessionStorage->filters[$project_id]) ? $this->sessionStorage->filters[$project_id] : 'status:open'; - } - - /** - * Save project filters in the session - * - * @access public - * @param integer $project_id - * @param string $filters - */ - public function setFilters($project_id, $filters) - { - $this->sessionStorage->filters[$project_id] = $filters; - } - - /** - * Is board collapsed or expanded - * - * @access public - * @param integer $project_id - * @return boolean - */ - public function isBoardCollapsed($project_id) - { - return ! empty($this->sessionStorage->boardCollapsed[$project_id]) ? $this->sessionStorage->boardCollapsed[$project_id] : false; - } - - /** - * Set board display mode - * - * @access public - * @param integer $project_id - * @param boolean $is_collapsed - */ - public function setBoardDisplayMode($project_id, $is_collapsed) - { - $this->sessionStorage->boardCollapsed[$project_id] = $is_collapsed; - } - - /** - * Set comments sorting - * - * @access public - * @param string $order - */ - public function setCommentSorting($order) - { - $this->sessionStorage->commentSorting = $order; - } - - /** - * Get comments sorting direction - * - * @access public - * @return string - */ - public function getCommentSorting() - { - return empty($this->sessionStorage->commentSorting) ? 'ASC' : $this->sessionStorage->commentSorting; - } -} diff --git a/sources/app/Core/User/UserSync.php b/sources/app/Core/User/UserSync.php deleted file mode 100644 index c2f8549..0000000 --- a/sources/app/Core/User/UserSync.php +++ /dev/null @@ -1,76 +0,0 @@ -userModel->getByExternalId($user->getExternalIdColumn(), $user->getExternalId()); - $properties = UserProperty::getProperties($user); - - if (! empty($profile)) { - $profile = $this->updateUser($profile, $properties); - } elseif ($user->isUserCreationAllowed()) { - $profile = $this->createUser($user, $properties); - } - - return $profile; - } - - /** - * Update user profile - * - * @access public - * @param array $profile - * @param array $properties - * @return array - */ - private function updateUser(array $profile, array $properties) - { - $values = UserProperty::filterProperties($profile, $properties); - - if (! empty($values)) { - $values['id'] = $profile['id']; - $result = $this->userModel->update($values); - return $result ? array_merge($profile, $properties) : $profile; - } - - return $profile; - } - - /** - * Create user - * - * @access public - * @param UserProviderInterface $user - * @param array $properties - * @return array - */ - private function createUser(UserProviderInterface $user, array $properties) - { - $userId = $this->userModel->create($properties); - - if ($userId === false) { - $this->logger->error('Unable to create user profile: '.$user->getExternalId()); - return array(); - } - - return $this->userModel->getById($userId); - } -} diff --git a/sources/app/Event/AuthFailureEvent.php b/sources/app/Event/AuthFailureEvent.php deleted file mode 100644 index 225ac04..0000000 --- a/sources/app/Event/AuthFailureEvent.php +++ /dev/null @@ -1,44 +0,0 @@ -username = $username; - } - - /** - * Get username - * - * @access public - * @return string - */ - public function getUsername() - { - return $this->username; - } -} diff --git a/sources/app/Event/AuthSuccessEvent.php b/sources/app/Event/AuthSuccessEvent.php deleted file mode 100644 index 38323e8..0000000 --- a/sources/app/Event/AuthSuccessEvent.php +++ /dev/null @@ -1,43 +0,0 @@ -authType = $authType; - } - - /** - * Get authentication type - * - * @return string - */ - public function getAuthType() - { - return $this->authType; - } -} diff --git a/sources/app/Event/CommentEvent.php b/sources/app/Event/CommentEvent.php deleted file mode 100644 index 3ac6a23..0000000 --- a/sources/app/Event/CommentEvent.php +++ /dev/null @@ -1,7 +0,0 @@ -container = $values; - } - - public function getAll() - { - return $this->container; - } - - public function offsetSet($offset, $value) - { - if (is_null($offset)) { - $this->container[] = $value; - } else { - $this->container[$offset] = $value; - } - } - - public function offsetExists($offset) - { - return isset($this->container[$offset]); - } - - public function offsetUnset($offset) - { - unset($this->container[$offset]); - } - - public function offsetGet($offset) - { - return isset($this->container[$offset]) ? $this->container[$offset] : null; - } -} diff --git a/sources/app/Event/SubtaskEvent.php b/sources/app/Event/SubtaskEvent.php deleted file mode 100644 index f34bb60..0000000 --- a/sources/app/Event/SubtaskEvent.php +++ /dev/null @@ -1,7 +0,0 @@ -container['tasks'] =& $tasks; - } -} diff --git a/sources/app/Event/UserProfileSyncEvent.php b/sources/app/Event/UserProfileSyncEvent.php deleted file mode 100644 index c02e1d8..0000000 --- a/sources/app/Event/UserProfileSyncEvent.php +++ /dev/null @@ -1,64 +0,0 @@ -profile = $profile; - $this->user = $user; - } - - /** - * Get user profile - * - * @access public - * @return array - */ - public function getProfile() - { - return $this->profile; - } - - /** - * Get user provider object - * - * @access public - * @return UserProviderInterface|LdapUserProvider - */ - public function getUser() - { - return $this->user; - } -} diff --git a/sources/app/Export/SubtaskExport.php b/sources/app/Export/SubtaskExport.php deleted file mode 100644 index 0939838..0000000 --- a/sources/app/Export/SubtaskExport.php +++ /dev/null @@ -1,124 +0,0 @@ -subtask_status = $this->subtaskModel->getStatusList(); - $subtasks = $this->getSubtasks($project_id, $from, $to); - $results = array($this->getColumns()); - - foreach ($subtasks as $subtask) { - $results[] = $this->format($subtask); - } - - return $results; - } - - /** - * Get column titles - * - * @access public - * @return string[] - */ - public function getColumns() - { - return array( - e('Subtask Id'), - e('Title'), - e('Status'), - e('Assignee'), - e('Time estimated'), - e('Time spent'), - e('Task Id'), - e('Task Title'), - ); - } - - /** - * Format the output of a subtask array - * - * @access public - * @param array $subtask Subtask properties - * @return array - */ - public function format(array $subtask) - { - $values = array(); - $values[] = $subtask['id']; - $values[] = $subtask['title']; - $values[] = $this->subtask_status[$subtask['status']]; - $values[] = $subtask['assignee_name'] ?: $subtask['assignee_username']; - $values[] = $subtask['time_estimated']; - $values[] = $subtask['time_spent']; - $values[] = $subtask['task_id']; - $values[] = $subtask['task_title']; - - return $values; - } - - /** - * Get all subtasks for a given project - * - * @access public - * @param integer $project_id Project id - * @param mixed $from Start date (timestamp or user formatted date) - * @param mixed $to End date (timestamp or user formatted date) - * @return array - */ - public function getSubtasks($project_id, $from, $to) - { - if (! is_numeric($from)) { - $from = $this->dateParser->removeTimeFromTimestamp($this->dateParser->getTimestamp($from)); - } - - if (! is_numeric($to)) { - $to = $this->dateParser->removeTimeFromTimestamp(strtotime('+1 day', $this->dateParser->getTimestamp($to))); - } - - return $this->db->table(SubtaskModel::TABLE) - ->eq('project_id', $project_id) - ->columns( - SubtaskModel::TABLE.'.*', - UserModel::TABLE.'.username AS assignee_username', - UserModel::TABLE.'.name AS assignee_name', - TaskModel::TABLE.'.title AS task_title' - ) - ->gte('date_creation', $from) - ->lte('date_creation', $to) - ->join(TaskModel::TABLE, 'id', 'task_id') - ->join(UserModel::TABLE, 'id', 'user_id') - ->asc(SubtaskModel::TABLE.'.id') - ->findAll(); - } -} diff --git a/sources/app/Export/TaskExport.php b/sources/app/Export/TaskExport.php deleted file mode 100644 index 0e576d3..0000000 --- a/sources/app/Export/TaskExport.php +++ /dev/null @@ -1,148 +0,0 @@ -getTasks($project_id, $from, $to); - $swimlanes = $this->swimlaneModel->getList($project_id); - $results = array($this->getColumns()); - - foreach ($tasks as &$task) { - $results[] = array_values($this->format($task, $swimlanes)); - } - - return $results; - } - - /** - * Get the list of tasks for a given project and date range - * - * @access public - * @param integer $project_id Project id - * @param mixed $from Start date (timestamp or user formatted date) - * @param mixed $to End date (timestamp or user formatted date) - * @return array - */ - public function getTasks($project_id, $from, $to) - { - $sql = ' - SELECT - tasks.id, - projects.name AS project_name, - tasks.is_active, - project_has_categories.name AS category_name, - tasks.swimlane_id, - columns.title AS column_title, - tasks.position, - tasks.color_id, - tasks.date_due, - creators.username AS creator_username, - users.username AS assignee_username, - users.name AS assignee_name, - tasks.score, - tasks.title, - tasks.date_creation, - tasks.date_modification, - tasks.date_completed, - tasks.date_started, - tasks.time_estimated, - tasks.time_spent - FROM tasks - LEFT JOIN users ON users.id = tasks.owner_id - LEFT JOIN users AS creators ON creators.id = tasks.creator_id - LEFT JOIN project_has_categories ON project_has_categories.id = tasks.category_id - LEFT JOIN columns ON columns.id = tasks.column_id - LEFT JOIN projects ON projects.id = tasks.project_id - WHERE tasks.date_creation >= ? AND tasks.date_creation <= ? AND tasks.project_id = ? - ORDER BY tasks.id ASC - '; - - if (! is_numeric($from)) { - $from = $this->dateParser->removeTimeFromTimestamp($this->dateParser->getTimestamp($from)); - } - - if (! is_numeric($to)) { - $to = $this->dateParser->removeTimeFromTimestamp(strtotime('+1 day', $this->dateParser->getTimestamp($to))); - } - - $rq = $this->db->execute($sql, array($from, $to, $project_id)); - return $rq->fetchAll(PDO::FETCH_ASSOC); - } - - /** - * Format the output of a task array - * - * @access public - * @param array $task Task properties - * @param array $swimlanes List of swimlanes - * @return array - */ - public function format(array &$task, array &$swimlanes) - { - $colors = $this->colorModel->getList(); - - $task['is_active'] = $task['is_active'] == TaskModel::STATUS_OPEN ? e('Open') : e('Closed'); - $task['color_id'] = $colors[$task['color_id']]; - $task['score'] = $task['score'] ?: 0; - $task['swimlane_id'] = isset($swimlanes[$task['swimlane_id']]) ? $swimlanes[$task['swimlane_id']] : '?'; - - $task = $this->dateParser->format($task, array('date_due', 'date_modification', 'date_creation', 'date_started', 'date_completed'), DateParser::DATE_FORMAT); - - return $task; - } - - /** - * Get column titles - * - * @access public - * @return string[] - */ - public function getColumns() - { - return array( - e('Task Id'), - e('Project'), - e('Status'), - e('Category'), - e('Swimlane'), - e('Column'), - e('Position'), - e('Color'), - e('Due date'), - e('Creator'), - e('Assignee Username'), - e('Assignee Name'), - e('Complexity'), - e('Title'), - e('Creation date'), - e('Modification date'), - e('Completion date'), - e('Start date'), - e('Time estimated'), - e('Time spent'), - ); - } -} diff --git a/sources/app/Export/TransitionExport.php b/sources/app/Export/TransitionExport.php deleted file mode 100644 index 35f9fe4..0000000 --- a/sources/app/Export/TransitionExport.php +++ /dev/null @@ -1,76 +0,0 @@ -getColumns()); - $transitions = $this->transitionModel->getAllByProjectAndDate($project_id, $from, $to); - - foreach ($transitions as $transition) { - $results[] = $this->format($transition); - } - - return $results; - } - - /** - * Get column titles - * - * @access protected - * @return string[] - */ - protected function getColumns() - { - return array( - e('Id'), - e('Task Title'), - e('Source column'), - e('Destination column'), - e('Executer'), - e('Date'), - e('Time spent'), - ); - } - - /** - * Format the output of a transition array - * - * @access protected - * @param array $transition - * @return array - */ - protected function format(array $transition) - { - $values = array( - (int) $transition['id'], - $transition['title'], - $transition['src_column'], - $transition['dst_column'], - $transition['name'] ?: $transition['username'], - date($this->dateParser->getUserDateTimeFormat(), $transition['date']), - round($transition['time_spent'] / 3600, 2) - ); - - return $values; - } -} diff --git a/sources/app/ExternalLink/AttachmentLink.php b/sources/app/ExternalLink/AttachmentLink.php deleted file mode 100644 index 5a0d134..0000000 --- a/sources/app/ExternalLink/AttachmentLink.php +++ /dev/null @@ -1,26 +0,0 @@ -url, PHP_URL_PATH); - return basename($path); - } -} diff --git a/sources/app/ExternalLink/AttachmentLinkProvider.php b/sources/app/ExternalLink/AttachmentLinkProvider.php deleted file mode 100644 index 706ac1d..0000000 --- a/sources/app/ExternalLink/AttachmentLinkProvider.php +++ /dev/null @@ -1,117 +0,0 @@ - t('Related'), - ); - } - - /** - * Return true if the provider can parse correctly the user input - * - * @access public - * @return boolean - */ - public function match() - { - if (preg_match('/^https?:\/\/.*\.([^\/]+)$/', $this->userInput, $matches)) { - return $this->isValidExtension($matches[1]); - } - - return false; - } - - /** - * Get the link found with the properties - * - * @access public - * @return \Kanboard\Core\ExternalLink\ExternalLinkInterface - */ - public function getLink() - { - $link = new AttachmentLink($this->container); - $link->setUrl($this->userInput); - - return $link; - } - - /** - * Check file extension - * - * @access protected - * @param string $extension - * @return boolean - */ - protected function isValidExtension($extension) - { - $extension = strtolower($extension); - - foreach ($this->extensions as $ext) { - if ($extension === $ext) { - return false; - } - } - - return true; - } -} diff --git a/sources/app/ExternalLink/BaseLink.php b/sources/app/ExternalLink/BaseLink.php deleted file mode 100644 index 08693ae..0000000 --- a/sources/app/ExternalLink/BaseLink.php +++ /dev/null @@ -1,44 +0,0 @@ -url; - } - - /** - * Set link URL - * - * @access public - * @param string $url - */ - public function setUrl($url) - { - $this->url = $url; - } -} diff --git a/sources/app/ExternalLink/BaseLinkProvider.php b/sources/app/ExternalLink/BaseLinkProvider.php deleted file mode 100644 index 749cda9..0000000 --- a/sources/app/ExternalLink/BaseLinkProvider.php +++ /dev/null @@ -1,33 +0,0 @@ -userInput = trim($input); - } -} diff --git a/sources/app/ExternalLink/FileLink.php b/sources/app/ExternalLink/FileLink.php deleted file mode 100644 index ea13ece..0000000 --- a/sources/app/ExternalLink/FileLink.php +++ /dev/null @@ -1,26 +0,0 @@ -url, PHP_URL_PATH); - return basename(str_replace('\\', '/', $path)); - } -} diff --git a/sources/app/ExternalLink/FileLinkProvider.php b/sources/app/ExternalLink/FileLinkProvider.php deleted file mode 100644 index 901f78f..0000000 --- a/sources/app/ExternalLink/FileLinkProvider.php +++ /dev/null @@ -1,74 +0,0 @@ - t('Related'), - ); - } - - /** - * Return true if the provider can parse correctly the user input - * - * @access public - * @return boolean - */ - public function match() - { - return strpos($this->userInput, 'file://') === 0; - } - - /** - * Get the link found with the properties - * - * @access public - * @return \Kanboard\Core\ExternalLink\ExternalLinkInterface - */ - public function getLink() - { - $link = new FileLink($this->container); - $link->setUrl($this->userInput); - - return $link; - } -} diff --git a/sources/app/ExternalLink/WebLink.php b/sources/app/ExternalLink/WebLink.php deleted file mode 100644 index 9338ca4..0000000 --- a/sources/app/ExternalLink/WebLink.php +++ /dev/null @@ -1,37 +0,0 @@ -httpClient->get($this->url); - - if (preg_match('/(.*)<\/title>/siU', $html, $matches)) { - return trim($matches[1]); - } - - $components = parse_url($this->url); - - if (! empty($components['host']) && ! empty($components['path'])) { - return $components['host'].$components['path']; - } - - return t('Title not found'); - } -} diff --git a/sources/app/ExternalLink/WebLinkProvider.php b/sources/app/ExternalLink/WebLinkProvider.php deleted file mode 100644 index 5ec1bbe..0000000 --- a/sources/app/ExternalLink/WebLinkProvider.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php - -namespace Kanboard\ExternalLink; - -use Kanboard\Core\ExternalLink\ExternalLinkProviderInterface; - -/** - * Web Link Provider - * - * @package externalLink - * @author Frederic Guillot - */ -class WebLinkProvider extends BaseLinkProvider implements ExternalLinkProviderInterface -{ - /** - * Get provider name - * - * @access public - * @return string - */ - public function getName() - { - return t('Web Link'); - } - - /** - * Get link type - * - * @access public - * @return string - */ - public function getType() - { - return 'weblink'; - } - - /** - * Get a dictionary of supported dependency types by the provider - * - * @access public - * @return array - */ - public function getDependencies() - { - return array( - 'related' => t('Related'), - ); - } - - /** - * Return true if the provider can parse correctly the user input - * - * @access public - * @return boolean - */ - public function match() - { - $startWithHttp = strpos($this->userInput, 'http://') === 0 || strpos($this->userInput, 'https://') === 0; - $validUrl = filter_var($this->userInput, FILTER_VALIDATE_URL); - - return $startWithHttp && $validUrl; - } - - /** - * Get the link found with the properties - * - * @access public - * @return \Kanboard\Core\ExternalLink\ExternalLinkInterface - */ - public function getLink() - { - $link = new WebLink($this->container); - $link->setUrl($this->userInput); - - return $link; - } -} diff --git a/sources/app/Filter/BaseDateFilter.php b/sources/app/Filter/BaseDateFilter.php deleted file mode 100644 index 56fb2d7..0000000 --- a/sources/app/Filter/BaseDateFilter.php +++ /dev/null @@ -1,103 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\DateParser; - -/** - * Base date filter class - * - * @package filter - * @author Frederic Guillot - */ -abstract class BaseDateFilter extends BaseFilter -{ - /** - * DateParser object - * - * @access protected - * @var DateParser - */ - protected $dateParser; - - /** - * Set DateParser object - * - * @access public - * @param DateParser $dateParser - * @return $this - */ - public function setDateParser(DateParser $dateParser) - { - $this->dateParser = $dateParser; - return $this; - } - - /** - * Parse operator in the input string - * - * @access protected - * @return string - */ - protected function parseOperator() - { - $operators = array( - '<=' => 'lte', - '>=' => 'gte', - '<' => 'lt', - '>' => 'gt', - ); - - foreach ($operators as $operator => $method) { - if (strpos($this->value, $operator) === 0) { - $this->value = substr($this->value, strlen($operator)); - return $method; - } - } - - return ''; - } - - /** - * Apply a date filter - * - * @access protected - * @param string $field - */ - protected function applyDateFilter($field) - { - $method = $this->parseOperator(); - $timestamp = $this->dateParser->getTimestampFromIsoFormat($this->value); - - if ($method !== '') { - $this->query->$method($field, $this->getTimestampFromOperator($method, $timestamp)); - } else { - $this->query->gte($field, $timestamp); - $this->query->lte($field, $timestamp + 86399); - } - } - - /** - * Get timestamp from the operator - * - * @access public - * @param string $method - * @param integer $timestamp - * @return integer - */ - protected function getTimestampFromOperator($method, $timestamp) - { - switch ($method) { - case 'lte': - return $timestamp + 86399; - case 'lt': - return $timestamp; - case 'gte': - return $timestamp; - case 'gt': - return $timestamp + 86400; - } - - return $timestamp; - } -} diff --git a/sources/app/Filter/BaseFilter.php b/sources/app/Filter/BaseFilter.php deleted file mode 100644 index e029f4e..0000000 --- a/sources/app/Filter/BaseFilter.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use PicoDb\Table; - -/** - * Base filter class - * - * @package filter - * @author Frederic Guillot - */ -abstract class BaseFilter -{ - /** - * @var Table - */ - protected $query; - - /** - * @var mixed - */ - protected $value; - - /** - * BaseFilter constructor - * - * @access public - * @param mixed $value - */ - public function __construct($value = null) - { - $this->value = $value; - } - - /** - * Get object instance - * - * @static - * @access public - * @param mixed $value - * @return static - */ - public static function getInstance($value = null) - { - return new static($value); - } - - /** - * Set query - * - * @access public - * @param Table $query - * @return \Kanboard\Core\Filter\FilterInterface - */ - public function withQuery(Table $query) - { - $this->query = $query; - return $this; - } - - /** - * Set the value - * - * @access public - * @param string $value - * @return \Kanboard\Core\Filter\FilterInterface - */ - public function withValue($value) - { - $this->value = $value; - return $this; - } -} diff --git a/sources/app/Filter/ProjectActivityCreationDateFilter.php b/sources/app/Filter/ProjectActivityCreationDateFilter.php deleted file mode 100644 index 451f654..0000000 --- a/sources/app/Filter/ProjectActivityCreationDateFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectActivityModel; - -/** - * Filter activity events by creation date - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityCreationDateFilter extends BaseDateFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('created'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->applyDateFilter(ProjectActivityModel::TABLE.'.date_creation'); - return $this; - } -} diff --git a/sources/app/Filter/ProjectActivityCreatorFilter.php b/sources/app/Filter/ProjectActivityCreatorFilter.php deleted file mode 100644 index 573238d..0000000 --- a/sources/app/Filter/ProjectActivityCreatorFilter.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectActivityModel; - -/** - * Filter activity events by creator - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityCreatorFilter extends BaseFilter implements FilterInterface -{ - /** - * Current user id - * - * @access private - * @var int - */ - private $currentUserId = 0; - - /** - * Set current user id - * - * @access public - * @param integer $userId - * @return TaskAssigneeFilter - */ - public function setCurrentUserId($userId) - { - $this->currentUserId = $userId; - return $this; - } - - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('creator'); - } - - /** - * Apply filter - * - * @access public - * @return string - */ - public function apply() - { - if ($this->value === 'me') { - $this->query->eq(ProjectActivityModel::TABLE . '.creator_id', $this->currentUserId); - } else { - $this->query->beginOr(); - $this->query->ilike('uc.username', '%'.$this->value.'%'); - $this->query->ilike('uc.name', '%'.$this->value.'%'); - $this->query->closeOr(); - } - } -} diff --git a/sources/app/Filter/ProjectActivityProjectIdFilter.php b/sources/app/Filter/ProjectActivityProjectIdFilter.php deleted file mode 100644 index 7146a05..0000000 --- a/sources/app/Filter/ProjectActivityProjectIdFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectActivityModel; - -/** - * Filter activity events by projectId - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityProjectIdFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('project_id'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->eq(ProjectActivityModel::TABLE.'.project_id', $this->value); - return $this; - } -} diff --git a/sources/app/Filter/ProjectActivityProjectIdsFilter.php b/sources/app/Filter/ProjectActivityProjectIdsFilter.php deleted file mode 100644 index 70968f7..0000000 --- a/sources/app/Filter/ProjectActivityProjectIdsFilter.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectActivityModel; - -/** - * Filter activity events by projectIds - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityProjectIdsFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('projects'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (empty($this->value)) { - $this->query->eq(ProjectActivityModel::TABLE.'.project_id', 0); - } else { - $this->query->in(ProjectActivityModel::TABLE.'.project_id', $this->value); - } - - return $this; - } -} diff --git a/sources/app/Filter/ProjectActivityProjectNameFilter.php b/sources/app/Filter/ProjectActivityProjectNameFilter.php deleted file mode 100644 index b487218..0000000 --- a/sources/app/Filter/ProjectActivityProjectNameFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectModel; - -/** - * Filter activity events by project name - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityProjectNameFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('project'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->ilike(ProjectModel::TABLE.'.name', '%'.$this->value.'%'); - return $this; - } -} diff --git a/sources/app/Filter/ProjectActivityTaskIdFilter.php b/sources/app/Filter/ProjectActivityTaskIdFilter.php deleted file mode 100644 index b8e074d..0000000 --- a/sources/app/Filter/ProjectActivityTaskIdFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectActivityModel; - -/** - * Filter activity events by taskId - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityTaskIdFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('task_id'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->eq(ProjectActivityModel::TABLE.'.task_id', $this->value); - return $this; - } -} diff --git a/sources/app/Filter/ProjectActivityTaskStatusFilter.php b/sources/app/Filter/ProjectActivityTaskStatusFilter.php deleted file mode 100644 index 2c98cab..0000000 --- a/sources/app/Filter/ProjectActivityTaskStatusFilter.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter activity events by task status - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityTaskStatusFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('status'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if ($this->value === 'open') { - $this->query->eq(TaskModel::TABLE.'.is_active', TaskModel::STATUS_OPEN); - } elseif ($this->value === 'closed') { - $this->query->eq(TaskModel::TABLE.'.is_active', TaskModel::STATUS_CLOSED); - } - - return $this; - } -} diff --git a/sources/app/Filter/ProjectActivityTaskTitleFilter.php b/sources/app/Filter/ProjectActivityTaskTitleFilter.php deleted file mode 100644 index bf2afa3..0000000 --- a/sources/app/Filter/ProjectActivityTaskTitleFilter.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; - -/** - * Filter activity events by task title - * - * @package filter - * @author Frederic Guillot - */ -class ProjectActivityTaskTitleFilter extends TaskTitleFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('title'); - } -} diff --git a/sources/app/Filter/ProjectGroupRoleProjectFilter.php b/sources/app/Filter/ProjectGroupRoleProjectFilter.php deleted file mode 100644 index 035931b..0000000 --- a/sources/app/Filter/ProjectGroupRoleProjectFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectGroupRoleModel; - -/** - * Filter ProjectGroupRole users by project - * - * @package filter - * @author Frederic Guillot - */ -class ProjectGroupRoleProjectFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array(); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->eq(ProjectGroupRoleModel::TABLE.'.project_id', $this->value); - return $this; - } -} diff --git a/sources/app/Filter/ProjectGroupRoleUsernameFilter.php b/sources/app/Filter/ProjectGroupRoleUsernameFilter.php deleted file mode 100644 index 9feac33..0000000 --- a/sources/app/Filter/ProjectGroupRoleUsernameFilter.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\GroupMemberModel; -use Kanboard\Model\ProjectGroupRoleModel; -use Kanboard\Model\UserModel; - -/** - * Filter ProjectGroupRole users by username - * - * @package filter - * @author Frederic Guillot - */ -class ProjectGroupRoleUsernameFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array(); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query - ->join(GroupMemberModel::TABLE, 'group_id', 'group_id', ProjectGroupRoleModel::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id', GroupMemberModel::TABLE) - ->ilike(UserModel::TABLE.'.username', $this->value.'%'); - - return $this; - } -} diff --git a/sources/app/Filter/ProjectIdsFilter.php b/sources/app/Filter/ProjectIdsFilter.php deleted file mode 100644 index 9af9db5..0000000 --- a/sources/app/Filter/ProjectIdsFilter.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectModel; - -/** - * Filter project by ids - * - * @package filter - * @author Frederic Guillot - */ -class ProjectIdsFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('project_ids'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (empty($this->value)) { - $this->query->eq(ProjectModel::TABLE.'.id', 0); - } else { - $this->query->in(ProjectModel::TABLE.'.id', $this->value); - } - - return $this; - } -} diff --git a/sources/app/Filter/ProjectStatusFilter.php b/sources/app/Filter/ProjectStatusFilter.php deleted file mode 100644 index c1a06ef..0000000 --- a/sources/app/Filter/ProjectStatusFilter.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectModel; - -/** - * Filter project by status - * - * @package filter - * @author Frederic Guillot - */ -class ProjectStatusFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('status'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(ProjectModel::TABLE.'.is_active', $this->value); - } elseif ($this->value === 'inactive' || $this->value === 'closed' || $this->value === 'disabled') { - $this->query->eq(ProjectModel::TABLE.'.is_active', 0); - } else { - $this->query->eq(ProjectModel::TABLE.'.is_active', 1); - } - - return $this; - } -} diff --git a/sources/app/Filter/ProjectTypeFilter.php b/sources/app/Filter/ProjectTypeFilter.php deleted file mode 100644 index 6afcd29..0000000 --- a/sources/app/Filter/ProjectTypeFilter.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectModel; - -/** - * Filter project by type - * - * @package filter - * @author Frederic Guillot - */ -class ProjectTypeFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('type'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(ProjectModel::TABLE.'.is_private', $this->value); - } elseif ($this->value === 'private') { - $this->query->eq(ProjectModel::TABLE.'.is_private', ProjectModel::TYPE_PRIVATE); - } else { - $this->query->eq(ProjectModel::TABLE.'.is_private', ProjectModel::TYPE_TEAM); - } - - return $this; - } -} diff --git a/sources/app/Filter/ProjectUserRoleProjectFilter.php b/sources/app/Filter/ProjectUserRoleProjectFilter.php deleted file mode 100644 index 6952364..0000000 --- a/sources/app/Filter/ProjectUserRoleProjectFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectUserRoleModel; - -/** - * Filter ProjectUserRole users by project - * - * @package filter - * @author Frederic Guillot - */ -class ProjectUserRoleProjectFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array(); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->eq(ProjectUserRoleModel::TABLE.'.project_id', $this->value); - return $this; - } -} diff --git a/sources/app/Filter/ProjectUserRoleUsernameFilter.php b/sources/app/Filter/ProjectUserRoleUsernameFilter.php deleted file mode 100644 index 327d3d5..0000000 --- a/sources/app/Filter/ProjectUserRoleUsernameFilter.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\UserModel; - -/** - * Filter ProjectUserRole users by username - * - * @package filter - * @author Frederic Guillot - */ -class ProjectUserRoleUsernameFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array(); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query - ->join(UserModel::TABLE, 'id', 'user_id') - ->ilike(UserModel::TABLE.'.username', $this->value.'%'); - - return $this; - } -} diff --git a/sources/app/Filter/TaskAssigneeFilter.php b/sources/app/Filter/TaskAssigneeFilter.php deleted file mode 100644 index d6962a9..0000000 --- a/sources/app/Filter/TaskAssigneeFilter.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; -use Kanboard\Model\UserModel; - -/** - * Filter tasks by assignee - * - * @package filter - * @author Frederic Guillot - */ -class TaskAssigneeFilter extends BaseFilter implements FilterInterface -{ - /** - * Current user id - * - * @access private - * @var int - */ - private $currentUserId = 0; - - /** - * Set current user id - * - * @access public - * @param integer $userId - * @return TaskAssigneeFilter - */ - public function setCurrentUserId($userId) - { - $this->currentUserId = $userId; - return $this; - } - - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('assignee'); - } - - /** - * Apply filter - * - * @access public - * @return string - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(TaskModel::TABLE.'.owner_id', $this->value); - } else { - switch ($this->value) { - case 'me': - $this->query->eq(TaskModel::TABLE.'.owner_id', $this->currentUserId); - break; - case 'nobody': - $this->query->eq(TaskModel::TABLE.'.owner_id', 0); - break; - default: - $this->query->beginOr(); - $this->query->ilike(UserModel::TABLE.'.username', '%'.$this->value.'%'); - $this->query->ilike(UserModel::TABLE.'.name', '%'.$this->value.'%'); - $this->query->closeOr(); - } - } - } -} diff --git a/sources/app/Filter/TaskCategoryFilter.php b/sources/app/Filter/TaskCategoryFilter.php deleted file mode 100644 index 35c52f6..0000000 --- a/sources/app/Filter/TaskCategoryFilter.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\CategoryModel; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by category - * - * @package filter - * @author Frederic Guillot - */ -class TaskCategoryFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('category'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(TaskModel::TABLE.'.category_id', $this->value); - } elseif ($this->value === 'none') { - $this->query->eq(TaskModel::TABLE.'.category_id', 0); - } else { - $this->query->eq(CategoryModel::TABLE.'.name', $this->value); - } - - return $this; - } -} diff --git a/sources/app/Filter/TaskColorFilter.php b/sources/app/Filter/TaskColorFilter.php deleted file mode 100644 index 2ddb47c..0000000 --- a/sources/app/Filter/TaskColorFilter.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ColorModel; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by color - * - * @package filter - * @author Frederic Guillot - */ -class TaskColorFilter extends BaseFilter implements FilterInterface -{ - /** - * Color object - * - * @access private - * @var ColorModel - */ - private $colorModel; - - /** - * Set color model object - * - * @access public - * @param ColorModel $colorModel - * @return TaskColorFilter - */ - public function setColorModel(ColorModel $colorModel) - { - $this->colorModel = $colorModel; - return $this; - } - - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('color', 'colour'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->eq(TaskModel::TABLE.'.color_id', $this->colorModel->find($this->value)); - return $this; - } -} diff --git a/sources/app/Filter/TaskColumnFilter.php b/sources/app/Filter/TaskColumnFilter.php deleted file mode 100644 index fa925b7..0000000 --- a/sources/app/Filter/TaskColumnFilter.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ColumnModel; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by column - * - * @package filter - * @author Frederic Guillot - */ -class TaskColumnFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('column'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(TaskModel::TABLE.'.column_id', $this->value); - } else { - $this->query->eq(ColumnModel::TABLE.'.title', $this->value); - } - - return $this; - } -} diff --git a/sources/app/Filter/TaskCommentFilter.php b/sources/app/Filter/TaskCommentFilter.php deleted file mode 100644 index 52db558..0000000 --- a/sources/app/Filter/TaskCommentFilter.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\CommentModel; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by comment - * - * @package filter - * @author Frederic Guillot - */ -class TaskCommentFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('comment'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->ilike(CommentModel::TABLE.'.comment', '%'.$this->value.'%'); - $this->query->join(CommentModel::TABLE, 'task_id', 'id', TaskModel::TABLE); - - return $this; - } -} diff --git a/sources/app/Filter/TaskCompletionDateFilter.php b/sources/app/Filter/TaskCompletionDateFilter.php deleted file mode 100644 index 79b5e7d..0000000 --- a/sources/app/Filter/TaskCompletionDateFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by completion date - * - * @package filter - * @author Frederic Guillot - */ -class TaskCompletionDateFilter extends BaseDateFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('completed'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->applyDateFilter(TaskModel::TABLE.'.date_completed'); - return $this; - } -} diff --git a/sources/app/Filter/TaskCreationDateFilter.php b/sources/app/Filter/TaskCreationDateFilter.php deleted file mode 100644 index db28ac8..0000000 --- a/sources/app/Filter/TaskCreationDateFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by creation date - * - * @package filter - * @author Frederic Guillot - */ -class TaskCreationDateFilter extends BaseDateFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('created'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->applyDateFilter(TaskModel::TABLE.'.date_creation'); - return $this; - } -} diff --git a/sources/app/Filter/TaskCreatorFilter.php b/sources/app/Filter/TaskCreatorFilter.php deleted file mode 100644 index 611db18..0000000 --- a/sources/app/Filter/TaskCreatorFilter.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by creator - * - * @package filter - * @author Frederic Guillot - */ -class TaskCreatorFilter extends BaseFilter implements FilterInterface -{ - /** - * Current user id - * - * @access private - * @var int - */ - private $currentUserId = 0; - - /** - * Set current user id - * - * @access public - * @param integer $userId - * @return TaskAssigneeFilter - */ - public function setCurrentUserId($userId) - { - $this->currentUserId = $userId; - return $this; - } - - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('creator'); - } - - /** - * Apply filter - * - * @access public - * @return string - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(TaskModel::TABLE.'.creator_id', $this->value); - } else { - switch ($this->value) { - case 'me': - $this->query->eq(TaskModel::TABLE.'.creator_id', $this->currentUserId); - break; - case 'nobody': - $this->query->eq(TaskModel::TABLE.'.creator_id', 0); - break; - default: - $this->query->beginOr(); - $this->query->ilike('uc.username', '%'.$this->value.'%'); - $this->query->ilike('uc.name', '%'.$this->value.'%'); - $this->query->closeOr(); - } - } - } -} diff --git a/sources/app/Filter/TaskDescriptionFilter.php b/sources/app/Filter/TaskDescriptionFilter.php deleted file mode 100644 index c73c2f5..0000000 --- a/sources/app/Filter/TaskDescriptionFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by description - * - * @package filter - * @author Frederic Guillot - */ -class TaskDescriptionFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('description', 'desc'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->ilike(TaskModel::TABLE.'.description', '%'.$this->value.'%'); - return $this; - } -} diff --git a/sources/app/Filter/TaskDueDateFilter.php b/sources/app/Filter/TaskDueDateFilter.php deleted file mode 100644 index 0de055b..0000000 --- a/sources/app/Filter/TaskDueDateFilter.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by due date - * - * @package filter - * @author Frederic Guillot - */ -class TaskDueDateFilter extends BaseDateFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('due'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->neq(TaskModel::TABLE.'.date_due', 0); - $this->query->notNull(TaskModel::TABLE.'.date_due'); - $this->applyDateFilter(TaskModel::TABLE.'.date_due'); - - return $this; - } -} diff --git a/sources/app/Filter/TaskDueDateRangeFilter.php b/sources/app/Filter/TaskDueDateRangeFilter.php deleted file mode 100644 index a6aefbe..0000000 --- a/sources/app/Filter/TaskDueDateRangeFilter.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by due date range - * - * @package filter - * @author Frederic Guillot - */ -class TaskDueDateRangeFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array(); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->gte(TaskModel::TABLE.'.date_due', is_numeric($this->value[0]) ? $this->value[0] : strtotime($this->value[0])); - $this->query->lte(TaskModel::TABLE.'.date_due', is_numeric($this->value[1]) ? $this->value[1] : strtotime($this->value[1])); - return $this; - } -} diff --git a/sources/app/Filter/TaskIdExclusionFilter.php b/sources/app/Filter/TaskIdExclusionFilter.php deleted file mode 100644 index 20177b2..0000000 --- a/sources/app/Filter/TaskIdExclusionFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Exclude task ids - * - * @package filter - * @author Frederic Guillot - */ -class TaskIdExclusionFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('exclude'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->notin(TaskModel::TABLE.'.id', $this->value); - return $this; - } -} diff --git a/sources/app/Filter/TaskIdFilter.php b/sources/app/Filter/TaskIdFilter.php deleted file mode 100644 index fdf668b..0000000 --- a/sources/app/Filter/TaskIdFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by id - * - * @package filter - * @author Frederic Guillot - */ -class TaskIdFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('id'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->eq(TaskModel::TABLE.'.id', $this->value); - return $this; - } -} diff --git a/sources/app/Filter/TaskLinkFilter.php b/sources/app/Filter/TaskLinkFilter.php deleted file mode 100644 index 98cd597..0000000 --- a/sources/app/Filter/TaskLinkFilter.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\LinkModel; -use Kanboard\Model\TaskModel; -use Kanboard\Model\TaskLinkModel; -use PicoDb\Database; -use PicoDb\Table; - -/** - * Filter tasks by link name - * - * @package filter - * @author Frederic Guillot - */ -class TaskLinkFilter extends BaseFilter implements FilterInterface -{ - /** - * Database object - * - * @access private - * @var Database - */ - private $db; - - /** - * Set database object - * - * @access public - * @param Database $db - * @return TaskLinkFilter - */ - public function setDatabase(Database $db) - { - $this->db = $db; - return $this; - } - - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('link'); - } - - /** - * Apply filter - * - * @access public - * @return string - */ - public function apply() - { - $task_ids = $this->getSubQuery()->findAllByColumn('task_id'); - - if (! empty($task_ids)) { - $this->query->in(TaskModel::TABLE.'.id', $task_ids); - } else { - $this->query->eq(TaskModel::TABLE.'.id', 0); // No match - } - } - - /** - * Get subquery - * - * @access protected - * @return Table - */ - protected function getSubQuery() - { - return $this->db->table(TaskLinkModel::TABLE) - ->columns( - TaskLinkModel::TABLE.'.task_id', - LinkModel::TABLE.'.label' - ) - ->join(LinkModel::TABLE, 'id', 'link_id', TaskLinkModel::TABLE) - ->ilike(LinkModel::TABLE.'.label', $this->value); - } -} diff --git a/sources/app/Filter/TaskModificationDateFilter.php b/sources/app/Filter/TaskModificationDateFilter.php deleted file mode 100644 index 316f183..0000000 --- a/sources/app/Filter/TaskModificationDateFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by modification date - * - * @package filter - * @author Frederic Guillot - */ -class TaskModificationDateFilter extends BaseDateFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('updated', 'modified'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->applyDateFilter(TaskModel::TABLE.'.date_modification'); - return $this; - } -} diff --git a/sources/app/Filter/TaskProjectFilter.php b/sources/app/Filter/TaskProjectFilter.php deleted file mode 100644 index 0b5a336..0000000 --- a/sources/app/Filter/TaskProjectFilter.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectModel; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by project - * - * @package filter - * @author Frederic Guillot - */ -class TaskProjectFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('project'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(TaskModel::TABLE.'.project_id', $this->value); - } else { - $this->query->ilike(ProjectModel::TABLE.'.name', $this->value); - } - - return $this; - } -} diff --git a/sources/app/Filter/TaskProjectsFilter.php b/sources/app/Filter/TaskProjectsFilter.php deleted file mode 100644 index 2b6b16c..0000000 --- a/sources/app/Filter/TaskProjectsFilter.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by project ids - * - * @package filter - * @author Frederic Guillot - */ -class TaskProjectsFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('projects'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (empty($this->value)) { - $this->query->eq(TaskModel::TABLE.'.project_id', 0); - } else { - $this->query->in(TaskModel::TABLE.'.project_id', $this->value); - } - - return $this; - } -} diff --git a/sources/app/Filter/TaskReferenceFilter.php b/sources/app/Filter/TaskReferenceFilter.php deleted file mode 100644 index 27c838f..0000000 --- a/sources/app/Filter/TaskReferenceFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by reference - * - * @package filter - * @author Frederic Guillot - */ -class TaskReferenceFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('reference', 'ref'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->eq(TaskModel::TABLE.'.reference', $this->value); - return $this; - } -} diff --git a/sources/app/Filter/TaskStartDateFilter.php b/sources/app/Filter/TaskStartDateFilter.php deleted file mode 100644 index d5abedb..0000000 --- a/sources/app/Filter/TaskStartDateFilter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by start date - * - * @package filter - * @author Frederic Guillot - */ -class TaskStartDateFilter extends BaseDateFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('started'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->applyDateFilter(TaskModel::TABLE.'.date_started'); - return $this; - } -} diff --git a/sources/app/Filter/TaskStatusFilter.php b/sources/app/Filter/TaskStatusFilter.php deleted file mode 100644 index a55532c..0000000 --- a/sources/app/Filter/TaskStatusFilter.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by status - * - * @package filter - * @author Frederic Guillot - */ -class TaskStatusFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('status'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if ($this->value === 'open' || $this->value === 'closed') { - $this->query->eq(TaskModel::TABLE.'.is_active', $this->value === 'open' ? TaskModel::STATUS_OPEN : TaskModel::STATUS_CLOSED); - } else { - $this->query->eq(TaskModel::TABLE.'.is_active', $this->value); - } - - return $this; - } -} diff --git a/sources/app/Filter/TaskSubtaskAssigneeFilter.php b/sources/app/Filter/TaskSubtaskAssigneeFilter.php deleted file mode 100644 index 46553a3..0000000 --- a/sources/app/Filter/TaskSubtaskAssigneeFilter.php +++ /dev/null @@ -1,140 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\SubtaskModel; -use Kanboard\Model\TaskModel; -use Kanboard\Model\UserModel; -use PicoDb\Database; -use PicoDb\Table; - -/** - * Filter tasks by subtasks assignee - * - * @package filter - * @author Frederic Guillot - */ -class TaskSubtaskAssigneeFilter extends BaseFilter implements FilterInterface -{ - /** - * Database object - * - * @access private - * @var Database - */ - private $db; - - /** - * Current user id - * - * @access private - * @var int - */ - private $currentUserId = 0; - - /** - * Set current user id - * - * @access public - * @param integer $userId - * @return TaskSubtaskAssigneeFilter - */ - public function setCurrentUserId($userId) - { - $this->currentUserId = $userId; - return $this; - } - - /** - * Set database object - * - * @access public - * @param Database $db - * @return TaskSubtaskAssigneeFilter - */ - public function setDatabase(Database $db) - { - $this->db = $db; - return $this; - } - - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('subtask:assignee'); - } - - /** - * Apply filter - * - * @access public - * @return string - */ - public function apply() - { - $task_ids = $this->getSubQuery()->findAllByColumn('task_id'); - - if (! empty($task_ids)) { - $this->query->in(TaskModel::TABLE.'.id', $task_ids); - } else { - $this->query->eq(TaskModel::TABLE.'.id', 0); // No match - } - } - - /** - * Get subquery - * - * @access protected - * @return Table - */ - protected function getSubQuery() - { - $subquery = $this->db->table(SubtaskModel::TABLE) - ->columns( - SubtaskModel::TABLE.'.user_id', - SubtaskModel::TABLE.'.task_id', - UserModel::TABLE.'.name', - UserModel::TABLE.'.username' - ) - ->join(UserModel::TABLE, 'id', 'user_id', SubtaskModel::TABLE) - ->neq(SubtaskModel::TABLE.'.status', SubtaskModel::STATUS_DONE); - - return $this->applySubQueryFilter($subquery); - } - - /** - * Apply subquery filter - * - * @access protected - * @param Table $subquery - * @return Table - */ - protected function applySubQueryFilter(Table $subquery) - { - if (is_int($this->value) || ctype_digit($this->value)) { - $subquery->eq(SubtaskModel::TABLE.'.user_id', $this->value); - } else { - switch ($this->value) { - case 'me': - $subquery->eq(SubtaskModel::TABLE.'.user_id', $this->currentUserId); - break; - case 'nobody': - $subquery->eq(SubtaskModel::TABLE.'.user_id', 0); - break; - default: - $subquery->beginOr(); - $subquery->ilike(UserModel::TABLE.'.username', $this->value.'%'); - $subquery->ilike(UserModel::TABLE.'.name', '%'.$this->value.'%'); - $subquery->closeOr(); - } - } - - return $subquery; - } -} diff --git a/sources/app/Filter/TaskSwimlaneFilter.php b/sources/app/Filter/TaskSwimlaneFilter.php deleted file mode 100644 index 0724396..0000000 --- a/sources/app/Filter/TaskSwimlaneFilter.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\ProjectModel; -use Kanboard\Model\SwimlaneModel; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by swimlane - * - * @package filter - * @author Frederic Guillot - */ -class TaskSwimlaneFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('swimlane'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (is_int($this->value) || ctype_digit($this->value)) { - $this->query->eq(TaskModel::TABLE.'.swimlane_id', $this->value); - } elseif ($this->value === 'default') { - $this->query->eq(TaskModel::TABLE.'.swimlane_id', 0); - } else { - $this->query->beginOr(); - $this->query->ilike(SwimlaneModel::TABLE.'.name', $this->value); - $this->query->ilike(ProjectModel::TABLE.'.default_swimlane', $this->value); - $this->query->closeOr(); - } - - return $this; - } -} diff --git a/sources/app/Filter/TaskTagFilter.php b/sources/app/Filter/TaskTagFilter.php deleted file mode 100644 index 01b6f62..0000000 --- a/sources/app/Filter/TaskTagFilter.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TagModel; -use Kanboard\Model\TaskModel; -use Kanboard\Model\TaskTagModel; -use PicoDb\Database; - -/** - * Class TaskTagFilter - * - * @package Kanboard\Filter - * @author Frederic Guillot - */ -class TaskTagFilter extends BaseFilter implements FilterInterface -{ - /** - * Database object - * - * @access private - * @var Database - */ - private $db; - - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('tag'); - } - - /** - * Set database object - * - * @access public - * @param Database $db - * @return $this - */ - public function setDatabase(Database $db) - { - $this->db = $db; - return $this; - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $task_ids = $this->db - ->table(TagModel::TABLE) - ->ilike(TagModel::TABLE.'.name', $this->value) - ->asc(TagModel::TABLE.'.project_id') - ->join(TaskTagModel::TABLE, 'tag_id', 'id') - ->findAllByColumn(TaskTagModel::TABLE.'.task_id'); - - if (empty($task_ids)) { - $task_ids = array(-1); - } - - $this->query->in(TaskModel::TABLE.'.id', $task_ids); - - return $this; - } -} diff --git a/sources/app/Filter/TaskTitleFilter.php b/sources/app/Filter/TaskTitleFilter.php deleted file mode 100644 index 4e3a2df..0000000 --- a/sources/app/Filter/TaskTitleFilter.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; -use Kanboard\Model\TaskModel; - -/** - * Filter tasks by title - * - * @package filter - * @author Frederic Guillot - */ -class TaskTitleFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('title'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - if (ctype_digit($this->value) || (strlen($this->value) > 1 && $this->value{0} === '#' && ctype_digit(substr($this->value, 1)))) { - $this->query->beginOr(); - $this->query->eq(TaskModel::TABLE.'.id', str_replace('#', '', $this->value)); - $this->query->ilike(TaskModel::TABLE.'.title', '%'.$this->value.'%'); - $this->query->closeOr(); - } else { - $this->query->ilike(TaskModel::TABLE.'.title', '%'.$this->value.'%'); - } - - return $this; - } -} diff --git a/sources/app/Filter/UserNameFilter.php b/sources/app/Filter/UserNameFilter.php deleted file mode 100644 index dfb07fd..0000000 --- a/sources/app/Filter/UserNameFilter.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -namespace Kanboard\Filter; - -use Kanboard\Core\Filter\FilterInterface; - -class UserNameFilter extends BaseFilter implements FilterInterface -{ - /** - * Get search attribute - * - * @access public - * @return string[] - */ - public function getAttributes() - { - return array('name'); - } - - /** - * Apply filter - * - * @access public - * @return FilterInterface - */ - public function apply() - { - $this->query->beginOr() - ->ilike('username', '%'.$this->value.'%') - ->ilike('name', '%'.$this->value.'%') - ->closeOr(); - - return $this; - } -} diff --git a/sources/app/Formatter/BaseFormatter.php b/sources/app/Formatter/BaseFormatter.php deleted file mode 100644 index 89c4843..0000000 --- a/sources/app/Formatter/BaseFormatter.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Base; -use PicoDb\Table; -use Pimple\Container; - -/** - * Class BaseFormatter - * - * @package formatter - * @author Frederic Guillot - */ -abstract class BaseFormatter extends Base -{ - /** - * Query object - * - * @access protected - * @var Table - */ - 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 - * @param Table $query - * @return $this - */ - public function withQuery(Table $query) - { - $this->query = $query; - return $this; - } -} diff --git a/sources/app/Formatter/BaseTaskCalendarFormatter.php b/sources/app/Formatter/BaseTaskCalendarFormatter.php deleted file mode 100644 index 8fab3e9..0000000 --- a/sources/app/Formatter/BaseTaskCalendarFormatter.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Common class to handle calendar events - * - * @package formatter - * @author Frederic Guillot - */ -abstract class BaseTaskCalendarFormatter extends BaseFormatter -{ - /** - * Column used for event start date - * - * @access protected - * @var string - */ - protected $startColumn = 'date_started'; - - /** - * Column used for event end date - * - * @access protected - * @var string - */ - protected $endColumn = 'date_completed'; - - /** - * Transform results to calendar events - * - * @access public - * @param string $start_column Column name for the start date - * @param string $end_column Column name for the end date - * @return FormatterInterface - */ - public function setColumns($start_column, $end_column = '') - { - $this->startColumn = $start_column; - $this->endColumn = $end_column ?: $start_column; - return $this; - } -} diff --git a/sources/app/Formatter/BoardColumnFormatter.php b/sources/app/Formatter/BoardColumnFormatter.php deleted file mode 100644 index d49a577..0000000 --- a/sources/app/Formatter/BoardColumnFormatter.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Board Column Formatter - * - * @package formatter - * @author Frederic Guillot - */ -class BoardColumnFormatter extends BaseFormatter implements FormatterInterface -{ - protected $swimlaneId = 0; - protected $columns = array(); - protected $tasks = array(); - protected $tags = array(); - - /** - * Set swimlaneId - * - * @access public - * @param integer $swimlaneId - * @return $this - */ - public function withSwimlaneId($swimlaneId) - { - $this->swimlaneId = $swimlaneId; - return $this; - } - - /** - * Set columns - * - * @access public - * @param array $columns - * @return $this - */ - public function withColumns(array $columns) - { - $this->columns = $columns; - return $this; - } - - /** - * Set tasks - * - * @access public - * @param array $tasks - * @return $this - */ - public function withTasks(array $tasks) - { - $this->tasks = $tasks; - return $this; - } - - /** - * Set tags - * - * @access public - * @param array $tags - * @return $this - */ - public function withTags(array $tags) - { - $this->tags = $tags; - return $this; - } - - /** - * Apply formatter - * - * @access public - * @return array - */ - public function format() - { - foreach ($this->columns as &$column) { - $column['tasks'] = BoardTaskFormatter::getInstance($this->container) - ->withTasks($this->tasks) - ->withTags($this->tags) - ->withSwimlaneId($this->swimlaneId) - ->withColumnId($column['id']) - ->format(); - - $column['nb_tasks'] = count($column['tasks']); - $column['score'] = (int) array_column_sum($column['tasks'], 'score'); - } - - return $this->columns; - } -} diff --git a/sources/app/Formatter/BoardFormatter.php b/sources/app/Formatter/BoardFormatter.php deleted file mode 100644 index 350dde6..0000000 --- a/sources/app/Formatter/BoardFormatter.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; -use Kanboard\Model\TaskModel; - -/** - * Board Formatter - * - * @package formatter - * @author Frederic Guillot - */ -class BoardFormatter extends BaseFormatter implements FormatterInterface -{ - /** - * Project id - * - * @access protected - * @var integer - */ - protected $projectId; - - /** - * Set ProjectId - * - * @access public - * @param integer $projectId - * @return $this - */ - public function withProjectId($projectId) - { - $this->projectId = $projectId; - return $this; - } - - /** - * Apply formatter - * - * @access public - * @return array - */ - public function format() - { - $swimlanes = $this->swimlaneModel->getSwimlanes($this->projectId); - $columns = $this->columnModel->getAll($this->projectId); - $tasks = $this->query - ->eq(TaskModel::TABLE.'.project_id', $this->projectId) - ->asc(TaskModel::TABLE.'.position') - ->findAll(); - - $task_ids = array_column($tasks, 'id'); - $tags = $this->taskTagModel->getTagsByTasks($task_ids); - - if (empty($swimlanes) || empty($columns)) { - return array(); - } - - return BoardSwimlaneFormatter::getInstance($this->container) - ->withSwimlanes($swimlanes) - ->withColumns($columns) - ->withTasks($tasks) - ->withTags($tags) - ->format(); - } -} diff --git a/sources/app/Formatter/BoardSwimlaneFormatter.php b/sources/app/Formatter/BoardSwimlaneFormatter.php deleted file mode 100644 index c2abb44..0000000 --- a/sources/app/Formatter/BoardSwimlaneFormatter.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Board Swimlane Formatter - * - * @package formatter - * @author Frederic Guillot - */ -class BoardSwimlaneFormatter extends BaseFormatter implements FormatterInterface -{ - protected $swimlanes = array(); - protected $columns = array(); - protected $tasks = array(); - protected $tags = array(); - - /** - * Set swimlanes - * - * @access public - * @param array $swimlanes - * @return $this - */ - public function withSwimlanes($swimlanes) - { - $this->swimlanes = $swimlanes; - return $this; - } - - /** - * Set columns - * - * @access public - * @param array $columns - * @return $this - */ - public function withColumns($columns) - { - $this->columns = $columns; - return $this; - } - - /** - * Set tasks - * - * @access public - * @param array $tasks - * @return $this - */ - public function withTasks(array $tasks) - { - $this->tasks = $tasks; - return $this; - } - - /** - * Set tags - * - * @access public - * @param array $tags - * @return $this - */ - public function withTags(array $tags) - { - $this->tags = $tags; - return $this; - } - - /** - * Apply formatter - * - * @access public - * @return array - */ - public function format() - { - $nb_swimlanes = count($this->swimlanes); - $nb_columns = count($this->columns); - - foreach ($this->swimlanes as &$swimlane) { - $swimlane['columns'] = BoardColumnFormatter::getInstance($this->container) - ->withSwimlaneId($swimlane['id']) - ->withColumns($this->columns) - ->withTasks($this->tasks) - ->withTags($this->tags) - ->format(); - - $swimlane['nb_swimlanes'] = $nb_swimlanes; - $swimlane['nb_columns'] = $nb_columns; - $swimlane['nb_tasks'] = array_column_sum($swimlane['columns'], 'nb_tasks'); - $swimlane['score'] = array_column_sum($swimlane['columns'], 'score'); - - $this->calculateStatsByColumnAcrossSwimlanes($swimlane['columns']); - } - - return $this->swimlanes; - } - - /** - * Calculate stats for each column acrosss all swimlanes - * - * @access protected - * @param array $columns - */ - protected function calculateStatsByColumnAcrossSwimlanes(array $columns) - { - foreach ($columns as $columnIndex => $column) { - if (! isset($this->swimlanes[0]['columns'][$columnIndex]['column_nb_tasks'])) { - $this->swimlanes[0]['columns'][$columnIndex]['column_nb_tasks'] = 0; - $this->swimlanes[0]['columns'][$columnIndex]['column_score'] = 0; - } - - $this->swimlanes[0]['columns'][$columnIndex]['column_nb_tasks'] += $column['nb_tasks']; - $this->swimlanes[0]['columns'][$columnIndex]['column_score'] += $column['score']; - } - } -} diff --git a/sources/app/Formatter/BoardTaskFormatter.php b/sources/app/Formatter/BoardTaskFormatter.php deleted file mode 100644 index 3bf171b..0000000 --- a/sources/app/Formatter/BoardTaskFormatter.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Board Task Formatter - * - * @package formatter - * @author Frederic Guillot - */ -class BoardTaskFormatter extends BaseFormatter implements FormatterInterface -{ - protected $tasks = array(); - protected $tags = array(); - protected $columnId = 0; - protected $swimlaneId = 0; - - /** - * Set tags - * - * @access public - * @param array $tags - * @return $this - */ - public function withTags(array $tags) - { - $this->tags = $tags; - return $this; - } - - /** - * Set tasks - * - * @access public - * @param array $tasks - * @return $this - */ - public function withTasks(array $tasks) - { - $this->tasks = $tasks; - return $this; - } - - /** - * Set columnId - * - * @access public - * @param integer $columnId - * @return $this - */ - public function withColumnId($columnId) - { - $this->columnId = $columnId; - return $this; - } - - /** - * Set swimlaneId - * - * @access public - * @param integer $swimlaneId - * @return $this - */ - public function withSwimlaneId($swimlaneId) - { - $this->swimlaneId = $swimlaneId; - return $this; - } - - /** - * Apply formatter - * - * @access public - * @return array - */ - public function format() - { - $tasks = array_values(array_filter($this->tasks, array($this, 'filterTasks'))); - array_merge_relation($tasks, $this->tags, 'tags', 'id'); - return $tasks; - } - - /** - * Keep only tasks of the given column and swimlane - * - * @access protected - * @param array $task - * @return bool - */ - protected function filterTasks(array $task) - { - return $task['column_id'] == $this->columnId && $task['swimlane_id'] == $this->swimlaneId; - } -} diff --git a/sources/app/Formatter/GroupAutoCompleteFormatter.php b/sources/app/Formatter/GroupAutoCompleteFormatter.php deleted file mode 100644 index 4d55288..0000000 --- a/sources/app/Formatter/GroupAutoCompleteFormatter.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; -use Kanboard\Core\Group\GroupProviderInterface; -use PicoDb\Table; - -/** - * Auto-complete formatter for groups - * - * @package formatter - * @author Frederic Guillot - */ -class GroupAutoCompleteFormatter implements FormatterInterface -{ - /** - * Groups found - * - * @access private - * @var GroupProviderInterface[] - */ - private $groups; - - /** - * Format groups for the ajax auto-completion - * - * @access public - * @param GroupProviderInterface[] $groups - */ - public function __construct(array $groups) - { - $this->groups = $groups; - } - - /** - * Set query - * - * @access public - * @param Table $query - * @return FormatterInterface - */ - public function withQuery(Table $query) - { - return $this; - } - - /** - * Format groups for the ajax auto-completion - * - * @access public - * @return array - */ - public function format() - { - $result = array(); - - foreach ($this->groups as $group) { - $result[] = array( - 'id' => $group->getInternalId(), - 'external_id' => $group->getExternalId(), - 'value' => $group->getName(), - 'label' => $group->getName(), - ); - } - - return $result; - } -} diff --git a/sources/app/Formatter/ProjectActivityEventFormatter.php b/sources/app/Formatter/ProjectActivityEventFormatter.php deleted file mode 100644 index aa0ea7c..0000000 --- a/sources/app/Formatter/ProjectActivityEventFormatter.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -class ProjectActivityEventFormatter extends BaseFormatter implements FormatterInterface -{ - /** - * Apply formatter - * - * @access public - * @return array - */ - public function format() - { - $events = $this->query->findAll(); - - foreach ($events as &$event) { - $event += $this->unserializeEvent($event['data']); - unset($event['data']); - - $event['author'] = $event['author_name'] ?: $event['author_username']; - $event['event_title'] = $this->notificationModel->getTitleWithAuthor($event['author'], $event['event_name'], $event); - $event['event_content'] = $this->renderEvent($event); - } - - return $events; - } - - /** - * Decode event data, supports unserialize() and json_decode() - * - * @access protected - * @param string $data Serialized data - * @return array - */ - protected function unserializeEvent($data) - { - if ($data{0} === 'a') { - return unserialize($data); - } - - return json_decode($data, true) ?: array(); - } - - /** - * Get the event html content - * - * @access protected - * @param array $params Event properties - * @return string - */ - protected function renderEvent(array $params) - { - return $this->template->render( - 'event/'.str_replace('.', '_', $params['event_name']), - $params - ); - } -} diff --git a/sources/app/Formatter/ProjectGanttFormatter.php b/sources/app/Formatter/ProjectGanttFormatter.php deleted file mode 100644 index af04f49..0000000 --- a/sources/app/Formatter/ProjectGanttFormatter.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Gantt chart formatter for projects - * - * @package formatter - * @author Frederic Guillot - */ -class ProjectGanttFormatter extends BaseFormatter implements FormatterInterface -{ - /** - * Format projects to be displayed in the Gantt chart - * - * @access public - * @return array - */ - public function format() - { - $projects = $this->query->findAll(); - $colors = $this->colorModel->getDefaultColors(); - $bars = array(); - - foreach ($projects as $project) { - $start = empty($project['start_date']) ? time() : strtotime($project['start_date']); - $end = empty($project['end_date']) ? $start : strtotime($project['end_date']); - $color = next($colors) ?: reset($colors); - - $bars[] = array( - 'type' => 'project', - 'id' => $project['id'], - 'title' => $project['name'], - 'start' => array( - (int) date('Y', $start), - (int) date('n', $start), - (int) date('j', $start), - ), - 'end' => array( - (int) date('Y', $end), - (int) date('n', $end), - (int) date('j', $end), - ), - 'link' => $this->helper->url->href('ProjectViewController', 'show', array('project_id' => $project['id'])), - 'board_link' => $this->helper->url->href('BoardViewController', 'show', array('project_id' => $project['id'])), - 'gantt_link' => $this->helper->url->href('TaskGanttController', 'show', array('project_id' => $project['id'])), - 'color' => $color, - 'not_defined' => empty($project['start_date']) || empty($project['end_date']), - 'users' => $this->projectUserRoleModel->getAllUsersGroupedByRole($project['id']), - ); - } - - return $bars; - } -} diff --git a/sources/app/Formatter/SubtaskTimeTrackingCalendarFormatter.php b/sources/app/Formatter/SubtaskTimeTrackingCalendarFormatter.php deleted file mode 100644 index b7b81d8..0000000 --- a/sources/app/Formatter/SubtaskTimeTrackingCalendarFormatter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -class SubtaskTimeTrackingCalendarFormatter extends BaseFormatter implements FormatterInterface -{ - /** - * Format calendar events - * - * @access public - * @return array - */ - public function format() - { - $events = array(); - - foreach ($this->query->findAll() as $row) { - $user = isset($row['username']) ? ' ('.($row['user_fullname'] ?: $row['username']).')' : ''; - - $events[] = array( - 'id' => $row['id'], - 'subtask_id' => $row['subtask_id'], - 'title' => t('#%d', $row['task_id']).' '.$row['subtask_title'].$user, - 'start' => date('Y-m-d\TH:i:s', $row['start']), - 'end' => date('Y-m-d\TH:i:s', $row['end'] ?: time()), - 'backgroundColor' => $this->colorModel->getBackgroundColor($row['color_id']), - 'borderColor' => $this->colorModel->getBorderColor($row['color_id']), - 'textColor' => 'black', - 'url' => $this->helper->url->to('TaskViewController', 'show', array('task_id' => $row['task_id'], 'project_id' => $row['project_id'])), - 'editable' => false, - ); - } - - return $events; - } -} diff --git a/sources/app/Formatter/TaskAutoCompleteFormatter.php b/sources/app/Formatter/TaskAutoCompleteFormatter.php deleted file mode 100644 index 4f1c4c6..0000000 --- a/sources/app/Formatter/TaskAutoCompleteFormatter.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; -use Kanboard\Model\TaskModel; - -/** - * Task AutoComplete Formatter - * - * @package formatter - * @author Frederic Guillot - */ -class TaskAutoCompleteFormatter extends BaseFormatter implements FormatterInterface -{ - /** - * Apply formatter - * - * @access public - * @return array - */ - public function format() - { - $tasks = $this->query->columns(TaskModel::TABLE.'.id', TaskModel::TABLE.'.title')->findAll(); - - foreach ($tasks as &$task) { - $task['value'] = $task['title']; - $task['label'] = '#'.$task['id'].' - '.$task['title']; - } - - return $tasks; - } -} diff --git a/sources/app/Formatter/TaskCalendarFormatter.php b/sources/app/Formatter/TaskCalendarFormatter.php deleted file mode 100644 index 75d2a83..0000000 --- a/sources/app/Formatter/TaskCalendarFormatter.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Calendar event formatter for task filter - * - * @package formatter - * @author Frederic Guillot - */ -class TaskCalendarFormatter extends BaseTaskCalendarFormatter implements FormatterInterface -{ - /** - * Full day event flag - * - * @access private - * @var boolean - */ - private $fullDay = false; - - /** - * When called calendar events will be full day - * - * @access public - * @return FormatterInterface - */ - public function setFullDay() - { - $this->fullDay = true; - return $this; - } - - /** - * Transform tasks to calendar events - * - * @access public - * @return array - */ - public function format() - { - $events = array(); - - foreach ($this->query->findAll() as $task) { - $events[] = array( - 'timezoneParam' => $this->timezoneModel->getCurrentTimezone(), - 'id' => $task['id'], - 'title' => t('#%d', $task['id']).' '.$task['title'], - 'backgroundColor' => $this->colorModel->getBackgroundColor($task['color_id']), - 'borderColor' => $this->colorModel->getBorderColor($task['color_id']), - 'textColor' => 'black', - 'url' => $this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), - 'start' => date($this->getDateTimeFormat(), $task[$this->startColumn]), - 'end' => date($this->getDateTimeFormat(), $task[$this->endColumn] ?: time()), - 'editable' => $this->fullDay, - 'allday' => $this->fullDay, - ); - } - - return $events; - } - - /** - * Get DateTime format for event - * - * @access private - * @return string - */ - private function getDateTimeFormat() - { - return $this->fullDay ? 'Y-m-d' : 'Y-m-d\TH:i:s'; - } -} diff --git a/sources/app/Formatter/TaskGanttFormatter.php b/sources/app/Formatter/TaskGanttFormatter.php deleted file mode 100644 index ddb3f93..0000000 --- a/sources/app/Formatter/TaskGanttFormatter.php +++ /dev/null @@ -1,78 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Task Gantt Formatter - * - * @package formatter - * @author Frederic Guillot - */ -class TaskGanttFormatter extends BaseFormatter implements FormatterInterface -{ - /** - * Local cache for project columns - * - * @access private - * @var array - */ - private $columns = array(); - - /** - * Apply formatter - * - * @access public - * @return array - */ - public function format() - { - $bars = array(); - - foreach ($this->query->findAll() as $task) { - $bars[] = $this->formatTask($task); - } - - return $bars; - } - - /** - * Format a single task - * - * @access private - * @param array $task - * @return array - */ - private function formatTask(array $task) - { - if (! isset($this->columns[$task['project_id']])) { - $this->columns[$task['project_id']] = $this->columnModel->getList($task['project_id']); - } - - $start = $task['date_started'] ?: time(); - $end = $task['date_due'] ?: $start; - - return array( - 'type' => 'task', - 'id' => $task['id'], - 'title' => $task['title'], - 'start' => array( - (int) date('Y', $start), - (int) date('n', $start), - (int) date('j', $start), - ), - 'end' => array( - (int) date('Y', $end), - (int) date('n', $end), - (int) date('j', $end), - ), - 'column_title' => $task['column_name'], - 'assignee' => $task['assignee_name'] ?: $task['assignee_username'], - 'progress' => $this->taskModel->getProgress($task, $this->columns[$task['project_id']]).'%', - 'link' => $this->helper->url->href('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), - 'color' => $this->colorModel->getColorProperties($task['color_id']), - 'not_defined' => empty($task['date_due']) || empty($task['date_started']), - ); - } -} diff --git a/sources/app/Formatter/TaskICalFormatter.php b/sources/app/Formatter/TaskICalFormatter.php deleted file mode 100644 index ad2a444..0000000 --- a/sources/app/Formatter/TaskICalFormatter.php +++ /dev/null @@ -1,143 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use DateTime; -use Eluceo\iCal\Component\Calendar; -use Eluceo\iCal\Component\Event; -use Eluceo\iCal\Property\Event\Attendees; -use Eluceo\iCal\Property\Event\Organizer; -use Kanboard\Core\Filter\FormatterInterface; - -/** - * iCal event formatter for tasks - * - * @package formatter - * @author Frederic Guillot - */ -class TaskICalFormatter extends BaseTaskCalendarFormatter implements FormatterInterface -{ - /** - * Calendar object - * - * @access private - * @var \Eluceo\iCal\Component\Calendar - */ - private $vCalendar; - - /** - * Get Ical events - * - * @access public - * @return string - */ - public function format() - { - return $this->vCalendar->render(); - } - - /** - * Set calendar object - * - * @access public - * @param \Eluceo\iCal\Component\Calendar $vCalendar - * @return FormatterInterface - */ - public function setCalendar(Calendar $vCalendar) - { - $this->vCalendar = $vCalendar; - return $this; - } - - /** - * Transform results to iCal events - * - * @access public - * @return FormatterInterface - */ - public function addDateTimeEvents() - { - foreach ($this->query->findAll() as $task) { - $start = new DateTime; - $start->setTimestamp($task[$this->startColumn]); - - $end = new DateTime; - $end->setTimestamp($task[$this->endColumn] ?: time()); - - $vEvent = $this->getTaskIcalEvent($task, 'task-#'.$task['id'].'-'.$this->startColumn.'-'.$this->endColumn); - $vEvent->setDtStart($start); - $vEvent->setDtEnd($end); - - $this->vCalendar->addComponent($vEvent); - } - - return $this; - } - - /** - * Transform results to all day iCal events - * - * @access public - * @return FormatterInterface - */ - public function addFullDayEvents() - { - foreach ($this->query->findAll() as $task) { - $date = new DateTime; - $date->setTimestamp($task[$this->startColumn]); - - $vEvent = $this->getTaskIcalEvent($task, 'task-#'.$task['id'].'-'.$this->startColumn); - $vEvent->setDtStart($date); - $vEvent->setDtEnd($date); - $vEvent->setNoTime(true); - - $this->vCalendar->addComponent($vEvent); - } - - return $this; - } - - /** - * Get common events for task iCal events - * - * @access protected - * @param array $task - * @param string $uid - * @return Event - */ - protected function getTaskIcalEvent(array &$task, $uid) - { - $dateCreation = new DateTime; - $dateCreation->setTimestamp($task['date_creation']); - - $dateModif = new DateTime; - $dateModif->setTimestamp($task['date_modification']); - - $vEvent = new Event($uid); - $vEvent->setCreated($dateCreation); - $vEvent->setModified($dateModif); - $vEvent->setUseTimezone(true); - $vEvent->setSummary(t('#%d', $task['id']).' '.$task['title']); - $vEvent->setDescription($task['description']); - $vEvent->setDescriptionHTML($this->helper->text->markdown($task['description'])); - $vEvent->setUrl($this->helper->url->base().$this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); - - if (! empty($task['owner_id'])) { - $attendees = new Attendees; - $attendees->add( - 'MAILTO:'.($task['assignee_email'] ?: $task['assignee_username'].'@kanboard.local'), - array('CN' => $task['assignee_name'] ?: $task['assignee_username']) - ); - $vEvent->setAttendees($attendees); - } - - if (! empty($task['creator_id'])) { - $vEvent->setOrganizer(new Organizer( - 'MAILTO:' . $task['creator_email'] ?: $task['creator_username'].'@kanboard.local', - array('CN' => $task['creator_name'] ?: $task['creator_username']) - )); - } - - return $vEvent; - } -} diff --git a/sources/app/Formatter/UserAutoCompleteFormatter.php b/sources/app/Formatter/UserAutoCompleteFormatter.php deleted file mode 100644 index cd23a2a..0000000 --- a/sources/app/Formatter/UserAutoCompleteFormatter.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace Kanboard\Formatter; - -use Kanboard\Model\UserModel; -use Kanboard\Core\Filter\FormatterInterface; - -/** - * Auto-complete formatter for user filter - * - * @package formatter - * @author Frederic Guillot - */ -class UserAutoCompleteFormatter extends BaseFormatter implements FormatterInterface -{ - /** - * Format the tasks for the ajax autocompletion - * - * @access public - * @return array - */ - public function format() - { - $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['label'] = $user['username']; - } else { - $user['label'] = $user['name'].' ('.$user['username'].')'; - } - } - - return $users; - } -} diff --git a/sources/app/Group/DatabaseBackendGroupProvider.php b/sources/app/Group/DatabaseBackendGroupProvider.php deleted file mode 100644 index 29d04d5..0000000 --- a/sources/app/Group/DatabaseBackendGroupProvider.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -namespace Kanboard\Group; - -use Kanboard\Core\Base; -use Kanboard\Core\Group\GroupBackendProviderInterface; - -/** - * Database Backend Group Provider - * - * @package group - * @author Frederic Guillot - */ -class DatabaseBackendGroupProvider extends Base implements GroupBackendProviderInterface -{ - /** - * Find a group from a search query - * - * @access public - * @param string $input - * @return DatabaseGroupProvider[] - */ - public function find($input) - { - $result = array(); - $groups = $this->groupModel->search($input); - - foreach ($groups as $group) { - $result[] = new DatabaseGroupProvider($group); - } - - return $result; - } -} diff --git a/sources/app/Group/DatabaseGroupProvider.php b/sources/app/Group/DatabaseGroupProvider.php deleted file mode 100644 index 430121a..0000000 --- a/sources/app/Group/DatabaseGroupProvider.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php - -namespace Kanboard\Group; - -use Kanboard\Core\Group\GroupProviderInterface; - -/** - * Database Group Provider - * - * @package group - * @author Frederic Guillot - */ -class DatabaseGroupProvider implements GroupProviderInterface -{ - /** - * Group properties - * - * @access private - * @var array - */ - private $group = array(); - - /** - * Constructor - * - * @access public - * @param array $group - */ - public function __construct(array $group) - { - $this->group = $group; - } - - /** - * Get internal id - * - * @access public - * @return integer - */ - public function getInternalId() - { - return (int) $this->group['id']; - } - - /** - * Get external id - * - * @access public - * @return string - */ - public function getExternalId() - { - return ''; - } - - /** - * Get group name - * - * @access public - * @return string - */ - public function getName() - { - return $this->group['name']; - } -} diff --git a/sources/app/Group/LdapBackendGroupProvider.php b/sources/app/Group/LdapBackendGroupProvider.php deleted file mode 100644 index cad732c..0000000 --- a/sources/app/Group/LdapBackendGroupProvider.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -namespace Kanboard\Group; - -use LogicException; -use Kanboard\Core\Base; -use Kanboard\Core\Group\GroupBackendProviderInterface; -use Kanboard\Core\Ldap\Client as LdapClient; -use Kanboard\Core\Ldap\ClientException as LdapException; -use Kanboard\Core\Ldap\Group as LdapGroup; - -/** - * LDAP Backend Group Provider - * - * @package group - * @author Frederic Guillot - */ -class LdapBackendGroupProvider extends Base implements GroupBackendProviderInterface -{ - /** - * Find a group from a search query - * - * @access public - * @param string $input - * @return LdapGroupProvider[] - */ - public function find($input) - { - try { - $ldap = LdapClient::connect(); - return LdapGroup::getGroups($ldap, $this->getLdapGroupPattern($input)); - - } catch (LdapException $e) { - $this->logger->error($e->getMessage()); - return array(); - } - } - - /** - * Get LDAP group pattern - * - * @access public - * @param string $input - * @return string - */ - public function getLdapGroupPattern($input) - { - if (LDAP_GROUP_FILTER === '') { - throw new LogicException('LDAP group filter empty, check the parameter LDAP_GROUP_FILTER'); - } - - return sprintf(LDAP_GROUP_FILTER, $input); - } -} diff --git a/sources/app/Group/LdapGroupProvider.php b/sources/app/Group/LdapGroupProvider.php deleted file mode 100644 index b497d48..0000000 --- a/sources/app/Group/LdapGroupProvider.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php - -namespace Kanboard\Group; - -use Kanboard\Core\Group\GroupProviderInterface; - -/** - * LDAP Group Provider - * - * @package group - * @author Frederic Guillot - */ -class LdapGroupProvider implements GroupProviderInterface -{ - /** - * Group DN - * - * @access private - * @var string - */ - private $dn = ''; - - /** - * Group Name - * - * @access private - * @var string - */ - private $name = ''; - - /** - * Constructor - * - * @access public - * @param string $dn - * @param string $name - */ - public function __construct($dn, $name) - { - $this->dn = $dn; - $this->name = $name; - } - - /** - * Get internal id - * - * @access public - * @return integer - */ - public function getInternalId() - { - return ''; - } - - /** - * Get external id - * - * @access public - * @return string - */ - public function getExternalId() - { - return $this->dn; - } - - /** - * Get group name - * - * @access public - * @return string - */ - public function getName() - { - return $this->name; - } -} diff --git a/sources/app/Helper/AppHelper.php b/sources/app/Helper/AppHelper.php deleted file mode 100644 index 09f280c..0000000 --- a/sources/app/Helper/AppHelper.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Application Helper - * - * @package helper - * @author Frederic Guillot - */ -class AppHelper extends Base -{ - /** - * Get config variable - * - * @access public - * @param string $param - * @param mixed $default_value - * @return mixed - */ - public function config($param, $default_value = '') - { - return $this->configModel->get($param, $default_value); - } - - /** - * Make sidebar menu active - * - * @access public - * @param string $controller - * @param string $action - * @param string $plugin - * @return string - */ - public function checkMenuSelection($controller, $action = '', $plugin = '') - { - $result = strtolower($this->getRouterController()) === strtolower($controller); - - if ($result && $action !== '') { - $result = strtolower($this->getRouterAction()) === strtolower($action); - } - - if ($result && $plugin !== '') { - $result = strtolower($this->getPluginName()) === strtolower($plugin); - } - - return $result ? 'class="active"' : ''; - } - - /** - * Get plugin name from route - * - * @access public - * @return string - */ - public function getPluginName() - { - return $this->router->getPlugin(); - } - - /** - * Get router controller - * - * @access public - * @return string - */ - public function getRouterController() - { - return $this->router->getController(); - } - - /** - * Get router action - * - * @access public - * @return string - */ - public function getRouterAction() - { - return $this->router->getAction(); - } - - /** - * Get javascript language code - * - * @access public - * @return string - */ - public function jsLang() - { - return $this->languageModel->getJsLanguageCode(); - } - - /** - * Get date format for Jquery DatePicker - * - * @access public - * @return string - */ - public function getJsDateFormat() - { - $format = $this->dateParser->getUserDateFormat(); - $format = str_replace('m', 'mm', $format); - $format = str_replace('Y', 'yy', $format); - $format = str_replace('d', 'dd', $format); - - return $format; - } - - /** - * Get time format for Jquery Plugin DateTimePicker - * - * @access public - * @return string - */ - public function getJsTimeFormat() - { - $format = $this->dateParser->getUserTimeFormat(); - $format = str_replace('H', 'HH', $format); - $format = str_replace('i', 'mm', $format); - $format = str_replace('g', 'h', $format); - $format = str_replace('a', 'tt', $format); - - return $format; - } - - /** - * Get current timezone - * - * @access public - * @return string - */ - public function getTimezone() - { - return $this->timezoneModel->getCurrentTimezone(); - } - - /** - * Get session flash message - * - * @access public - * @return string - */ - public function flashMessage() - { - $success_message = $this->flash->getMessage('success'); - $failure_message = $this->flash->getMessage('failure'); - - if (! empty($success_message)) { - return '<div class="alert alert-success alert-fade-out">'.$this->helper->text->e($success_message).'</div>'; - } - - if (! empty($failure_message)) { - return '<div class="alert alert-error">'.$this->helper->text->e($failure_message).'</div>'; - } - - return ''; - } -} diff --git a/sources/app/Helper/AssetHelper.php b/sources/app/Helper/AssetHelper.php deleted file mode 100644 index dad1448..0000000 --- a/sources/app/Helper/AssetHelper.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Asset Helper - * - * @package helper - * @author Frederic Guillot - */ -class AssetHelper extends Base -{ - /** - * Add a Javascript asset - * - * @param string $filename Filename - * @param bool $async - * @return string - */ - public function js($filename, $async = false) - { - return '<script '.($async ? 'async' : '').' type="text/javascript" src="'.$this->helper->url->dir().$filename.'?'.filemtime($filename).'"></script>'; - } - - /** - * Add a stylesheet asset - * - * @param string $filename Filename - * @param boolean $is_file Add file timestamp - * @param string $media Media - * @return string - */ - public function css($filename, $is_file = true, $media = 'screen') - { - return '<link rel="stylesheet" href="'.$this->helper->url->dir().$filename.($is_file ? '?'.filemtime($filename) : '').'" media="'.$media.'">'; - } - - /** - * Get custom css - * - * @access public - * @return string - */ - public function customCss() - { - if ($this->configModel->get('application_stylesheet')) { - return '<style>'.$this->configModel->get('application_stylesheet').'</style>'; - } - - return ''; - } - - /** - * Get CSS for task colors - * - * @access public - * @return string - */ - public function colorCss() - { - return '<style>'.$this->colorModel->getCss().'</style>'; - } -} diff --git a/sources/app/Helper/AvatarHelper.php b/sources/app/Helper/AvatarHelper.php deleted file mode 100644 index a36d9b4..0000000 --- a/sources/app/Helper/AvatarHelper.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Avatar Helper - * - * @package helper - * @author Frederic Guillot - */ -class AvatarHelper extends Base -{ - /** - * Render user avatar - * - * @access public - * @param string $user_id - * @param string $username - * @param string $name - * @param string $email - * @param string $avatar_path - * @param string $css - * @param int $size - * @return string - */ - public function render($user_id, $username, $name, $email, $avatar_path, $css = 'avatar-left', $size = 48) - { - if (empty($user_id) && empty($username)) { - $html = $this->avatarManager->renderDefault($size); - } else { - $html = $this->avatarManager->render($user_id, $username, $name, $email, $avatar_path, $size); - } - - return '<div class="avatar avatar-'.$size.' '.$css.'">'.$html.'</div>'; - } - - /** - * Render small user avatar - * - * @access public - * @param string $user_id - * @param string $username - * @param string $name - * @param string $email - * @param string $avatar_path - * @param string $css - * @return string - */ - public function small($user_id, $username, $name, $email, $avatar_path, $css = '') - { - return $this->render($user_id, $username, $name, $email, $avatar_path, $css, 20); - } - - /** - * Get a small avatar for the current user - * - * @access public - * @param string $css - * @return string - */ - public function currentUserSmall($css = '') - { - $user = $this->userSession->getAll(); - return $this->small($user['id'], $user['username'], $user['name'], $user['email'], $user['avatar_path'], $css); - } -} diff --git a/sources/app/Helper/BoardHelper.php b/sources/app/Helper/BoardHelper.php deleted file mode 100644 index a86a6c1..0000000 --- a/sources/app/Helper/BoardHelper.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Board Helper - * - * @package helper - * @author Frederic Guillot - */ -class BoardHelper extends Base -{ - /** - * Return true if tasks are collapsed - * - * @access public - * @param integer $project_id - * @return boolean - */ - public function isCollapsed($project_id) - { - return $this->userSession->isBoardCollapsed($project_id); - } -} diff --git a/sources/app/Helper/CalendarHelper.php b/sources/app/Helper/CalendarHelper.php deleted file mode 100644 index b35c40f..0000000 --- a/sources/app/Helper/CalendarHelper.php +++ /dev/null @@ -1,112 +0,0 @@ -<?php - -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 - * - * @package helper - * @author Frederic Guillot - */ -class CalendarHelper extends Base -{ - /** - * Get formatted calendar task due events - * - * @access public - * @param QueryBuilder $queryBuilder - * @param string $start - * @param string $end - * @return array - */ - public function getTaskDateDueEvents(QueryBuilder $queryBuilder, $start, $end) - { - $formatter = new TaskCalendarFormatter($this->container); - $formatter->setFullDay(); - $formatter->setColumns('date_due'); - - return $queryBuilder - ->withFilter(new TaskDueDateRangeFilter(array($start, $end))) - ->format($formatter); - } - - /** - * Get formatted calendar task events - * - * @access public - * @param QueryBuilder $queryBuilder - * @param string $start - * @param string $end - * @return array - */ - public function getTaskEvents(QueryBuilder $queryBuilder, $start, $end) - { - $startColumn = $this->configModel->get('calendar_project_tasks', 'date_started'); - - $queryBuilder->getQuery()->addCondition($this->getCalendarCondition( - $this->dateParser->getTimestampFromIsoFormat($start), - $this->dateParser->getTimestampFromIsoFormat($end), - $startColumn, - 'date_due' - )); - - $formatter = new TaskCalendarFormatter($this->container); - $formatter->setColumns($startColumn, 'date_due'); - - return $queryBuilder->format($formatter); - } - - /** - * Get formatted calendar subtask time tracking events - * - * @access public - * @param integer $user_id - * @param string $start - * @param string $end - * @return array - */ - public function getSubtaskTimeTrackingEvents($user_id, $start, $end) - { - $formatter = new SubtaskTimeTrackingCalendarFormatter($this->container); - return $formatter - ->withQuery($this->subtaskTimeTrackingModel->getUserQuery($user_id) - ->addCondition($this->getCalendarCondition( - $this->dateParser->getTimestampFromIsoFormat($start), - $this->dateParser->getTimestampFromIsoFormat($end), - 'start', - 'end' - )) - ) - ->format(); - } - - /** - * Build SQL condition for a given time range - * - * @access public - * @param string $start_time Start timestamp - * @param string $end_time End timestamp - * @param string $start_column Start column name - * @param string $end_column End column name - * @return string - */ - public function getCalendarCondition($start_time, $end_time, $start_column, $end_column) - { - $start_column = $this->db->escapeIdentifier($start_column); - $end_column = $this->db->escapeIdentifier($end_column); - - $conditions = array( - "($start_column >= '$start_time' AND $start_column <= '$end_time')", - "($start_column <= '$start_time' AND $end_column >= '$start_time')", - "($start_column <= '$start_time' AND ($end_column = '0' OR $end_column IS NULL))", - ); - - return $start_column.' IS NOT NULL AND '.$start_column.' > 0 AND ('.implode(' OR ', $conditions).')'; - } -} diff --git a/sources/app/Helper/DateHelper.php b/sources/app/Helper/DateHelper.php deleted file mode 100644 index 7e2ec79..0000000 --- a/sources/app/Helper/DateHelper.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use DateTime; -use Kanboard\Core\Base; - -/** - * DateTime helpers - * - * @package helper - * @author Frederic Guillot - */ -class DateHelper extends Base -{ - /** - * Get formatted time - * - * @access public - * @param integer $value - * @return string - */ - public function time($value) - { - return date($this->configModel->get('application_time_format', 'H:i'), $value); - } - - /** - * Get formatted date - * - * @access public - * @param integer $value - * @return string - */ - public function date($value) - { - if (empty($value)) { - return ''; - } - - if (! ctype_digit($value)) { - $value = strtotime($value); - } - - return date($this->configModel->get('application_date_format', 'm/d/Y'), $value); - } - - /** - * Get formatted datetime - * - * @access public - * @param integer $value - * @return string - */ - public function datetime($value) - { - return date($this->configModel->get('application_datetime_format', 'm/d/Y H:i'), $value); - } - - /** - * Get duration in seconds into human format - * - * @access public - * @param integer $seconds - * @return string - */ - public function duration($seconds) - { - if ($seconds == 0) { - return 0; - } - - $dtF = new DateTime("@0"); - $dtT = new DateTime("@$seconds"); - return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds'); - } - - /** - * Get the age of an item in quasi human readable format. - * It's in this format: <1h , NNh, NNd - * - * @access public - * @param integer $timestamp Unix timestamp of the artifact for which age will be calculated - * @param integer $now Compare with this timestamp (Default value is the current unix timestamp) - * @return string - */ - public function age($timestamp, $now = null) - { - if ($now === null) { - $now = time(); - } - - $diff = $now - $timestamp; - - if ($diff < 900) { - return t('<15m'); - } - if ($diff < 1200) { - return t('<30m'); - } elseif ($diff < 3600) { - return t('<1h'); - } elseif ($diff < 86400) { - return '~'.t('%dh', $diff / 3600); - } - - return t('%dd', ($now - $timestamp) / 86400); - } - - /** - * Get all hours for day - * - * @access public - * @return array - */ - public function getDayHours() - { - $values = array(); - - foreach (range(0, 23) as $hour) { - foreach (array(0, 30) as $minute) { - $time = sprintf('%02d:%02d', $hour, $minute); - $values[$time] = $time; - } - } - - return $values; - } - - /** - * Get all days of a week - * - * @access public - * @return array - */ - public function getWeekDays() - { - $values = array(); - - foreach (range(1, 7) as $day) { - $values[$day] = $this->getWeekDay($day); - } - - return $values; - } - - /** - * Get the localized day name from the day number - * - * @access public - * @param integer $day Day number - * @return string - */ - public function getWeekDay($day) - { - return date('l', strtotime('next Monday +'.($day - 1).' days')); - } -} diff --git a/sources/app/Helper/FileHelper.php b/sources/app/Helper/FileHelper.php deleted file mode 100644 index cabf371..0000000 --- a/sources/app/Helper/FileHelper.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * File helpers - * - * @package helper - * @author Frederic Guillot - */ -class FileHelper extends Base -{ - /** - * Get file icon - * - * @access public - * @param string $filename Filename - * @return string Font-Awesome-Icon-Name - */ - public function icon($filename) - { - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - - switch ($extension) { - case 'jpeg': - case 'jpg': - case 'png': - case 'gif': - return 'fa-file-image-o'; - case 'xls': - case 'xlsx': - return 'fa-file-excel-o'; - case 'doc': - case 'docx': - return 'fa-file-word-o'; - case 'ppt': - case 'pptx': - return 'fa-file-powerpoint-o'; - case 'zip': - case 'rar': - case 'tar': - case 'bz2': - case 'xz': - case 'gz': - return 'fa-file-archive-o'; - case 'mp3': - return 'fa-file-audio-o'; - case 'avi': - case 'mov': - return 'fa-file-video-o'; - case 'php': - case 'html': - case 'css': - return 'fa-file-code-o'; - case 'pdf': - return 'fa-file-pdf-o'; - } - - return 'fa-file-o'; - } - - /** - * Return the image mimetype based on the file extension - * - * @access public - * @param $filename - * @return string - */ - public function getImageMimeType($filename) - { - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - - switch ($extension) { - case 'jpeg': - case 'jpg': - return 'image/jpeg'; - case 'png': - return 'image/png'; - case 'gif': - return 'image/gif'; - default: - return 'image/jpeg'; - } - } - - /** - * Get the preview type - * - * @access public - * @param string $filename - * @return string - */ - public function getPreviewType($filename) - { - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - - switch ($extension) { - case 'md': - case 'markdown': - return 'markdown'; - case 'txt': - return 'text'; - } - - return null; - } -} diff --git a/sources/app/Helper/FormHelper.php b/sources/app/Helper/FormHelper.php deleted file mode 100644 index c2ea1d7..0000000 --- a/sources/app/Helper/FormHelper.php +++ /dev/null @@ -1,363 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Form helpers - * - * @package helper - * @author Frederic Guillot - */ -class FormHelper extends Base -{ - /** - * Hidden CSRF token field - * - * @access public - * @return string - */ - public function csrf() - { - return '<input type="hidden" name="csrf_token" value="'.$this->token->getCSRFToken().'"/>'; - } - - /** - * Display a hidden form field - * - * @access public - * @param string $name Field name - * @param array $values Form values - * @return string - */ - public function hidden($name, array $values = array()) - { - return '<input type="hidden" name="'.$name.'" id="form-'.$name.'" '.$this->formValue($values, $name).'/>'; - } - - /** - * Display a select field - * - * @access public - * @param string $name Field name - * @param array $options Options - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes - * @param string $class CSS class - * @return string - */ - public function select($name, array $options, array $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - $html = '<select name="'.$name.'" id="form-'.$name.'" class="'.$class.'" '.implode(' ', $attributes).'>'; - - foreach ($options as $id => $value) { - $html .= '<option value="'.$this->helper->text->e($id).'"'; - - if (isset($values->$name) && $id == $values->$name) { - $html .= ' selected="selected"'; - } - if (isset($values[$name]) && $id == $values[$name]) { - $html .= ' selected="selected"'; - } - - $html .= '>'.$this->helper->text->e($value).'</option>'; - } - - $html .= '</select>'; - $html .= $this->errorList($errors, $name); - - return $html; - } - - /** - * Display a radio field group - * - * @access public - * @param string $name Field name - * @param array $options Options - * @param array $values Form values - * @return string - */ - public function radios($name, array $options, array $values = array()) - { - $html = ''; - - foreach ($options as $value => $label) { - $html .= $this->radio($name, $label, $value, isset($values[$name]) && $values[$name] == $value); - } - - return $html; - } - - /** - * Display a radio field - * - * @access public - * @param string $name Field name - * @param string $label Form label - * @param string $value Form value - * @param boolean $selected Field selected or not - * @param string $class CSS class - * @return string - */ - public function radio($name, $label, $value, $selected = false, $class = '') - { - return '<label><input type="radio" name="'.$name.'" class="'.$class.'" value="'.$this->helper->text->e($value).'" '.($selected ? 'checked="checked"' : '').'> '.$this->helper->text->e($label).'</label>'; - } - - /** - * Display a checkboxes group - * - * @access public - * @param string $name Field name - * @param array $options Options - * @param array $values Form values - * @return string - */ - public function checkboxes($name, array $options, array $values = array()) - { - $html = ''; - - foreach ($options as $value => $label) { - $html .= $this->checkbox($name.'['.$value.']', $label, $value, isset($values[$name]) && in_array($value, $values[$name])); - } - - return $html; - } - - /** - * 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 - * @return string - */ - public function checkbox($name, $label, $value, $checked = false, $class = '') - { - return '<label><input type="checkbox" name="'.$name.'" class="'.$class.'" value="'.$this->helper->text->e($value).'" '.($checked ? 'checked="checked"' : '').'> '.$this->helper->text->e($label).'</label>'; - } - - /** - * Display a form label - * - * @access public - * @param string $name Field name - * @param string $label Form label - * @param array $attributes HTML attributes - * @return string - */ - public function label($label, $name, array $attributes = array()) - { - return '<label for="form-'.$name.'" '.implode(' ', $attributes).'>'.$this->helper->text->e($label).'</label>'; - } - - /** - * Display a textarea - * - * @access public - * @param string $name Field name - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes HTML attributes - * @param string $class CSS class - * @return string - */ - public function textarea($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - $class .= $this->errorClass($errors, $name); - - $html = '<textarea name="'.$name.'" id="form-'.$name.'" class="'.$class.'" '; - $html .= implode(' ', $attributes).'>'; - $html .= isset($values->$name) ? $this->helper->text->e($values->$name) : isset($values[$name]) ? $values[$name] : ''; - $html .= '</textarea>'; - $html .= $this->errorList($errors, $name); - - return $html; - } - - /** - * Display file field - * - * @access public - * @param string $name - * @param array $errors - * @param boolean $multiple - * @return string - */ - public function file($name, array $errors = array(), $multiple = false) - { - $html = '<input type="file" name="'.$name.'" id="form-'.$name.'" '.($multiple ? 'multiple' : '').'>'; - $html .= $this->errorList($errors, $name); - - return $html; - } - - /** - * Display a input field - * - * @access public - * @param string $type HMTL input tag type - * @param string $name Field name - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes HTML attributes - * @param string $class CSS class - * @return string - */ - public function input($type, $name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - $class .= $this->errorClass($errors, $name); - - $html = '<input type="'.$type.'" name="'.$name.'" id="form-'.$name.'" '.$this->formValue($values, $name).' class="'.$class.'" '; - $html .= implode(' ', $attributes).'>'; - - if (in_array('required', $attributes)) { - $html .= '<span class="form-required">*</span>'; - } - - $html .= $this->errorList($errors, $name); - - return $html; - } - - /** - * Display a text field - * - * @access public - * @param string $name Field name - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes HTML attributes - * @param string $class CSS class - * @return string - */ - public function text($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - return $this->input('text', $name, $values, $errors, $attributes, $class); - } - - /** - * Display a password field - * - * @access public - * @param string $name Field name - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes HTML attributes - * @param string $class CSS class - * @return string - */ - public function password($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - return $this->input('password', $name, $values, $errors, $attributes, $class); - } - - /** - * Display an email field - * - * @access public - * @param string $name Field name - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes HTML attributes - * @param string $class CSS class - * @return string - */ - public function email($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - return $this->input('email', $name, $values, $errors, $attributes, $class); - } - - /** - * Display a number field - * - * @access public - * @param string $name Field name - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes HTML attributes - * @param string $class CSS class - * @return string - */ - public function number($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - return $this->input('number', $name, $values, $errors, $attributes, $class); - } - - /** - * Display a numeric field (allow decimal number) - * - * @access public - * @param string $name Field name - * @param array $values Form values - * @param array $errors Form errors - * @param array $attributes HTML attributes - * @param string $class CSS class - * @return string - */ - public function numeric($name, $values = array(), array $errors = array(), array $attributes = array(), $class = '') - { - return $this->input('text', $name, $values, $errors, $attributes, $class.' form-numeric'); - } - - /** - * Display the form error class - * - * @access private - * @param array $errors Error list - * @param string $name Field name - * @return string - */ - private function errorClass(array $errors, $name) - { - return ! isset($errors[$name]) ? '' : ' form-error'; - } - - /** - * Display a list of form errors - * - * @access private - * @param array $errors List of errors - * @param string $name Field name - * @return string - */ - private function errorList(array $errors, $name) - { - $html = ''; - - if (isset($errors[$name])) { - $html .= '<ul class="form-errors">'; - - foreach ($errors[$name] as $error) { - $html .= '<li>'.$this->helper->text->e($error).'</li>'; - } - - $html .= '</ul>'; - } - - return $html; - } - - /** - * Get an escaped form value - * - * @access private - * @param mixed $values Values - * @param string $name Field name - * @return string - */ - private function formValue($values, $name) - { - if (isset($values->$name)) { - return 'value="'.$this->helper->text->e($values->$name).'"'; - } - - return isset($values[$name]) ? 'value="'.$this->helper->text->e($values[$name]).'"' : ''; - } -} diff --git a/sources/app/Helper/HookHelper.php b/sources/app/Helper/HookHelper.php deleted file mode 100644 index 2d13ebc..0000000 --- a/sources/app/Helper/HookHelper.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Template Hook helpers - * - * @package helper - * @author Frederic Guillot - */ -class HookHelper extends Base -{ - /** - * Add assets JS or CSS - * - * @access public - * @param string $type - * @param string $hook - * @return string - */ - public function asset($type, $hook) - { - $buffer = ''; - - foreach ($this->hook->getListeners($hook) as $file) { - $buffer .= $this->helper->asset->$type($file); - } - - return $buffer; - } - - /** - * Render all attached hooks - * - * @access public - * @param string $hook - * @param array $variables - * @return string - */ - public function render($hook, array $variables = array()) - { - $buffer = ''; - - foreach ($this->hook->getListeners($hook) as $template) { - $buffer .= $this->template->render($template, $variables); - } - - return $buffer; - } - - /** - * Attach a template to a hook - * - * @access public - * @param string $hook - * @param string $template - * @return \Kanboard\Helper\Hook - */ - public function attach($hook, $template) - { - $this->hook->on($hook, $template); - return $this; - } -} diff --git a/sources/app/Helper/ICalHelper.php b/sources/app/Helper/ICalHelper.php deleted file mode 100644 index dc399bf..0000000 --- a/sources/app/Helper/ICalHelper.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -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; - -/** - * ICal Helper - * - * @package helper - * @author Frederic Guillot - */ -class ICalHelper extends Base -{ - /** - * Get formatted calendar task due events - * - * @access public - * @param QueryBuilder $queryBuilder - * @param iCalendar $calendar - * @param string $start - * @param string $end - */ - public function addTaskDateDueEvents(QueryBuilder $queryBuilder, iCalendar $calendar, $start, $end) - { - $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(); - } -} diff --git a/sources/app/Helper/LayoutHelper.php b/sources/app/Helper/LayoutHelper.php deleted file mode 100644 index 8ebb05d..0000000 --- a/sources/app/Helper/LayoutHelper.php +++ /dev/null @@ -1,202 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Layout Helper - * - * @package helper - * @author Frederic Guillot - */ -class LayoutHelper extends Base -{ - /** - * Render a template without the layout if Ajax request - * - * @access public - * @param string $template Template name - * @param array $params Template parameters - * @return string - */ - public function app($template, array $params = array()) - { - if ($this->request->isAjax()) { - return $this->template->render($template, $params); - } - - if (! isset($params['no_layout']) && ! isset($params['board_selector'])) { - $params['board_selector'] = $this->projectUserRoleModel->getActiveProjectsByUser($this->userSession->getId()); - } - - return $this->pageLayout($template, $params); - } - - /** - * Common layout for user views - * - * @access public - * @param string $template Template name - * @param array $params Template parameters - * @return string - */ - public function user($template, array $params) - { - if (isset($params['user'])) { - $params['title'] = '#'.$params['user']['id'].' '.($params['user']['name'] ?: $params['user']['username']); - } - - return $this->subLayout('user_view/layout', 'user_view/sidebar', $template, $params); - } - - /** - * Common layout for task views - * - * @access public - * @param string $template Template name - * @param array $params Template parameters - * @return string - */ - public function task($template, array $params) - { - $params['page_title'] = $params['task']['project_name'].', #'.$params['task']['id'].' - '.$params['task']['title']; - $params['title'] = $params['task']['project_name']; - return $this->subLayout('task/layout', 'task/sidebar', $template, $params); - } - - /** - * Common layout for project views - * - * @access public - * @param string $template - * @param array $params - * @param string $sidebar - * @return string - */ - public function project($template, array $params, $sidebar = 'project/sidebar') - { - if (empty($params['title'])) { - $params['title'] = $params['project']['name']; - } elseif ($params['project']['name'] !== $params['title']) { - $params['title'] = $params['project']['name'].' > '.$params['title']; - } - - return $this->subLayout('project/layout', $sidebar, $template, $params); - } - - /** - * Common layout for project user views - * - * @access public - * @param string $template - * @param array $params - * @return string - */ - public function projectUser($template, array $params) - { - $params['filter'] = array('user_id' => $params['user_id']); - return $this->subLayout('project_user_overview/layout', 'project_user_overview/sidebar', $template, $params); - } - - /** - * Common layout for config views - * - * @access public - * @param string $template - * @param array $params - * @return string - */ - public function config($template, array $params) - { - if (! isset($params['values'])) { - $params['values'] = $this->configModel->getAll(); - } - - if (! isset($params['errors'])) { - $params['errors'] = array(); - } - - return $this->subLayout('config/layout', 'config/sidebar', $template, $params); - } - - /** - * Common layout for plugin views - * - * @access public - * @param string $template - * @param array $params - * @return string - */ - public function plugin($template, array $params) - { - return $this->subLayout('plugin/layout', 'plugin/sidebar', $template, $params); - } - - /** - * Common layout for dashboard views - * - * @access public - * @param string $template - * @param array $params - * @return string - */ - public function dashboard($template, array $params) - { - return $this->subLayout('dashboard/layout', 'dashboard/sidebar', $template, $params); - } - - /** - * Common layout for analytic views - * - * @access public - * @param string $template - * @param array $params - * @return string - */ - public function analytic($template, array $params) - { - return $this->subLayout('analytic/layout', 'analytic/sidebar', $template, $params); - } - - /** - * Render page layout - * - * @access public - * @param string $template Template name - * @param array $params Key/value dictionary - * @param string $layout Layout name - * @return string - */ - public function pageLayout($template, array $params = array(), $layout = 'layout') - { - return $this->template->render( - $layout, - $params + array('content_for_layout' => $this->template->render($template, $params)) - ); - } - - /** - * Common method to generate a sub-layout - * - * @access public - * @param string $sublayout - * @param string $sidebar - * @param string $template - * @param array $params - * @return string - */ - public function subLayout($sublayout, $sidebar, $template, array $params = array()) - { - $content = $this->template->render($template, $params); - - if ($this->request->isAjax()) { - return $content; - } - - $params['content_for_sublayout'] = $content; - $params['sidebar_template'] = $sidebar; - - return $this->app($sublayout, $params); - } -} diff --git a/sources/app/Helper/MailHelper.php b/sources/app/Helper/MailHelper.php deleted file mode 100644 index 3b1c9e4..0000000 --- a/sources/app/Helper/MailHelper.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Class MailHelper - * - * @package Kanboard\Helper - * @author Frederic Guillot - */ -class MailHelper extends Base -{ - /** - * Get the mailbox hash from an email address - * - * @access public - * @param string $email - * @return string - */ - public function getMailboxHash($email) - { - if (! strpos($email, '@') || ! strpos($email, '+')) { - return ''; - } - - list($localPart, ) = explode('@', $email); - list(, $identifier) = explode('+', $localPart); - - return $identifier; - } - - /** - * Filter mail subject - * - * @access public - * @param string $subject - * @return string - */ - public function filterSubject($subject) - { - $subject = str_replace('RE: ', '', $subject); - $subject = str_replace('FW: ', '', $subject); - - return $subject; - } - - /** - * Get mail sender address - * - * @access public - * @return string - */ - public function getMailSenderAddress() - { - $email = $this->configModel->get('mail_sender_address'); - - if (!empty($email)) { - return $email; - } - - return MAIL_FROM; - } - - /** - * Get mail sender address - * - * @access public - * @return string - */ - public function getMailTransport() - { - $transport = $this->configModel->get('mail_transport'); - - if (!empty($transport)) { - return $transport; - } - - return MAIL_TRANSPORT; - } -} diff --git a/sources/app/Helper/ModelHelper.php b/sources/app/Helper/ModelHelper.php deleted file mode 100644 index d49637c..0000000 --- a/sources/app/Helper/ModelHelper.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Model Helper - * - * @package helper - * @author Frederic Guillot - */ -class ModelHelper extends Base -{ - /** - * Remove keys from an array - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys to remove - */ - public function removeFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (array_key_exists($key, $values)) { - unset($values[$key]); - } - } - } - - /** - * Remove keys from an array if empty - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys to remove - */ - public function removeEmptyFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (array_key_exists($key, $values) && empty($values[$key])) { - unset($values[$key]); - } - } - } - - /** - * Force fields to be at 0 if empty - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys - */ - public function resetFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (isset($values[$key]) && empty($values[$key])) { - $values[$key] = 0; - } - } - } - - /** - * Force some fields to be integer - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys - */ - public function convertIntegerFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (isset($values[$key])) { - $values[$key] = (int) $values[$key]; - } - } - } - - /** - * Force some fields to be null if empty - * - * @access public - * @param array $values Input array - * @param string[] $keys List of keys - */ - public function convertNullFields(array &$values, array $keys) - { - foreach ($keys as $key) { - if (array_key_exists($key, $values) && empty($values[$key])) { - $values[$key] = null; - } - } - } -} diff --git a/sources/app/Helper/ProjectActivityHelper.php b/sources/app/Helper/ProjectActivityHelper.php deleted file mode 100644 index 40f386d..0000000 --- a/sources/app/Helper/ProjectActivityHelper.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; -use Kanboard\Filter\ProjectActivityProjectIdFilter; -use Kanboard\Filter\ProjectActivityProjectIdsFilter; -use Kanboard\Filter\ProjectActivityTaskIdFilter; -use Kanboard\Formatter\ProjectActivityEventFormatter; -use Kanboard\Model\ProjectActivityModel; - -/** - * Project Activity Helper - * - * @package helper - * @author Frederic Guillot - */ -class ProjectActivityHelper extends Base -{ - /** - * Search events - * - * @access public - * @param string $search - * @return array - */ - public function searchEvents($search) - { - $projects = $this->projectUserRoleModel->getProjectsByUser($this->userSession->getId()); - $events = array(); - - if ($search !== '') { - $queryBuilder = $this->projectActivityLexer->build($search); - $queryBuilder - ->withFilter(new ProjectActivityProjectIdsFilter(array_keys($projects))) - ->getQuery() - ->desc(ProjectActivityModel::TABLE.'.id') - ->limit(500) - ; - - $events = $queryBuilder->format(new ProjectActivityEventFormatter($this->container)); - } - - return $events; - } - - /** - * Get project activity events - * - * @access public - * @param integer $project_id - * @param int $limit - * @return array - */ - public function getProjectEvents($project_id, $limit = 50) - { - $queryBuilder = $this->projectActivityQuery - ->withFilter(new ProjectActivityProjectIdFilter($project_id)); - - $queryBuilder->getQuery() - ->desc(ProjectActivityModel::TABLE.'.id') - ->limit($limit) - ; - - return $queryBuilder->format(new ProjectActivityEventFormatter($this->container)); - } - - /** - * Get projects activity events - * - * @access public - * @param int[] $project_ids - * @param int $limit - * @return array - */ - public function getProjectsEvents(array $project_ids, $limit = 50) - { - $queryBuilder = $this->projectActivityQuery - ->withFilter(new ProjectActivityProjectIdsFilter($project_ids)); - - $queryBuilder->getQuery() - ->desc(ProjectActivityModel::TABLE.'.id') - ->limit($limit) - ; - - return $queryBuilder->format(new ProjectActivityEventFormatter($this->container)); - } - - /** - * Get task activity events - * - * @access public - * @param integer $task_id - * @return array - */ - public function getTaskEvents($task_id) - { - $queryBuilder = $this->projectActivityQuery - ->withFilter(new ProjectActivityTaskIdFilter($task_id)); - - $queryBuilder->getQuery()->desc(ProjectActivityModel::TABLE.'.id'); - - return $queryBuilder->format(new ProjectActivityEventFormatter($this->container)); - } -} diff --git a/sources/app/Helper/ProjectHeaderHelper.php b/sources/app/Helper/ProjectHeaderHelper.php deleted file mode 100644 index 9514f4f..0000000 --- a/sources/app/Helper/ProjectHeaderHelper.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Project Header Helper - * - * @package helper - * @author Frederic Guillot - */ -class ProjectHeaderHelper extends Base -{ - /** - * Get current search query - * - * @access public - * @param array $project - * @return string - */ - public function getSearchQuery(array $project) - { - $search = $this->request->getStringParam('search', $this->userSession->getFilters($project['id'])); - $this->userSession->setFilters($project['id'], $search); - return urldecode($search); - } - - /** - * Render project header (views switcher and search box) - * - * @access public - * @param array $project - * @param string $controller - * @param string $action - * @param bool $boardView - * @return string - */ - public function render(array $project, $controller, $action, $boardView = false) - { - $filters = array( - 'controller' => $controller, - 'action' => $action, - 'project_id' => $project['id'], - 'search' => $this->getSearchQuery($project), - ); - - return $this->template->render('project_header/header', array( - 'project' => $project, - 'filters' => $filters, - 'categories_list' => $this->categoryModel->getList($project['id'], false), - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], false), - 'custom_filters_list' => $this->customFilterModel->getAll($project['id'], $this->userSession->getId()), - 'board_view' => $boardView, - )); - } - - /** - * Get project description - * - * @access public - * @param array &$project - * @return string - */ - public function getDescription(array &$project) - { - if ($project['owner_id'] > 0) { - $description = t('Project owner: ').'**'.$this->helper->text->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL; - - if (! empty($project['description'])) { - $description .= '***'.PHP_EOL.PHP_EOL; - $description .= $project['description']; - } - } else { - $description = $project['description']; - } - - return $description; - } -} diff --git a/sources/app/Helper/SubtaskHelper.php b/sources/app/Helper/SubtaskHelper.php deleted file mode 100644 index dac7120..0000000 --- a/sources/app/Helper/SubtaskHelper.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Subtask helpers - * - * @package helper - * @author Frederic Guillot - */ -class SubtaskHelper extends Base -{ - public function getTitle(array $subtask) - { - if ($subtask['status'] == 0) { - $html = '<i class="fa fa-square-o fa-fw"></i>'; - } elseif ($subtask['status'] == 1) { - $html = '<i class="fa fa-gears fa-fw"></i>'; - } else { - $html = '<i class="fa fa-check-square-o fa-fw"></i>'; - } - - return $html.$this->helper->text->e($subtask['title']); - } - - /** - * Get the link to toggle subtask status - * - * @access public - * @param array $subtask - * @param integer $project_id - * @param boolean $refresh_table - * @return string - */ - public function toggleStatus(array $subtask, $project_id, $refresh_table = false) - { - if (! $this->helper->user->hasProjectAccess('SubtaskController', 'edit', $project_id)) { - return $this->getTitle($subtask); - } - - $params = array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'refresh-table' => (int) $refresh_table); - - if ($subtask['status'] == 0 && isset($this->sessionStorage->hasSubtaskInProgress) && $this->sessionStorage->hasSubtaskInProgress) { - return $this->helper->url->link($this->getTitle($subtask), 'SubtaskRestrictionController', 'show', $params, false, 'popover'); - } - - $class = 'subtask-toggle-status '.($refresh_table ? 'subtask-refresh-table' : ''); - return $this->helper->url->link($this->getTitle($subtask), 'SubtaskStatusController', 'change', $params, false, $class); - } - - public function selectTitle(array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="1"', 'required', 'maxlength="255"'), $attributes); - - $html = $this->helper->form->label(t('Title'), 'title'); - $html .= $this->helper->form->text('title', $values, $errors, $attributes); - - return $html; - } - - public function selectAssignee(array $users, array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="2"'), $attributes); - - $html = $this->helper->form->label(t('Assignee'), 'user_id'); - $html .= $this->helper->form->select('user_id', $users, $values, $errors, $attributes); - $html .= ' <a href="#" class="assign-me" data-target-id="form-user_id" data-current-id="'.$this->userSession->getId().'" title="'.t('Assign to me').'">'.t('Me').'</a>'; - - return $html; - } - - public function selectTimeEstimated(array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="3"'), $attributes); - - $html = $this->helper->form->label(t('Original estimate'), 'time_estimated'); - $html .= $this->helper->form->numeric('time_estimated', $values, $errors, $attributes); - $html .= ' '.t('hours'); - - return $html; - } - - public function selectTimeSpent(array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="4"'), $attributes); - - $html = $this->helper->form->label(t('Time spent'), 'time_spent'); - $html .= $this->helper->form->numeric('time_spent', $values, $errors, $attributes); - $html .= ' '.t('hours'); - - return $html; - } -} diff --git a/sources/app/Helper/TaskHelper.php b/sources/app/Helper/TaskHelper.php deleted file mode 100644 index e1d65cc..0000000 --- a/sources/app/Helper/TaskHelper.php +++ /dev/null @@ -1,246 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Task helpers - * - * @package helper - * @author Frederic Guillot - */ -class TaskHelper extends Base -{ - /** - * Local cache for project columns - * - * @access private - * @var array - */ - private $columns = array(); - - public function getColors() - { - return $this->colorModel->getList(); - } - - public function recurrenceTriggers() - { - return $this->taskRecurrenceModel->getRecurrenceTriggerList(); - } - - public function recurrenceTimeframes() - { - return $this->taskRecurrenceModel->getRecurrenceTimeframeList(); - } - - public function recurrenceBasedates() - { - return $this->taskRecurrenceModel->getRecurrenceBasedateList(); - } - - public function selectTitle(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 .= $this->helper->form->textarea( - 'description', - $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' - ); - - return $html; - } - - public function selectTags(array $project, array $tags = array()) - { - $options = $this->tagModel->getAssignableList($project['id']); - - $html = $this->helper->form->label(t('Tags'), 'tags[]'); - $html .= '<input type="hidden" name="tags[]" value="">'; - $html .= '<select name="tags[]" id="form-tags" class="tag-autocomplete" multiple>'; - - foreach ($options as $tag) { - $html .= sprintf( - '<option value="%s" %s>%s</option>', - $this->helper->text->e($tag), - in_array($tag, $tags) ? 'selected="selected"' : '', - $this->helper->text->e($tag) - ); - } - - $html .= '</select>'; - - return $html; - } - - public function selectColor(array $values) - { - $colors = $this->colorModel->getList(); - $html = $this->helper->form->label(t('Color'), 'color_id'); - $html .= $this->helper->form->select('color_id', $colors, $values, array(), array(), 'color-picker'); - return $html; - } - - public function selectAssignee(array $users, array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="3"'), $attributes); - - $html = $this->helper->form->label(t('Assignee'), 'owner_id'); - $html .= $this->helper->form->select('owner_id', $users, $values, $errors, $attributes); - $html .= ' <a href="#" class="assign-me" data-target-id="form-owner_id" data-current-id="'.$this->userSession->getId().'" title="'.t('Assign to me').'">'.t('Me').'</a>'; - - return $html; - } - - public function selectCategory(array $categories, array $values, array $errors = array(), array $attributes = array(), $allow_one_item = false) - { - $attributes = array_merge(array('tabindex="4"'), $attributes); - $html = ''; - - if (! (! $allow_one_item && count($categories) === 1 && key($categories) == 0)) { - $html .= $this->helper->form->label(t('Category'), 'category_id'); - $html .= $this->helper->form->select('category_id', $categories, $values, $errors, $attributes); - } - - return $html; - } - - public function selectSwimlane(array $swimlanes, array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="5"'), $attributes); - $html = ''; - - if (! (count($swimlanes) === 1 && key($swimlanes) == 0)) { - $html .= $this->helper->form->label(t('Swimlane'), 'swimlane_id'); - $html .= $this->helper->form->select('swimlane_id', $swimlanes, $values, $errors, $attributes); - } - - return $html; - } - - public function selectColumn(array $columns, array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="6"'), $attributes); - - $html = $this->helper->form->label(t('Column'), 'column_id'); - $html .= $this->helper->form->select('column_id', $columns, $values, $errors, $attributes); - - return $html; - } - - public function selectPriority(array $project, array $values) - { - $html = ''; - - if ($project['priority_end'] > $project['priority_start']) { - $range = range($project['priority_start'], $project['priority_end']); - $options = array_combine($range, $range); - $values += array('priority' => $project['priority_default']); - - $html .= $this->helper->form->label(t('Priority'), 'priority'); - $html .= $this->helper->form->select('priority', $options, $values, array(), array('tabindex="7"')); - } - - return $html; - } - - public function selectScore(array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="8"'), $attributes); - - $html = $this->helper->form->label(t('Complexity'), 'score'); - $html .= $this->helper->form->number('score', $values, $errors, $attributes); - - return $html; - } - - public function selectReference(array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="9"'), $attributes); - - $html = $this->helper->form->label(t('Reference'), 'reference'); - $html .= $this->helper->form->text('reference', $values, $errors, $attributes, 'form-input-small'); - - return $html; - } - - public function selectTimeEstimated(array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="10"'), $attributes); - - $html = $this->helper->form->label(t('Original estimate'), 'time_estimated'); - $html .= $this->helper->form->numeric('time_estimated', $values, $errors, $attributes); - $html .= ' '.t('hours'); - - return $html; - } - - public function selectTimeSpent(array $values, array $errors = array(), array $attributes = array()) - { - $attributes = array_merge(array('tabindex="11"'), $attributes); - - $html = $this->helper->form->label(t('Time spent'), 'time_spent'); - $html .= $this->helper->form->numeric('time_spent', $values, $errors, $attributes); - $html .= ' '.t('hours'); - - return $html; - } - - public function selectStartDate(array $values, array $errors = array(), array $attributes = array()) - { - $placeholder = date($this->configModel->get('application_date_format', 'm/d/Y H:i')); - $attributes = array_merge(array('tabindex="12"', 'placeholder="'.$placeholder.'"'), $attributes); - - $html = $this->helper->form->label(t('Start Date'), 'date_started'); - $html .= $this->helper->form->text('date_started', $values, $errors, $attributes, 'form-datetime'); - - return $html; - } - - public function selectDueDate(array $values, array $errors = array(), array $attributes = array()) - { - $placeholder = date($this->configModel->get('application_date_format', 'm/d/Y')); - $attributes = array_merge(array('tabindex="13"', 'placeholder="'.$placeholder.'"'), $attributes); - - $html = $this->helper->form->label(t('Due Date'), 'date_due'); - $html .= $this->helper->form->text('date_due', $values, $errors, $attributes, 'form-date'); - - return $html; - } - - public function formatPriority(array $project, array $task) - { - $html = ''; - - if ($project['priority_end'] > $project['priority_start']) { - $html .= '<span class="task-board-priority" title="'.t('Task priority').'">'; - $html .= $task['priority'] >= 0 ? 'P'.$task['priority'] : '-P'.abs($task['priority']); - $html .= '</span>'; - } - - return $html; - } - - public function getProgress($task) - { - if (! isset($this->columns[$task['project_id']])) { - $this->columns[$task['project_id']] = $this->columnModel->getList($task['project_id']); - } - - return $this->taskModel->getProgress($task, $this->columns[$task['project_id']]); - } -} diff --git a/sources/app/Helper/TextHelper.php b/sources/app/Helper/TextHelper.php deleted file mode 100644 index 654eb17..0000000 --- a/sources/app/Helper/TextHelper.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Markdown; -use Kanboard\Core\Base; - -/** - * Text Helpers - * - * @package helper - * @author Frederic Guillot - */ -class TextHelper extends Base -{ - /** - * HTML escaping - * - * @param string $value Value to escape - * @return string - */ - public function e($value) - { - return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false); - } - - /** - * Markdown transformation - * - * @param string $text - * @param boolean $isPublicLink - * @return string - */ - public function markdown($text, $isPublicLink = false) - { - $parser = new Markdown($this->container, $isPublicLink); - $parser->setMarkupEscaped(MARKDOWN_ESCAPE_HTML); - return $parser->text($text); - } - - /** - * Escape Markdown text that need to be stored in HTML attribute - * - * @access public - * @param string $text - * @return mixed - */ - public function markdownAttribute($text) - { - return htmlentities($this->markdown($text), ENT_QUOTES, 'UTF-8'); - } - - /** - * Format a file size - * - * @param integer $size Size in bytes - * @param integer $precision Precision - * @return string - */ - public function bytes($size, $precision = 2) - { - $base = log($size) / log(1024); - $suffixes = array('', 'k', 'M', 'G', 'T'); - - return round(pow(1024, $base - floor($base)), $precision).$suffixes[(int)floor($base)]; - } - - /** - * Get the number of bytes from PHP size - * - * @param integer $val PHP size (example: 2M) - * @return integer - */ - public function phpToBytes($val) - { - $val = trim($val); - $last = strtolower($val[strlen($val)-1]); - - switch ($last) { - case 'g': - $val *= 1024; - case 'm': - $val *= 1024; - case 'k': - $val *= 1024; - } - - return $val; - } - - /** - * Return true if needle is contained in the haystack - * - * @param string $haystack Haystack - * @param string $needle Needle - * @return boolean - */ - public function contains($haystack, $needle) - { - return strpos($haystack, $needle) !== false; - } - - /** - * Return a value from a dictionary - * - * @param mixed $id Key - * @param array $listing Dictionary - * @param string $default_value Value displayed when the key doesn't exists - * @return string - */ - public function in($id, array $listing, $default_value = '?') - { - if (isset($listing[$id])) { - return $this->helper->text->e($listing[$id]); - } - - return $default_value; - } -} diff --git a/sources/app/Helper/UrlHelper.php b/sources/app/Helper/UrlHelper.php deleted file mode 100644 index 2127c69..0000000 --- a/sources/app/Helper/UrlHelper.php +++ /dev/null @@ -1,191 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; - -/** - * Url Helper - * - * @package helper - * @author Frederic Guillot - */ -class UrlHelper extends Base -{ - private $base = ''; - private $directory = ''; - - /** - * Helper to generate a link to the documentation - * - * @access public - * @param string $label - * @param string $file - * @return string - */ - public function doc($label, $file) - { - return $this->link($label, 'DocumentationController', 'show', array('file' => $file), false, '', '', true); - } - - /** - * Button Link Element - * - * @access public - * @param string $icon Font-Awesome icon - * @param string $label Link label - * @param string $controller Controller name - * @param string $action Action name - * @param array $params Url parameters - * @param string $class CSS class attribute - * @return string - */ - public function button($icon, $label, $controller, $action, array $params = array(), $class = '') - { - $icon = '<i class="fa '.$icon.' fa-fw"></i> '; - $class = 'btn '.$class; - return $this->link($icon.$label, $controller, $action, $params, false, $class); - } - - /** - * Link element - * - * @access public - * @param string $label Link label - * @param string $controller Controller name - * @param string $action Action name - * @param array $params Url parameters - * @param boolean $csrf Add a CSRF token - * @param string $class CSS class attribute - * @param string $title - * @param boolean $new_tab Open the link in a new tab - * @param string $anchor Link Anchor - * @return string - */ - public function link($label, $controller, $action, array $params = array(), $csrf = false, $class = '', $title = '', $new_tab = false, $anchor = '') - { - return '<a href="'.$this->href($controller, $action, $params, $csrf, $anchor).'" class="'.$class.'" title=\''.$title.'\' '.($new_tab ? 'target="_blank"' : '').'>'.$label.'</a>'; - } - - /** - * HTML Hyperlink - * - * @access public - * @param string $controller Controller name - * @param string $action Action name - * @param array $params Url parameters - * @param boolean $csrf Add a CSRF token - * @param string $anchor Link Anchor - * @param boolean $absolute Absolute or relative link - * @return string - */ - public function href($controller, $action, array $params = array(), $csrf = false, $anchor = '', $absolute = false) - { - return $this->build('&', $controller, $action, $params, $csrf, $anchor, $absolute); - } - - /** - * Generate controller/action url - * - * @access public - * @param string $controller Controller name - * @param string $action Action name - * @param array $params Url parameters - * @param string $anchor Link Anchor - * @param boolean $absolute Absolute or relative link - * @return string - */ - public function to($controller, $action, array $params = array(), $anchor = '', $absolute = false) - { - return $this->build('&', $controller, $action, $params, false, $anchor, $absolute); - } - - /** - * Get application base url - * - * @access public - * @return string - */ - public function base() - { - if (empty($this->base)) { - $this->base = $this->configModel->get('application_url') ?: $this->server(); - } - - return $this->base; - } - - /** - * Get application base directory - * - * @access public - * @return string - */ - public function dir() - { - if ($this->directory === '' && $this->request->getMethod() !== '') { - $this->directory = str_replace('\\', '/', dirname($this->request->getServerVariable('PHP_SELF'))); - $this->directory = $this->directory !== '/' ? $this->directory.'/' : '/'; - $this->directory = str_replace('//', '/', $this->directory); - } - - return $this->directory; - } - - /** - * Get current server base url - * - * @access public - * @return string - */ - public function server() - { - if ($this->request->getServerVariable('SERVER_NAME') === '') { - return 'http://localhost/'; - } - - $url = $this->request->isHTTPS() ? 'https://' : 'http://'; - $url .= $this->request->getServerVariable('SERVER_NAME'); - $url .= $this->request->getServerVariable('SERVER_PORT') == 80 || $this->request->getServerVariable('SERVER_PORT') == 443 ? '' : ':'.$this->request->getServerVariable('SERVER_PORT'); - $url .= $this->dir() ?: '/'; - - return $url; - } - - /** - * Build relative url - * - * @access private - * @param string $separator Querystring argument separator - * @param string $controller Controller name - * @param string $action Action name - * @param array $params Url parameters - * @param boolean $csrf Add a CSRF token - * @param string $anchor Link Anchor - * @param boolean $absolute Absolute or relative link - * @return string - */ - private function build($separator, $controller, $action, array $params = array(), $csrf = false, $anchor = '', $absolute = false) - { - $path = $this->route->findUrl($controller, $action, $params); - $qs = array(); - - if (empty($path)) { - $qs['controller'] = $controller; - $qs['action'] = $action; - $qs += $params; - } else { - unset($params['plugin']); - } - - if ($csrf) { - $qs['csrf_token'] = $this->token->getCSRFToken(); - } - - if (! empty($qs)) { - $path .= '?'.http_build_query($qs, '', $separator); - } - - return ($absolute ? $this->base() : $this->dir()).$path.(empty($anchor) ? '' : '#'.$anchor); - } -} diff --git a/sources/app/Helper/UserHelper.php b/sources/app/Helper/UserHelper.php deleted file mode 100644 index ab259a6..0000000 --- a/sources/app/Helper/UserHelper.php +++ /dev/null @@ -1,192 +0,0 @@ -<?php - -namespace Kanboard\Helper; - -use Kanboard\Core\Base; -use Kanboard\Core\Security\Role; - -/** - * User helpers - * - * @package helper - * @author Frederic Guillot - */ -class UserHelper extends Base -{ - /** - * Return true if the logged user as unread notifications - * - * @access public - * @return boolean - */ - public function hasNotifications() - { - return $this->userUnreadNotificationModel->hasNotifications($this->userSession->getId()); - } - - /** - * Get initials from a user - * - * @access public - * @param string $name - * @return string - */ - public function getInitials($name) - { - $initials = ''; - - foreach (explode(' ', $name, 2) as $string) { - $initials .= mb_substr($string, 0, 1, 'UTF-8'); - } - - return mb_strtoupper($initials, 'UTF-8'); - } - - /** - * Return the user full name - * - * @param array $user User properties - * @return string - */ - public function getFullname(array $user = array()) - { - return $this->userModel->getFullname(empty($user) ? $this->userSession->getAll() : $user); - } - - /** - * Get user id - * - * @access public - * @return integer - */ - public function getId() - { - return $this->userSession->getId(); - } - - /** - * Check if the given user_id is the connected user - * - * @param integer $user_id User id - * @return boolean - */ - public function isCurrentUser($user_id) - { - return $this->userSession->getId() == $user_id; - } - - /** - * Return if the logged user is admin - * - * @access public - * @return boolean - */ - public function isAdmin() - { - return $this->userSession->isAdmin(); - } - - /** - * Get role name - * - * @access public - * @param string $role - * @return string - */ - public function getRoleName($role = '') - { - return $this->role->getRoleName($role ?: $this->userSession->getRole()); - } - - /** - * Check application access - * - * @param string $controller - * @param string $action - * @return bool - */ - public function hasAccess($controller, $action) - { - if (! $this->userSession->isLogged()) { - return false; - } - - $key = 'app_access:'.$controller.$action; - $result = $this->memoryCache->get($key); - - if ($result === null) { - $result = $this->applicationAuthorization->isAllowed($controller, $action, $this->userSession->getRole()); - $this->memoryCache->set($key, $result); - } - - return $result; - } - - /** - * Check project access - * - * @param string $controller - * @param string $action - * @param integer $project_id - * @return bool - */ - public function hasProjectAccess($controller, $action, $project_id) - { - if (! $this->userSession->isLogged()) { - return false; - } - - if ($this->userSession->isAdmin()) { - return true; - } - - if (! $this->hasAccess($controller, $action)) { - return false; - } - - $key = 'project_access:'.$controller.$action.$project_id; - $result = $this->memoryCache->get($key); - - if ($result === null) { - $role = $this->getProjectUserRole($project_id); - $result = $this->projectAuthorization->isAllowed($controller, $action, $role); - $this->memoryCache->set($key, $result); - } - - return $result; - } - - /** - * Get project role for the current user - * - * @access public - * @param integer $project_id - * @return string - */ - public function getProjectUserRole($project_id) - { - return $this->memoryCache->proxy($this->projectUserRoleModel, 'getUserRole', $project_id, $this->userSession->getId()); - } - - /** - * Return true if the user can remove a task - * - * Regular users can't remove tasks from other people - * - * @public - * @param array $task - * @return bool - */ - public function canRemoveTask(array $task) - { - if (isset($task['creator_id']) && $task['creator_id'] == $this->userSession->getId()) { - return true; - } - - if ($this->userSession->isAdmin() || $this->getProjectUserRole($task['project_id']) === Role::PROJECT_MANAGER) { - return true; - } - - return false; - } -} diff --git a/sources/app/Import/TaskImport.php b/sources/app/Import/TaskImport.php deleted file mode 100644 index f5ca9b0..0000000 --- a/sources/app/Import/TaskImport.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php - -namespace Kanboard\Import; - -use Kanboard\Core\Base; -use Kanboard\Core\Csv; -use SimpleValidator\Validator; -use SimpleValidator\Validators; - -/** - * Task Import - * - * @package import - * @author Frederic Guillot - */ -class TaskImport extends Base -{ - /** - * Number of successful import - * - * @access public - * @var integer - */ - public $counter = 0; - - /** - * Project id to import tasks - * - * @access public - * @var integer - */ - public $projectId; - - /** - * Get mapping between CSV header and SQL columns - * - * @access public - * @return array - */ - public function getColumnMapping() - { - return array( - 'reference' => 'Reference', - 'title' => 'Title', - 'description' => 'Description', - 'assignee' => 'Assignee Username', - 'creator' => 'Creator Username', - 'color' => 'Color Name', - 'column' => 'Column Name', - 'category' => 'Category Name', - 'swimlane' => 'Swimlane Name', - 'score' => 'Complexity', - 'time_estimated' => 'Time Estimated', - 'time_spent' => 'Time Spent', - 'date_due' => 'Due Date', - 'is_active' => 'Closed', - ); - } - - /** - * Import a single row - * - * @access public - * @param array $row - * @param integer $line_number - */ - public function import(array $row, $line_number) - { - $row = $this->prepare($row); - - if ($this->validateCreation($row)) { - if ($this->taskCreationModel->create($row) > 0) { - $this->logger->debug('TaskImport: imported successfully line '.$line_number); - $this->counter++; - } else { - $this->logger->error('TaskImport: creation error at line '.$line_number); - } - } else { - $this->logger->error('TaskImport: validation error at line '.$line_number); - } - } - - /** - * Format row before validation - * - * @access public - * @param array $row - * @return array - */ - public function prepare(array $row) - { - $values = array(); - $values['project_id'] = $this->projectId; - $values['reference'] = $row['reference']; - $values['title'] = $row['title']; - $values['description'] = $row['description']; - $values['is_active'] = Csv::getBooleanValue($row['is_active']) == 1 ? 0 : 1; - $values['score'] = (int) $row['score']; - $values['time_estimated'] = (float) $row['time_estimated']; - $values['time_spent'] = (float) $row['time_spent']; - - if (! empty($row['assignee'])) { - $values['owner_id'] = $this->userModel->getIdByUsername($row['assignee']); - } - - if (! empty($row['creator'])) { - $values['creator_id'] = $this->userModel->getIdByUsername($row['creator']); - } - - if (! empty($row['color'])) { - $values['color_id'] = $this->colorModel->find($row['color']); - } - - if (! empty($row['column'])) { - $values['column_id'] = $this->columnModel->getColumnIdByTitle($this->projectId, $row['column']); - } - - if (! empty($row['category'])) { - $values['category_id'] = $this->categoryModel->getIdByName($this->projectId, $row['category']); - } - - if (! empty($row['swimlane'])) { - $values['swimlane_id'] = $this->swimlaneModel->getIdByName($this->projectId, $row['swimlane']); - } - - if (! empty($row['date_due'])) { - $values['date_due'] = $this->dateParser->getTimestampFromIsoFormat($row['date_due']); - } - - $this->helper->model->removeEmptyFields( - $values, - array('owner_id', 'creator_id', 'color_id', 'column_id', 'category_id', 'swimlane_id', 'date_due') - ); - - return $values; - } - - /** - * Validate user creation - * - * @access public - * @param array $values - * @return boolean - */ - public function validateCreation(array $values) - { - $v = new Validator($values, array( - new Validators\Integer('project_id', t('This value must be an integer')), - new Validators\Required('project_id', t('The project is required')), - new Validators\Required('title', t('The title is required')), - 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), - )); - - return $v->execute(); - } -} diff --git a/sources/app/Import/UserImport.php b/sources/app/Import/UserImport.php deleted file mode 100644 index 304a325..0000000 --- a/sources/app/Import/UserImport.php +++ /dev/null @@ -1,120 +0,0 @@ -<?php - -namespace Kanboard\Import; - -use Kanboard\Model\UserModel; -use SimpleValidator\Validator; -use SimpleValidator\Validators; -use Kanboard\Core\Security\Role; -use Kanboard\Core\Base; -use Kanboard\Core\Csv; - -/** - * User Import - * - * @package import - * @author Frederic Guillot - */ -class UserImport extends Base -{ - /** - * Number of successful import - * - * @access public - * @var integer - */ - public $counter = 0; - - /** - * Get mapping between CSV header and SQL columns - * - * @access public - * @return array - */ - public function getColumnMapping() - { - return array( - 'username' => 'Username', - 'password' => 'Password', - 'email' => 'Email', - 'name' => 'Full Name', - 'is_admin' => 'Administrator', - 'is_manager' => 'Manager', - 'is_ldap_user' => 'Remote User', - ); - } - - /** - * Import a single row - * - * @access public - * @param array $row - * @param integer $line_number - */ - public function import(array $row, $line_number) - { - $row = $this->prepare($row); - - if ($this->validateCreation($row)) { - if ($this->userModel->create($row) !== false) { - $this->logger->debug('UserImport: imported successfully line '.$line_number); - $this->counter++; - } else { - $this->logger->error('UserImport: creation error at line '.$line_number); - } - } else { - $this->logger->error('UserImport: validation error at line '.$line_number); - } - } - - /** - * Format row before validation - * - * @access public - * @param array $row - * @return array - */ - public function prepare(array $row) - { - $row['username'] = strtolower($row['username']); - - foreach (array('is_admin', 'is_manager', 'is_ldap_user') as $field) { - $row[$field] = Csv::getBooleanValue($row[$field]); - } - - if ($row['is_admin'] == 1) { - $row['role'] = Role::APP_ADMIN; - } elseif ($row['is_manager'] == 1) { - $row['role'] = Role::APP_MANAGER; - } else { - $row['role'] = Role::APP_USER; - } - - unset($row['is_admin']); - unset($row['is_manager']); - - $this->helper->model->removeEmptyFields($row, array('password', 'email', 'name')); - - return $row; - } - - /** - * Validate user creation - * - * @access public - * @param array $values - * @return boolean - */ - public function validateCreation(array $values) - { - $v = new Validator($values, array( - 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\MinLength('password', t('The minimum length is %d characters', 6), 6), - new Validators\Email('email', t('Email address invalid')), - new Validators\Integer('is_ldap_user', t('This value must be an integer')), - )); - - return $v->execute(); - } -} diff --git a/sources/app/Job/BaseJob.php b/sources/app/Job/BaseJob.php deleted file mode 100644 index 60522ac..0000000 --- a/sources/app/Job/BaseJob.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -namespace Kanboard\Job; - -use Kanboard\Core\Base; - -/** - * Class BaseJob - * - * @package Kanboard\Job - * @author Frederic Guillot - */ -abstract class BaseJob extends Base -{ - /** - * Job parameters - * - * @access protected - * @var array - */ - protected $jobParams = array(); - - /** - * Get job parameters - * - * @access public - * @return array - */ - public function getJobParams() - { - return $this->jobParams; - } -} diff --git a/sources/app/Job/EmailJob.php b/sources/app/Job/EmailJob.php deleted file mode 100644 index 2da3ca2..0000000 --- a/sources/app/Job/EmailJob.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php - -namespace Kanboard\Job; - -/** - * Class EmailJob - * - * @package Kanboard\Job - * @author Frederic Guillot - */ -class EmailJob extends BaseJob -{ - /** - * Set job parameters - * - * @access public - * @param string $email - * @param string $name - * @param string $subject - * @param string $html - * @param string $author - * @return $this - */ - public function withParams($email, $name, $subject, $html, $author) - { - $this->jobParams = array($email, $name, $subject, $html, $author); - return $this; - } - - /** - * Execute job - * - * @access public - * @param string $email - * @param string $name - * @param string $subject - * @param string $html - * @param string $author - */ - public function execute($email, $name, $subject, $html, $author) - { - $transport = $this->helper->mail->getMailTransport(); - $this->logger->debug(__METHOD__.' Sending email to: '.$email.' using transport: '.$transport); - $startTime = microtime(true); - - $this->emailClient - ->getTransport($transport) - ->sendEmail($email, $name, $subject, $html, $author) - ; - - if (DEBUG) { - $this->logger->debug('Email sent in '.round(microtime(true) - $startTime, 6).' seconds'); - } - } -} diff --git a/sources/app/Job/HttpAsyncJob.php b/sources/app/Job/HttpAsyncJob.php deleted file mode 100644 index 9e5cf10..0000000 --- a/sources/app/Job/HttpAsyncJob.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace Kanboard\Job; - -/** - * Async HTTP Client (fire and forget) - * - * @package Kanboard\Job - * @author Frederic Guillot - */ -class HttpAsyncJob extends BaseJob -{ - /** - * Set job parameters - * - * @access public - * @param string $method - * @param string $url - * @param string $content - * @param array $headers - * @return $this - */ - public function withParams($method, $url, $content, array $headers) - { - $this->jobParams = array($method, $url, $content, $headers); - return $this; - } - - /** - * Set job parameters - * - * @access public - * @param string $method - * @param string $url - * @param string $content - * @param array $headers - * @return $this - */ - public function execute($method, $url, $content, array $headers) - { - $this->httpClient->doRequest($method, $url, $content, $headers); - } -} diff --git a/sources/app/Job/NotificationJob.php b/sources/app/Job/NotificationJob.php deleted file mode 100644 index 904a927..0000000 --- a/sources/app/Job/NotificationJob.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php - -namespace Kanboard\Job; - -use Kanboard\Event\GenericEvent; - -/** - * Class NotificationJob - * - * @package Kanboard\Job - * @author Frederic Guillot - */ -class NotificationJob extends BaseJob -{ - /** - * Set job parameters - * - * @param GenericEvent $event - * @param string $eventName - * @param string $eventObjectName - * @return $this - */ - public function withParams(GenericEvent $event, $eventName, $eventObjectName) - { - $this->jobParams = array($event->getAll(), $eventName, $eventObjectName); - return $this; - } - - /** - * Execute job - * - * @param array $event - * @param string $eventName - * @param string $eventObjectName - */ - public function execute(array $event, $eventName, $eventObjectName) - { - $eventData = $this->getEventData($event, $eventObjectName); - - if (! empty($eventData)) { - if (! empty($event['mention'])) { - $this->userNotificationModel->sendUserNotification($event['mention'], $eventName, $eventData); - } else { - $this->userNotificationModel->sendNotifications($eventName, $eventData); - $this->projectNotificationModel->sendNotifications($eventData['task']['project_id'], $eventName, $eventData); - } - } - } - - /** - * Get event data - * - * @param array $event - * @param string $eventObjectName - * @return array - */ - public function getEventData(array $event, $eventObjectName) - { - $values = array(); - - if (! empty($event['changes'])) { - $values['changes'] = $event['changes']; - } - - switch ($eventObjectName) { - case 'Kanboard\Event\TaskEvent': - $values['task'] = $this->taskFinderModel->getDetails($event['task_id']); - break; - case 'Kanboard\Event\SubtaskEvent': - $values['subtask'] = $this->subtaskModel->getById($event['id'], true); - $values['task'] = $this->taskFinderModel->getDetails($values['subtask']['task_id']); - break; - case 'Kanboard\Event\FileEvent': - $values['file'] = $event; - $values['task'] = $this->taskFinderModel->getDetails($values['file']['task_id']); - break; - case 'Kanboard\Event\CommentEvent': - $values['comment'] = $this->commentModel->getById($event['id']); - $values['task'] = $this->taskFinderModel->getDetails($values['comment']['task_id']); - break; - } - - return $values; - } -} diff --git a/sources/app/Job/ProjectMetricJob.php b/sources/app/Job/ProjectMetricJob.php deleted file mode 100644 index 6330bd4..0000000 --- a/sources/app/Job/ProjectMetricJob.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -namespace Kanboard\Job; - -/** - * Class ProjectMetricJob - * - * @package Kanboard\Job - * @author Frederic Guillot - */ -class ProjectMetricJob extends BaseJob -{ - /** - * Set job parameters - * - * @access public - * @param integer $projectId - * @return $this - */ - public function withParams($projectId) - { - $this->jobParams = array($projectId); - return $this; - } - - /** - * Execute job - * - * @access public - * @param integer $projectId - */ - public function execute($projectId) - { - $this->logger->debug(__METHOD__.' Run project metrics calculation'); - $now = date('Y-m-d'); - - $this->projectDailyColumnStatsModel->updateTotals($projectId, $now); - $this->projectDailyStatsModel->updateTotals($projectId, $now); - } -} diff --git a/sources/app/Library/password.php b/sources/app/Library/password.php deleted file mode 100644 index d4972ab..0000000 --- a/sources/app/Library/password.php +++ /dev/null @@ -1,226 +0,0 @@ -<?php -/** - * A Compatibility library with PHP 5.5's simplified password hashing API. - * - * @author Anthony Ferrara <ircmaxell@php.net> - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @copyright 2012 The Authors - */ - -if (!defined('PASSWORD_BCRYPT')) { - define('PASSWORD_BCRYPT', 1); - define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); - - if (version_compare(PHP_VERSION, '5.3.7', '<')) { - define('PASSWORD_PREFIX', '$2a$'); - } else { - define('PASSWORD_PREFIX', '$2y$'); - } - - /** - * Hash the password using the specified algorithm - * - * @param string $password The password to hash - * @param int $algo The algorithm to use (Defined by PASSWORD_* constants) - * @param array $options The options for the algorithm to use - * - * @return string|false The hashed password, or false on error. - */ - function password_hash($password, $algo, array $options = array()) - { - if (!function_exists('crypt')) { - trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING); - return null; - } - if (!is_string($password)) { - trigger_error("password_hash(): Password must be a string", E_USER_WARNING); - return null; - } - if (!is_int($algo)) { - trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING); - return null; - } - switch ($algo) { - case PASSWORD_BCRYPT: - // Note that this is a C constant, but not exposed to PHP, so we don't define it here. - $cost = 10; - if (isset($options['cost'])) { - $cost = $options['cost']; - if ($cost < 4 || $cost > 31) { - trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING); - return null; - } - } - $required_salt_len = 22; - $hash_format = sprintf("%s%02d$", PASSWORD_PREFIX, $cost); - break; - default: - trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING); - return null; - } - if (isset($options['salt'])) { - switch (gettype($options['salt'])) { - case 'NULL': - case 'boolean': - case 'integer': - case 'double': - case 'string': - $salt = (string) $options['salt']; - break; - case 'object': - if (method_exists($options['salt'], '__tostring')) { - $salt = (string) $options['salt']; - break; - } - case 'array': - case 'resource': - default: - trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING); - return null; - } - if (strlen($salt) < $required_salt_len) { - trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", strlen($salt), $required_salt_len), E_USER_WARNING); - return null; - } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) { - $salt = str_replace('+', '.', base64_encode($salt)); - } - } else { - $buffer = ''; - $raw_length = (int) ($required_salt_len * 3 / 4 + 1); - $buffer_valid = false; - if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) { - $buffer = mcrypt_create_iv($raw_length, MCRYPT_DEV_URANDOM); - if ($buffer) { - $buffer_valid = true; - } - } - if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { - $buffer = openssl_random_pseudo_bytes($raw_length); - if ($buffer) { - $buffer_valid = true; - } - } - if (!$buffer_valid && is_readable('/dev/urandom')) { - $f = fopen('/dev/urandom', 'r'); - $read = strlen($buffer); - while ($read < $raw_length) { - $buffer .= fread($f, $raw_length - $read); - $read = strlen($buffer); - } - fclose($f); - if ($read >= $raw_length) { - $buffer_valid = true; - } - } - if (!$buffer_valid || strlen($buffer) < $raw_length) { - $bl = strlen($buffer); - for ($i = 0; $i < $raw_length; $i++) { - if ($i < $bl) { - $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255)); - } else { - $buffer .= chr(mt_rand(0, 255)); - } - } - } - $salt = str_replace('+', '.', base64_encode($buffer)); - } - $salt = substr($salt, 0, $required_salt_len); - - $hash = $hash_format . $salt; - - $ret = crypt($password, $hash); - - if (!is_string($ret) || strlen($ret) <= 13) { - return false; - } - - return $ret; - } - - /** - * Get information about the password hash. Returns an array of the information - * that was used to generate the password hash. - * - * array( - * 'algo' => 1, - * 'algoName' => 'bcrypt', - * 'options' => array( - * 'cost' => 10, - * ), - * ) - * - * @param string $hash The password hash to extract info from - * - * @return array The array of information about the hash. - */ - function password_get_info($hash) - { - $return = array( - 'algo' => 0, - 'algoName' => 'unknown', - 'options' => array(), - ); - if (substr($hash, 0, 4) == PASSWORD_PREFIX && strlen($hash) == 60) { - $return['algo'] = PASSWORD_BCRYPT; - $return['algoName'] = 'bcrypt'; - list($cost) = sscanf($hash, PASSWORD_PREFIX."%d$"); - $return['options']['cost'] = $cost; - } - return $return; - } - - /** - * Determine if the password hash needs to be rehashed according to the options provided - * - * If the answer is true, after validating the password using password_verify, rehash it. - * - * @param string $hash The hash to test - * @param int $algo The algorithm used for new password hashes - * @param array $options The options array passed to password_hash - * - * @return boolean True if the password needs to be rehashed. - */ - function password_needs_rehash($hash, $algo, array $options = array()) - { - $info = password_get_info($hash); - if ($info['algo'] != $algo) { - return true; - } - switch ($algo) { - case PASSWORD_BCRYPT: - $cost = isset($options['cost']) ? $options['cost'] : 10; - if ($cost != $info['options']['cost']) { - return true; - } - break; - } - return false; - } - - /** - * Verify a password against a hash using a timing attack resistant approach - * - * @param string $password The password to verify - * @param string $hash The hash to verify against - * - * @return boolean If the password matches the hash - */ - function password_verify($password, $hash) - { - if (!function_exists('crypt')) { - trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING); - return false; - } - $ret = crypt($password, $hash); - if (!is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) { - return false; - } - - $status = 0; - for ($i = 0; $i < strlen($ret); $i++) { - $status |= (ord($ret[$i]) ^ ord($hash[$i])); - } - - return $status === 0; - } -} diff --git a/sources/app/Locale/bs_BA/translations.php b/sources/app/Locale/bs_BA/translations.php deleted file mode 100644 index 4213d10..0000000 --- a/sources/app/Locale/bs_BA/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'None', - 'edit' => 'uredi', - 'Edit' => 'Uredi', - 'remove' => 'ukloni', - 'Remove' => 'Ukloni', - 'Yes' => 'Da', - 'No' => 'Ne', - 'cancel' => 'odustani', - 'or' => 'ili', - 'Yellow' => 'Žuta', - 'Blue' => 'Plava', - 'Green' => 'Zelena', - 'Purple' => 'Ljubičasta', - 'Red' => 'Crvena', - 'Orange' => 'Narandžasta', - 'Grey' => 'Siva', - 'Brown' => 'Smeđa', - 'Deep Orange' => 'Tamno narandžasta', - 'Dark Grey' => 'Tamno siva', - 'Pink' => 'Roze', - 'Teal' => 'Tirkizna', - 'Cyan' => 'Zelenkasto plava', - 'Lime' => 'Žućkasto zelena', - 'Light Green' => 'Svijetlo zelena', - 'Amber' => 'Ćilibarska', - 'Save' => 'Sačuvaj', - 'Login' => 'Prijava', - 'Official website:' => 'Zvanična stranica:', - 'Unassigned' => 'Nedodijeljen', - 'View this task' => 'Pregledaj zadatak', - 'Remove user' => 'Ukloni korisnika', - 'Do you really want to remove this user: "%s"?' => 'Da li zaista želiš da ukloniš korisnika: "%s"?', - 'All users' => 'Svi korisnici', - 'Username' => 'Korisničko ime', - 'Password' => 'Šifra', - 'Administrator' => 'Administrator', - 'Sign in' => 'Prijava', - 'Users' => 'Korisnici', - 'No user' => 'Nema korisnika', - 'Forbidden' => 'Zabranjeno', - 'Access Forbidden' => 'Pristup zabranjen', - 'Edit user' => 'Uredi korisnika', - 'Logout' => 'Odjava', - 'Bad username or password' => 'Pogrešno korisničko ime ili šifra', - 'Edit project' => 'Uredi projekat', - 'Name' => 'Ime', - 'Projects' => 'Projekti', - 'No project' => 'Bez projekta', - 'Project' => 'Projekat', - 'Status' => 'Status', - 'Tasks' => 'Zadatak', - 'Board' => 'Ploča', - 'Actions' => 'Akcije', - 'Inactive' => 'Neaktivan', - 'Active' => 'Aktivan', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Da li želiš da ukloniš projekat: "%s"?', - 'Remove project' => 'Ukloni projekat', - 'Edit the board for "%s"' => 'Uredi ploču za "%s"', - 'All projects' => 'Svi projekti', - 'Add a new column' => 'Dodaj novu kolonu', - '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!', - 'Settings' => 'Podešavanja', - 'Application settings' => 'Podešavanja aplikacije', - 'Language' => 'Jezik', - 'Webhook token:' => 'Token:', - 'API token:' => 'Token za API', - 'Database size:' => 'Veličina baze:', - 'Download the database' => 'Preuzmi bazu', - 'Optimize the database' => 'Optimizuj bazu', - '(VACUUM command)' => '(Naredba VACUUM)', - '(Gzip compressed Sqlite file)' => '(Sqlite baza spakovana Gzip-om)', - 'Close a task' => 'Zatvori zadatak', - 'Edit a task' => 'Uredi zadatak', - 'Column' => 'Kolona', - 'Color' => 'Boja', - 'Assignee' => 'Izvršilac', - 'Create another task' => 'Dodaj zadatak', - 'New task' => 'Novi zadatak', - 'Open a task' => 'Otvori zadatak', - 'Do you really want to open this task: "%s"?' => 'Da li zaista želiš da otvoriš zadatak: "%s"?', - 'Back to the board' => 'Nazad na ploču', - 'There is nobody assigned' => 'Niko nije dodijeljen!', - 'Column on the board:' => 'Kolona na tabli:', - 'Close this task' => 'Zatvori ovaj zadatak', - 'Open this task' => 'Otvori ovaj zadatak', - 'There is no description.' => 'Bez opisa.', - 'Add a new task' => 'Dodaj zadatak', - 'The username is required' => 'Korisničko ime je obavezno', - 'The maximum length is %d characters' => 'Maksimalna dužina je %d znakova', - 'The minimum length is %d characters' => 'Minimalna dužina je %d znakova', - 'The password is required' => 'Šifra je obavezna', - 'This value must be an integer' => 'Mora biti cio broj', - 'The username must be unique' => 'Korisničko ime mora biti jedinstveno', - 'The user id is required' => 'ID korisnika je obavezan', - 'Passwords don\'t match' => 'Šifre se ne podudaraju', - 'The confirmation is required' => 'Potvrda je obavezna', - 'The project is required' => 'Projekat je obavezan', - 'The id is required' => 'ID je obavezan', - 'The project id is required' => 'ID projekta je obavezan', - 'The project name is required' => 'Naziv projekta je obavezan', - 'The title is required' => 'Naslov je obavezan', - 'Settings saved successfully.' => 'Podešavanja uspješno sačuvana.', - 'Unable to save your settings.' => 'Nemoguće sačuvati podešavanja.', - 'Database optimization done.' => 'Optimizacija baze je završena.', - 'Your project have been created successfully.' => 'Projekat je uspješno napravljen.', - 'Unable to create your project.' => 'Nemoguće kreiranje projekta.', - 'Project updated successfully.' => 'Projekat je uspješno ažuriran.', - 'Unable to update this project.' => 'Nemoguće ažuriranje projekta.', - 'Unable to remove this project.' => 'Nemoguće uklanjanje projekta.', - 'Project removed successfully.' => 'Projekat uspješno uklonjen.', - 'Project activated successfully.' => 'Projekt uspješno aktiviran.', - 'Unable to activate this project.' => 'Nemoguće aktiviranje projekta.', - 'Project disabled successfully.' => 'Projekat uspješno deaktiviran.', - 'Unable to disable this project.' => 'nemoguće deaktiviranje projekta.', - 'Unable to open this task.' => 'Nemoguće otvaranje zadatka.', - 'Task opened successfully.' => 'Zadatak uspješno otvoren.', - 'Unable to close this task.' => 'Nije moguće zatvaranje ovog zadatka.', - 'Task closed successfully.' => 'Zadatak uspješno zatvoren.', - 'Unable to update your task.' => 'Nije moguće ažuriranje zadatka.', - 'Task updated successfully.' => 'Zadatak uspješno ažuriran.', - 'Unable to create your task.' => 'Nije moguće kreiranje zadatka.', - 'Task created successfully.' => 'Zadatak uspješno kreiran.', - 'User created successfully.' => 'Korisnik uspješno kreiran', - 'Unable to create your user.' => 'Nije uspjelo kreiranje korisnika.', - 'User updated successfully.' => 'Korisnik uspješno ažuriran.', - 'Unable to update your user.' => 'Nije moguće ažuriranje korisnika.', - 'User removed successfully.' => 'Korisnik uspješno uklonjen.', - 'Unable to remove this user.' => 'Nije moguće uklanjanje korisnika.', - 'Board updated successfully.' => 'Ploča je uspješno ažurirana.', - 'Ready' => 'Spreman', - 'Backlog' => 'Zaliha', - 'Work in progress' => 'U izradi', - 'Done' => 'Gotovo', - 'Application version:' => 'Verzija aplikacije:', - 'Id' => 'Id', - '%d closed tasks' => '%d zatvorenih zadataka', - 'No task for this project' => 'Nema dodijeljenih zadataka ovom projektu', - 'Public link' => 'Javni link', - 'Timezone' => 'Vremenska zona', - 'Sorry, I didn\'t find this information in my database!' => 'Na žalost, nije pronađena informacija u bazi', - 'Page not found' => 'Strana nije pronađena', - 'Complexity' => 'Složenost', - 'Task limit' => 'Najviše zadataka', - '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', - 'Invalid date' => 'Pogrešan datum', - 'Automatic actions' => 'Automatske akcije', - 'Your automatic action have been created successfully.' => 'Uspješno kreirana automatska akcija', - 'Unable to create your automatic action.' => 'Nemoguće kreiranje automatske akcije', - 'Remove an action' => 'Obriši akciju', - 'Unable to remove this action.' => 'Nije moguće obrisati akciju', - 'Action removed successfully.' => 'Akcija obrisana', - 'Automatic actions for the project "%s"' => 'Akcije za automatizaciju projekta "%s"', - 'Add an action' => 'dodaj akcju', - 'Event name' => 'Naziv događaja', - 'Action name' => 'Naziv akcije', - 'Action parameters' => 'Parametri akcije', - 'Action' => 'Akcija', - 'Event' => 'Događaj', - 'When the selected event occurs execute the corresponding action.' => 'Na izabrani događaj izvrši odgovarajuću akciju', - 'Next step' => 'Slijedeći korak', - 'Define action parameters' => 'Definiši parametre akcije', - 'Do you really want to remove this action: "%s"?' => 'Da li da obrišem akciju "%s"?', - 'Remove an automatic action' => 'Obriši automatsku akciju', - 'Assign the task to a specific user' => 'Dodijeli zadatak određenom korisniku', - 'Assign the task to the person who does the action' => 'Dodeli zadatak korisniku koji je izvršio akciju', - 'Duplicate the task to another project' => 'Kopiraj akciju u drugi projekat', - 'Move a task to another column' => 'Premjesti zadatak u drugu kolonu', - 'Task modification' => 'Izmjene zadatka', - 'Task creation' => 'Kreiranje zadatka', - 'Closing a task' => 'Zatvaranja zadatka', - 'Assign a color to a specific user' => 'Dodeli boju korisniku', - 'Column title' => 'Naslov kolone', - 'Position' => 'Pozicija', - 'Duplicate to another project' => 'Dupliciraj u drugi projekat', - 'Duplicate' => 'Dupliciraj', - 'link' => 'link', - 'Comment updated successfully.' => 'Komentar uspješno ažuriran.', - 'Unable to update your comment.' => 'Neuspješno ažuriranje komentara.', - 'Remove a comment' => 'Obriši komentar', - 'Comment removed successfully.' => 'Komentar je uspješno obrisan.', - 'Unable to remove this comment.' => 'Neuspješno brisanje komentara.', - 'Do you really want to remove this comment?' => 'Da li zaista želiš obrisati ovaj komentar?', - 'Current password for the user "%s"' => 'Trenutna šifra korisnika "%s"', - 'The current password is required' => 'Trenutna šifra je obavezna', - 'Wrong password' => 'Pogrešna šifra', - 'Unknown' => 'Nepoznat', - 'Last logins' => 'Posljednje prijave', - 'Login date' => 'Datum prijave', - 'Authentication method' => 'Metod autentikacije', - 'IP address' => 'IP adresa', - 'User agent' => 'Browser', - 'Persistent connections' => 'Stalna konekcija', - 'No session.' => 'Bez sesije', - 'Expiration date' => 'Ističe', - 'Remember Me' => 'Zapamti me', - 'Creation date' => 'Datum kreiranja', - 'Everybody' => 'Svi', - 'Open' => 'Otvoreni', - 'Closed' => 'Zatvoreni', - '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', - 'Email address invalid' => 'Pogrešan e-mail', - 'Your external account is not linked anymore to your profile.' => 'Vaš vanjski korisnički profil nije više povezan.', - 'Unable to unlink your external account.' => 'Nemoguće ukloniti vezu s vanjskim korisničkim profilom', - 'External authentication failed' => 'Vanjska autentikacija nije uspostavljena', - 'Your external account is linked to your profile successfully.' => 'Uspješno uspostavljena vanjska autentikacija', - 'Email' => 'E-mail', - 'Task removed successfully.' => 'Zadatak uspješno uklonjen.', - 'Unable to remove this task.' => 'Nemoguće uklanjanje zadatka.', - 'Remove a task' => 'Ukloni zadatak', - 'Do you really want to remove this task: "%s"?' => 'Da li zaista želiš ukloniti zadatak "%s"?', - 'Assign automatically a color based on a category' => 'Automatski dodijeli boju po kategoriji', - 'Assign automatically a category based on a color' => 'Automatski dodijeli kategoriju po boji', - 'Task creation or modification' => 'Kreiranje ili izmjena zadatka', - 'Category' => 'Kategorija', - 'Category:' => 'Kategorija:', - 'Categories' => 'Kategorije', - 'Your category have been created successfully.' => 'Uspješno kreirana kategorija.', - 'Unable to create your category.' => 'Nije moguće kreirati kategoriju.', - 'Your category have been updated successfully.' => 'Kategorija je uspješno ažurirana', - 'Unable to update your category.' => 'Nemoguće izmijeniti kategoriju', - 'Remove a category' => 'Ukloni kategoriju', - 'Category removed successfully.' => 'Kategorija uspešno uklonjena.', - 'Unable to remove this category.' => 'Nije moguće ukloniti kategoriju.', - 'Category modification for the project "%s"' => 'Izmjena kategorije za projekat "%s"', - 'Category Name' => 'Naziv kategorije', - 'Add a new category' => 'Dodaj novu kategoriju', - 'Do you really want to remove this category: "%s"?' => 'Da li zaista želiš ukloniti kategoriju: "%s"?', - 'All categories' => 'Sve kategorije', - 'No category' => 'Bez kategorije', - 'The name is required' => 'Naziv je obavezan', - 'Remove a file' => 'Ukloni fajl', - 'Unable to remove this file.' => 'Fajl nije moguće ukloniti.', - 'File removed successfully.' => 'Uspješno uklonjen fajl.', - 'Attach a document' => 'Prikači dokument', - 'Do you really want to remove this file: "%s"?' => 'Da li da uklonim fajl: "%s"?', - 'Attachments' => 'Prilozi', - 'Edit the task' => 'Uredi zadatak', - 'Add a comment' => 'Dodaj komentar', - 'Edit a comment' => 'Izmijeni komentar', - 'Summary' => 'Pregled', - 'Time tracking' => 'Praćenje vremena', - 'Estimate:' => 'Procjena:', - 'Spent:' => 'Potrošeno:', - 'Do you really want to remove this sub-task?' => 'Da li da zaista želiš ukloniti pod-zdadatak?', - 'Remaining:' => 'Preostalo:', - 'hours' => 'sati', - 'spent' => 'potrošeno', - 'estimated' => 'procijenjeno', - 'Sub-Tasks' => 'Pod-zadaci', - 'Add a sub-task' => 'Dodaj pod-zadatak', - 'Original estimate' => 'Originalna procjena', - 'Create another sub-task' => 'Dodaj novi pod-zadatak', - 'Time spent' => 'Utrošeno vrijeme', - 'Edit a sub-task' => 'Izmijeni pod-zadatak', - 'Remove a sub-task' => 'Ukloni pod-zadatak', - 'The time must be a numeric value' => 'Vrijeme mora biti broj', - 'Todo' => 'Za uraditi', - 'In progress' => 'U radu', - 'Sub-task removed successfully.' => 'Pod-zadatak uspješno uklonjen.', - 'Unable to remove this sub-task.' => 'Nemoguće ukloniti pod-zadatak.', - 'Sub-task updated successfully.' => 'Pod-zadatak uspješno ažuriran.', - 'Unable to update your sub-task.' => 'Nemoguće ažurirati pod-zadatak.', - 'Unable to create your sub-task.' => 'Nemoguće dodati pod-zadatak.', - 'Sub-task added successfully.' => 'Pod-zadatak uspješno dodan.', - 'Maximum size: ' => 'Maksimalna veličina: ', - 'Unable to upload the file.' => 'Nije moguće snimiti fajl.', - 'Display another project' => 'Prikaži drugi projekat', - 'Created by %s' => 'Kreirao %s', - 'Tasks Export' => 'Izvoz zadataka', - 'Tasks exportation for "%s"' => 'Izvoz zadataka za "%s"', - 'Start Date' => 'Početni datum', - 'End Date' => 'Datum završetka', - 'Execute' => 'Izvrši', - 'Task Id' => 'Identifikator zadatka', - 'Creator' => 'Autor', - 'Modification date' => 'Datum izmjene', - 'Completion date' => 'Datum završetka', - 'Clone' => 'Kloniraj', - 'Project cloned successfully.' => 'Projekat uspješno kloniran.', - 'Unable to clone this project.' => 'Nije moguće klonirati projekat.', - 'Enable email notifications' => 'Omogući obavještenja e-mailom', - 'Task position:' => 'Pozicija zadatka:', - 'The task #%d have been opened.' => 'Zadatak #%d je otvoren.', - 'The task #%d have been closed.' => 'Zadatak #%d je zatvoren.', - 'Sub-task updated' => 'Pod-zadatak izmijenjen', - 'Title:' => 'Naslov:', - 'Status:' => 'Status:', - 'Assignee:' => 'Izvršilac:', - 'Time tracking:' => 'Praćenje vremena:', - 'New sub-task' => 'Novi pod-zadatak', - 'New attachment added "%s"' => 'Ubačen novi prilog "%s"', - 'New comment posted by %s' => '%s ostavio novi komentar', - 'New attachment' => 'Novi prilog', - 'New comment' => 'Novi komentar', - 'Comment updated' => 'Komentar ažuriran', - 'New subtask' => 'Novi pod-zadatak', - 'Subtask updated' => 'Pod-zadatak ažuriran', - 'Task updated' => 'Zadatak ažuriran', - 'Task closed' => 'Zadatak je zatvoren', - 'Task opened' => 'Zadatak je otvoren', - 'I want to receive notifications only for those projects:' => 'Želim obavještenja samo za ove projekte:', - 'view the task on Kanboard' => 'Pregledaj zadatke', - 'Public access' => 'Javni pristup', - 'Active tasks' => 'Aktivni zadaci', - 'Disable public access' => 'Zabrani javni pristup', - 'Enable public access' => 'Dozvoli javni pristup', - 'Public access disabled' => 'Javni pristup onemogućen!', - 'Do you really want to disable this project: "%s"?' => 'Da li zaista želiš da deaktiviraš projekat: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Da li zaista želiš da aktiviraš projekat: "%s"?', - 'Project activation' => 'Aktivacija projekta', - 'Move the task to another project' => 'Premjesti zadatak u drugi projekat', - 'Move to another project' => 'Premjesti u drugi projekat', - 'Do you really want to duplicate this task?' => 'Da li zaista želiš duplicirati ovaj zadatak?', - 'Duplicate a task' => 'Dupliciraj zadatak', - 'External accounts' => 'Vanjski korisnički računi', - 'Account type' => 'Tip korisničkog računa', - 'Local' => 'Lokalno', - 'Remote' => 'Udaljeno', - 'Enabled' => 'Omogućeno', - 'Disabled' => 'Onemogućeno', - 'Username:' => 'Korisničko ime:', - 'Name:' => 'Ime i Prezime', - 'Email:' => 'Email: ', - 'Notifications:' => 'Obavještenja: ', - 'Notifications' => 'Obavještenja', - 'Account type:' => 'Vrsta korisničkog računa:', - 'Edit profile' => 'Uredi profil', - 'Change password' => 'Promijeni šifru', - 'Password modification' => 'Izmjena šifre', - 'External authentications' => 'Vanjske autentikacije', - 'Never connected.' => 'Bez konekcija.', - 'No external authentication enabled.' => 'Bez omogućenih vanjskih autentikacija.', - 'Password modified successfully.' => 'Uspješna izmjena šifre.', - 'Unable to change the password.' => 'Nije moguće izmijeniti šifru.', - 'Change category' => 'Izmijeni kategoriju', - '%s updated the task %s' => '%s izmijenio zadatak %s', - '%s opened the task %s' => '%s otvorio zadatak %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s premjestio zadatak %s na poziciju #%d u koloni "%s"', - '%s moved the task %s to the column "%s"' => '%s premjestio zadatak %s u kolonu "%s"', - '%s created the task %s' => '%s kreirao zadatak %s', - '%s closed the task %s' => '%s zatvorio zadatak %s', - '%s created a subtask for the task %s' => '%s kreirao pod-zadatak zadatka %s', - '%s updated a subtask for the task %s' => '%s izmijenio pod-zadatak zadatka %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Dodijeljen korisniku %s uz procjenu vremena %s/%sh', - 'Not assigned, estimate of %sh' => 'Ne dodijeljen, procijenjeno vrijeme %sh', - '%s updated a comment on the task %s' => '%s izmijenio komentar zadatka %s', - '%s commented the task %s' => '%s komentarisao zadatak %s', - '%s\'s activity' => 'Aktivnosti %s', - 'RSS feed' => 'RSS kanal', - '%s updated a comment on the task #%d' => '%s izmijenio komentar zadatka #%d', - '%s commented on the task #%d' => '%s komentarisao zadatak #%d', - '%s updated a subtask for the task #%d' => '%s izmijenio pod-zadatak zadatka #%d', - '%s created a subtask for the task #%d' => '%s kreirao pod-zadatak zadatka #%d', - '%s updated the task #%d' => '%s ažurirao zadatak #%d', - '%s created the task #%d' => '%s kreirao zadatak #%d', - '%s closed the task #%d' => '%s zatvorio zadatak #%d', - '%s open the task #%d' => '%s otvorio zadatak #%d', - '%s moved the task #%d to the column "%s"' => '%s premjestio zadatak #%d u kolonu "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s premjestio zadatak #%d na poziciju %d u koloni "%s"', - 'Activity' => 'Aktivnosti', - 'Default values are "%s"' => 'Podrazumijevane vrijednosti su: "%s"', - 'Default columns for new projects (Comma-separated)' => 'Podrazumijevane kolone za novi projekat (Odvojene zarezom)', - 'Task assignee change' => 'Promijena izvršioca zadatka', - '%s change the assignee of the task #%d to %s' => '%s zamijeni izvršioca za zadatak #%d u %s', - '%s changed the assignee of the task %s to %s' => '%s promijenio izvršioca za zadatak %s u %s', - 'New password for the user "%s"' => 'Nova šifra korisnika "%s"', - 'Choose an event' => 'Izaberi događaj', - 'Create a task from an external provider' => 'Kreiraj zadatak preko posrednika', - 'Change the assignee based on an external username' => 'Izmijene izvršioca bazirano na vanjskom korisničkom imenu', - 'Change the category based on an external label' => 'Izmijene kategorije bazirano na vanjskoj etiketi', - 'Reference' => 'Referenca', - 'Label' => 'Etiketa', - 'Database' => 'Baza', - 'About' => 'O Kanboardu', - 'Database driver:' => 'Database driver:', - 'Board settings' => 'Postavke table', - 'Webhook settings' => 'Postavke za webhook', - 'Reset token' => 'Resetuj token', - 'API endpoint:' => 'API endpoint', - 'Refresh interval for private board' => 'Interval osvježavanja privatnih ploča', - 'Refresh interval for public board' => 'Interval osvježavanja javnih ploča', - 'Task highlight period' => 'Period naznačavanja zadatka', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Period (u sekundama) u kom su se događale promjene na zadatku (0 je onemogućeno, 2 dana je uobičajeno)', - 'Frequency in second (60 seconds by default)' => 'Frekvencija u sekundama (60 sekundi je uobičajeno)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvencija u sekundama (0 je onemogućeno u budućnosti, 10 sekundi je uobičajeno)', - 'Application URL' => 'URL aplikacije', - 'Token regenerated.' => 'Token regenerisan.', - 'Date format' => 'Format datuma', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO je uvijek prihvatljiv, primjer: "%s", "%s"', - 'New private project' => 'Novi privatni projekat', - 'This project is private' => 'Ovaj projekat je privatan', - 'Add' => 'Dodaj', - 'Start date' => 'Datum početka', - 'Time estimated' => 'Procijenjeno vrijeme', - 'There is nothing assigned to you.' => 'Ništa ti nije dodijeljeno', - 'My tasks' => 'Moji zadaci', - 'Activity stream' => 'Spisak aktivnosti', - 'Dashboard' => 'Panel', - 'Confirmation' => 'Potvrda', - 'Allow everybody to access to this project' => 'Dozvoli svima pristup ovom projektu', - 'Everybody have access to this project.' => 'Svima je dozvoljen pristup ovom projektu.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Napravi komentar preko vanjskog posrednika', - 'Project management' => 'Upravljanje projektima', - 'My projects' => 'Moji projekti', - 'Columns' => 'Kolone', - 'Task' => 'Zadatak', - 'Your are not member of any project.' => 'Nisi član ni jednog projekta', - 'Percentage' => 'Procenat', - 'Number of tasks' => 'Broj zadataka', - 'Task distribution' => 'Podjela zadataka', - 'Reportings' => 'Izveštaji', - 'Task repartition for "%s"' => 'Zaduženja zadataka za "%s"', - 'Analytics' => 'Analiza', - 'Subtask' => 'Pod-zadatak', - 'My subtasks' => 'Moji pod-zadaci', - 'User repartition' => 'Zaduženja korisnika', - 'User repartition for "%s"' => 'Zaduženja korisnika za "%s"', - 'Clone this project' => 'Kloniraj ovaj projekat', - 'Column removed successfully.' => 'Kolona uspješno uklonjena.', - 'Not enough data to show the graph.' => 'Nedovoljno podataka za prikaz na grafikonu.', - 'Previous' => 'Prethodni', - 'The id must be an integer' => 'ID mora biti cjeloviti broj', - 'The project id must be an integer' => 'ID projekta mora biti cjeloviti broj', - 'The status must be an integer' => 'Status mora biti cjeloviti broj', - 'The subtask id is required' => 'ID pod-zadataka je obavezan', - 'The subtask id must be an integer' => 'ID pod-zadatka mora biti cjeloviti broj', - 'The task id is required' => 'ID zadatka je obavezan', - 'The task id must be an integer' => 'ID zadatka mora biti cjeloviti broj', - 'The user id must be an integer' => 'ID korisnika mora biti cjeloviti broj', - 'This value is required' => 'Vrijednost je obavezna', - 'This value must be numeric' => 'Vrijednost mora biti broj', - 'Unable to create this task.' => 'Nije moguće kreirati zadatak.', - 'Cumulative flow diagram' => 'Zbirni dijagram toka', - 'Cumulative flow diagram for "%s"' => 'Zbirni dijagram toka za "%s"', - 'Daily project summary' => 'Zbirni pregled po danima', - 'Daily project summary export' => 'Izvoz zbirnog pregleda po danima', - 'Daily project summary export for "%s"' => 'Izvoz zbirnog pregleda po danima za "%s"', - 'Exports' => 'Izvozi', - 'This export contains the number of tasks per column grouped per day.' => 'Ovaj izvoz sadržava broj zadataka po koloni grupisanih po danima.', - 'Active swimlanes' => 'Aktivne swimline trake', - 'Add a new swimlane' => 'Dodaj novu swimline traku', - 'Change default swimlane' => 'Preimenuj podrazumijevanu swimline traku', - 'Default swimlane' => 'Podrazumijevana swimline traka', - 'Do you really want to remove this swimlane: "%s"?' => 'Da li zaista želiš ukloniti ovu swimline traku: "%s"?', - 'Inactive swimlanes' => 'Neaktivne swimline trake', - 'Remove a swimlane' => 'Ukloni swimline traku', - 'Show default swimlane' => 'Prikaži podrazumijevanu swimline traku', - 'Swimlane modification for the project "%s"' => 'Izmjene swimline trake za projekat "%s"', - 'Swimlane removed successfully.' => 'Swimline traka uspješno uklonjena.', - 'Swimlanes' => 'Swimline trake', - 'Swimlane updated successfully.' => 'Swimline traka uspjeno ažurirana.', - 'The default swimlane have been updated successfully.' => 'Podrazumijevana swimline traka uspješno ažurirana.', - 'Unable to remove this swimlane.' => 'Nemoguće ukloniti swimline traku.', - 'Unable to update this swimlane.' => 'Nemoguće ažurirati swimline traku.', - 'Your swimlane have been created successfully.' => 'Swimline traka je uspješno kreirana.', - 'Example: "Bug, Feature Request, Improvement"' => 'Npr: "Greška, Zahtjev za izmjenama, Poboljšanje"', - 'Default categories for new projects (Comma-separated)' => 'Podrazumijevane kategorije za novi projekat', - 'Integrations' => 'Integracije', - 'Integration with third-party services' => 'Integracija sa uslugama vanjskih servisa', - 'Subtask Id' => 'ID pod-zadatka', - 'Subtasks' => 'Pod-zadaci', - 'Subtasks Export' => 'Izvoz pod-zadataka', - 'Subtasks exportation for "%s"' => 'Izvoz pod-zadataka za "%s"', - 'Task Title' => 'Naslov zadatka', - 'Untitled' => 'Bez naslova', - 'Application default' => 'Podrazumijevano od aplikacije', - 'Language:' => 'Jezik:', - 'Timezone:' => 'Vremenska zona:', - 'All columns' => 'Sve kolone', - 'Calendar' => 'Kalendar', - 'Next' => 'Slijedeći', - '#%d' => '#%d', - 'All swimlanes' => 'Sve swimline trake', - 'All colors' => 'Sve boje', - 'Moved to column %s' => 'Premješten u kolonu %s', - 'User dashboard' => 'Korisnički panel', - 'Allow only one subtask in progress at the same time for a user' => 'Dozvoli samo jedan pod-zadatak "u radu" po korisniku', - 'Edit column "%s"' => 'Uredi kolonu "%s"', - 'Select the new status of the subtask: "%s"' => 'Izaberi novi status za pod-zadatak: "%s"', - 'Subtask timesheet' => 'Vremenska tabela za pod-zadatak', - 'There is nothing to show.' => 'Nema ništa za pokazati', - 'Time Tracking' => 'Praćenje vremena', - 'You already have one subtask in progress' => 'Već imaš jedan pod-zadatak "u radu"', - 'Which parts of the project do you want to duplicate?' => 'Koje delove projekta želiš duplicirati?', - 'Disallow login form' => 'Zabrani prijavnu formu', - 'Start' => 'Početak', - 'End' => 'Kraj', - 'Task age in days' => 'Trajanje zadatka u danima', - 'Days in this column' => 'Dani u ovoj koloni', - '%dd' => '%dd', - 'Add a new link' => 'Dodaj novu vezu', - 'Do you really want to remove this link: "%s"?' => 'Da li zaista želite ukloniti ovu vezu: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Da li zaista želite ukloniti ovu vezu sa zadatkom #%d?', - 'Field required' => 'Polje je obavezno', - 'Link added successfully.' => 'Veza je uspješno dodana.', - 'Link updated successfully.' => 'Veza je uspješno ažurirana.', - 'Link removed successfully.' => 'Veza je uspješno uklonjena.', - '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', - 'Unable to create your link.' => 'Nemoguće napraviti vezu.', - 'Unable to update your link.' => 'Nemoguće ažurirati vezu.', - 'Unable to remove this link.' => 'Nemoguće ukloniti vezu.', - 'relates to' => 'relacija sa', - 'blocks' => 'blokira', - 'is blocked by' => 'je blokiran od', - 'duplicates' => 'duplicira', - 'is duplicated by' => 'je dupliciran od', - 'is a child of' => 'je dijete od', - 'is a parent of' => 'je roditelj od', - 'targets milestone' => 'cilj prekretnice', - 'is a milestone of' => 'je od prekretnice', - 'fixes' => 'popravlja', - 'is fixed by' => 'je popravljen od', - 'This task' => 'Ovaj zadatak', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Proširi zadatke', - 'Collapse tasks' => 'Skupi zadatke', - 'Expand/collapse tasks' => 'Proširi/skupi zadatke', - 'Close dialog box' => 'Skupi dialog', - 'Submit a form' => 'Pošalji obrazac', - 'Board view' => 'Pregled ploče', - 'Keyboard shortcuts' => 'Prečice tastature', - 'Open board switcher' => 'Otvori prekidače ploče', - 'Application' => 'Aplikacija', - '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', - 'CAD - Canadian Dollar' => 'CAD - Kanadski dolar', - 'CHF - Swiss Francs' => 'CHF - Švicarski franak', - 'Custom Stylesheet' => 'Prilagođeni stil', - 'download' => 'preuzmi', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Britanska funta', - 'INR - Indian Rupee' => 'INR - Indijski rupi', - 'JPY - Japanese Yen' => 'JPY - Japanski jen', - 'NZD - New Zealand Dollar' => 'NZD - Novozelandski dolar', - 'RSD - Serbian dinar' => 'RSD - Srpski dinar', - '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', - 'Move the task to another column when assignee is cleared' => 'Premjesti zadatak u neku drugu kolonu kada se ukloni izvršilac', - 'Source column' => 'Izvorna kolona', - 'Transitions' => 'Prelaz', - 'Executer' => 'Izvršilac', - 'Time spent in the column' => 'Vrijeme provedeno u koloni', - 'Task transitions' => 'Prelazi zadatka', - 'Task transitions export' => 'Izvezi prelaze zadatka', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Ovaj izvještaj sadržava sve kolone premještanja za svaki zadatak s datumom, te korisnikom i utrošenim vremenom za svaki premještaj.', - '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.', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s je uklonio izvršioca zadatka %s', - 'Enable Gravatar images' => 'Omogući Gravatar slike', - 'Information' => 'Informacije', - 'Check two factor authentication code' => 'Provjera faktor-dva autentifikacionog koda', - 'The two factor authentication code is not valid.' => 'Faktor-dva autentifikacionog koda nije validan.', - 'The two factor authentication code is valid.' => 'Faktor-dva autentifikacionog koda je validan.', - 'Code' => 'Kod', - 'Two factor authentication' => 'Faktor-dva autentifikacija', - 'This QR code contains the key URI: ' => 'Ovaj QR kod sadržava ključni URL: ', - 'Check my code' => 'Provjeri moj kod', - 'Secret key: ' => 'Tajni ključ: ', - 'Test your device' => 'Testiraj svoj uređaj', - 'Assign a color when the task is moved to a specific column' => 'Dodijeli boju kada je zadatak pomjeren u odabranu kolonu', - '%s via Kanboard' => '%s uz pomoć Kanboard-a', - 'Burndown chart for "%s"' => 'Grafikon izgaranja za "%s"', - 'Burndown chart' => 'Grafikon izgaranja', - 'This chart show the task complexity over the time (Work Remaining).' => 'Ovaj grafikon pokazuje kompleksnost zadatka u vremenu (Preostalo vremena)', - 'Screenshot taken %s' => 'Slika ekrana uzeta %s', - 'Add a screenshot' => 'Dodaj sliku ekrana', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Uzmi sliku ekrana i pritisni CTRL+V ili ⌘+V da zalijepiš ovdje.', - 'Screenshot uploaded successfully.' => 'Slika ekrana uspješno dodana.', - 'SEK - Swedish Krona' => 'SEK - Švedska kruna', - 'Identifier' => 'Identifikator', - 'Disable two factor authentication' => 'Onemogući faktor-dva autentifikaciju', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Da li zaista želiš onemogućiti faktor-dva autentifikaciju: "%s"?', - 'Edit link' => 'Uredi vezu', - 'Start to type task title...' => 'Počni pisati naslov zadatka...', - 'A task cannot be linked to itself' => 'Zadatak ne može biti povezan sa samim sobom', - 'The exact same link already exists' => 'Ista veza već postoji', - 'Recurrent task is scheduled to be generated' => 'Ponavljajući zadatak je pripremljen da bude kreiran', - 'Score' => 'Uspjeh', - 'The identifier must be unique' => 'Identifikator mora biti jedinstven', - 'This linked task id doesn\'t exists' => 'Povezani ID zadatka ne postoji', - 'This value must be alphanumeric' => 'Ova vrijednost mora biti alfanumerička', - 'Edit recurrence' => 'Uredi ponavljanje', - 'Generate recurrent task' => 'Napravi ponavljajući zadatak', - 'Trigger to generate recurrent task' => 'Okidač koji pravi ponavljajući zadatak', - 'Factor to calculate new due date' => 'Faktor za računanje novog datuma završetka', - 'Timeframe to calculate new due date' => 'Vremenski okvir za računanje novog datuma završetka', - 'Base date to calculate new due date' => 'Početni datum za računanje novog datuma završetka', - 'Action date' => 'Datum akcije', - 'Base date to calculate new due date: ' => 'Početni datum za računanje novog datuma završetka: ', - 'This task has created this child task: ' => 'Ovaj zadatak će napraviti zadatak-dijete: ', - 'Day(s)' => 'Dan(i)', - 'Existing due date' => 'Postojeći datum završetka', - 'Factor to calculate new due date: ' => 'Faktor za računanje novog datuma završetka: ', - 'Month(s)' => 'Mjesec(i)', - 'Recurrence' => 'Referenca', - 'This task has been created by: ' => 'Ovaj zadatak je napravio: ', - 'Recurrent task has been generated:' => 'Ponavljajući zadatak je napravio:', - 'Timeframe to calculate new due date: ' => 'Vremenski okvir za računanje novog datuma završetka:', - 'Trigger to generate recurrent task: ' => 'Okidač za pravljenje ponavljajućeg zadatka', - 'When task is closed' => 'Kada je zadatak zatvoren', - 'When task is moved from first column' => 'Kada je zadatak premješten iz prve kolone', - 'When task is moved to last column' => 'Kada je zadatak premješten u posljednju kolonu', - 'Year(s)' => 'Godina/e', - 'Calendar settings' => 'Postavke kalendara', - 'Project calendar view' => 'Pregled kalendara projekta', - 'Project settings' => 'Postavke projekta', - 'Show subtasks based on the time tracking' => 'Prikaži pod-zadatke bazirano na vremenskom praćenju', - 'Show tasks based on the creation date' => 'Prikaži zadatke bazirano na vremenu otvaranja', - 'Show tasks based on the start date' => 'Prikaži zadatke bazirano na vremenu početka rada', - 'Subtasks time tracking' => 'Vremensko praćenje pod-zadataka', - 'User calendar view' => 'Pregled korisničkog kalendara', - 'Automatically update the start date' => 'Automatski ažuriraj početni datum', - 'iCal feed' => 'iCal kanal', - 'Preferences' => 'Postavke', - 'Security' => 'Sigurnost', - 'Two factor authentication disabled' => 'Faktor-dva autentifikacija onemogućena', - 'Two factor authentication enabled' => 'Faktor-dva autentifikacija omogućena', - 'Unable to update this user.' => 'Nemoguće ažurirati ovog korisnika', - 'There is no user management for private projects.' => 'Nema mehanizma za upravljanje korisnicima kod privatnih projekata.', - 'User that will receive the email' => 'Korisnik će dobiti email', - 'Email subject' => 'Predmet email-a', - 'Date' => 'Datum', - 'Add a comment log when moving the task between columns' => 'Dodaj komentar u dnevnik kada se pomjeri zadatak između kolona', - 'Move the task to another column when the category is changed' => 'Pomjeri zadatak u drugu kolonu kada je kategorija promijenjena', - 'Send a task by email to someone' => 'Pošalji zadatak nekome emailom', - 'Reopen a task' => 'Ponovo otvori zadatak', - 'Column change' => 'Promijena kolone', - 'Position change' => 'Promjena pozicije', - 'Swimlane change' => 'Promjena swimline trake', - 'Assignee change' => 'Promijenjen izvršilac', - '[%s] Overdue tasks' => '[%s] Zaostali zadaci', - 'Notification' => 'Obavještenja', - '%s moved the task #%d to the first swimlane' => '%s je premjestio zadatak #%d u prvu swimline traku', - '%s moved the task #%d to the swimlane "%s"' => '%s je premjestio zadatak #%d u swimline traku "%s"', - 'Swimlane' => 'Swimline traka', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s je premjestio zadatak %s u prvi swimline traku', - '%s moved the task %s to the swimlane "%s"' => '%s je premjestio zadatak %s u swimline traku "%s"', - 'This report contains all subtasks information for the given date range.' => 'Ovaj izvještaj sadržava sve informacije o pod-zadacima za dati period', - 'This report contains all tasks information for the given date range.' => 'Ovaj izvještaj sadržava sve informacije o zadacima u datom periodu', - 'Project activities for %s' => 'Aktivnosti projekta za %s', - 'view the board on Kanboard' => 'pregled ploče na Kanboard-u', - 'The task have been moved to the first swimlane' => 'Zadatak je premješten u prvu swimline traku', - 'The task have been moved to another swimlane:' => 'Zadatak je premješten u drugu swimline traku', - 'New title: %s' => 'Novi naslov: %s', - 'The task is not assigned anymore' => 'Zadatak nema više izvršioca', - 'New assignee: %s' => 'Novi izvršilac: %s', - 'There is no category now' => 'Sada nema kategorije', - 'New category: %s' => 'Nova kategorija: %s', - 'New color: %s' => 'Nova boja: %s', - 'New complexity: %d' => 'Nova složenost: %d', - 'The due date have been removed' => 'Datum završetka je ukloljen', - 'There is no description anymore' => 'Nema više opisa', - 'Recurrence settings have been modified' => 'Promijenjene postavke za ponavljajuće zadatke', - 'Time spent changed: %sh' => 'Utrošeno vrijeme je promijenjeno: %sh', - 'Time estimated changed: %sh' => 'Očekivano vrijeme je promijenjeno: %sh', - 'The field "%s" have been updated' => 'Polje "%s" je ažurirano', - 'The description has been modified:' => 'Promijenjen opis:', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Da li zaista želiš zatvoriti zadatak "%s" kao i sve pod-zadatke?', - 'I want to receive notifications for:' => 'Želim dobijati obavještenja za:', - 'All tasks' => 'Sve zadatke', - 'Only for tasks assigned to me' => 'Samo za zadatke na kojima sam izvršilac', - 'Only for tasks created by me' => 'Samo za zadatke koje sam ja napravio', - 'Only for tasks created by me and assigned to me' => 'Samo za zadatke koje sam ja napravio i na kojima sam izvršilac', - '%%Y-%%m-%%d' => '%%Y-%%m-%%d', - 'Total for all columns' => 'Ukupno za sve kolone', - 'You need at least 2 days of data to show the chart.' => 'Da bi se prikazao ovaj grafik potrebni su podaci iz najmanje posljednja dva dana.', - '<15m' => '<15m', - '<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', - 'Reset filters' => 'Vrati filtere na početno', - 'My tasks due tomorrow' => 'Moji zadaci koje treba završiti sutra', - 'Tasks due today' => 'Zadaci koje treba završiti danas', - 'Tasks due tomorrow' => 'Zadaci koje treba završiti sutra', - 'Tasks due yesterday' => 'Zadaci koje je trebalo završiti jučer', - 'Closed tasks' => 'Zatvoreni zadaci', - 'Open tasks' => 'Otvoreni zadaci', - 'Not assigned' => 'Bez izvršioca', - 'View advanced search syntax' => 'Vidi naprednu sintaksu pretrage', - 'Overview' => 'Opšti pregled', - 'Board/Calendar/List view' => 'Pregled Ploče/Kalendara/Liste', - 'Switch to the board view' => 'Promijeni da vidim ploču', - 'Switch to the calendar view' => 'Promijeni da vidim kalendar', - 'Switch to the list view' => 'Promijeni da vidim listu', - 'Go to the search/filter box' => 'Idi na kutiju s pretragom/filterima', - 'There is no activity yet.' => 'Još uvijek nema aktivnosti.', - 'No tasks found.' => 'Zadaci nisu pronađeni.', - 'Keyboard shortcut: "%s"' => 'Prečica tastature: "%s"', - 'List' => 'Lista', - 'Filter' => 'Filter', - 'Advanced search' => 'Napredna pretraga', - 'Example of query: ' => 'Primjer za upit: ', - 'Search by project: ' => 'Pretraga po projektu: ', - 'Search by column: ' => 'Pretraga po koloni: ', - 'Search by assignee: ' => 'Pretraga po izvršiocu: ', - 'Search by color: ' => 'Pretraga po boji: ', - 'Search by category: ' => 'Pretraga po kategoriji: ', - 'Search by description: ' => 'Pretraga po opisu: ', - 'Search by due date: ' => 'Pretraga po datumu završetka: ', - 'Lead and Cycle time for "%s"' => 'Vrijeme upravljanje i vremenski ciklus za "%s"', - 'Average time spent into each column for "%s"' => 'Prosjek utrošenog vremena u svakoj koloni za "%s"', - 'Average time spent into each column' => 'Prosjek utrošenog vrmena u svakoj koloni', - 'Average time spent' => 'Prosjek utrošenog vremena', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Ovaj grafik pokazuje prosjek utrošenog vremena u svakoj koloni za posljednjih %d zadataka.', - 'Average Lead and Cycle time' => 'Prosjek vremena upravljanja i vremenskog ciklusa', - 'Average lead time: ' => 'Prosjek vremena upravljanja', - 'Average cycle time: ' => 'Prosjek vremenskog ciklusa', - 'Cycle Time' => 'Vremenski ciklus', - 'Lead Time' => 'Vrijeme upravljanja', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Ovaj grafik pokazuje prosjek vremena vođenja i vremenskog ciklusa za posljednjih %d zadataka tokom vremena.', - 'Average time into each column' => 'Prosječno vrijeme u svakoj koloni', - 'Lead and cycle time' => 'Vrijeme vođenja i vremenski ciklus', - 'Lead time: ' => 'Vrijeme vođenja: ', - 'Cycle time: ' => 'Vremenski ciklus: ', - 'Time spent into each column' => 'Utrošeno vrijeme u svakoj koloni', - 'The lead time is the duration between the task creation and the completion.' => 'Vrijeme vođenja je vrijeme koje je proteklo između otvaranja i zatvaranja zadatka.', - 'The cycle time is the duration between the start date and the completion.' => 'Vremenski ciklus je vrijeme koje je proteklo između početka i završetka rada na zadatku.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Ako zadatak nije zatvoren trenutno vrijeme je iskorišteno umjesto datuma završetka.', - 'Set automatically the start date' => 'Automatski postavi početno vrijeme', - 'Edit Authentication' => 'Uredi autentifikaciju', - '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.', - 'Trigger automatically subtask time tracking' => 'Okidač za automatsko vremensko praćenje za pod-zadatke', - 'Include closed tasks in the cumulative flow diagram' => 'Obuhvati zatvorene zadatke u kumulativnom dijagramu toka', - 'Current swimlane: %s' => 'Trenutna swimline traka: %s', - 'Current column: %s' => 'Trenutna kolona: %s', - 'Current category: %s' => 'Trenutna kategorija: %s', - 'no category' => 'bez kategorije', - 'Current assignee: %s' => 'Trenutni izvršilac: %s', - 'not assigned' => 'bez ivršioca', - 'Author:' => 'Autor:', - 'contributors' => 'saradnici', - 'License:' => 'Licenca:', - 'License' => 'Licenca', - 'Enter the text below' => 'Unesi tekst ispod', - 'Gantt chart for %s' => 'Gantogram za %s', - 'Sort by position' => 'Sortiraj po poziciji', - 'Sort by date' => 'Sortiraj po datumu', - 'Add task' => 'Dodaj zadatak', - 'Start date:' => 'Početno vrijeme:', - 'Due date:' => 'Vrijeme do kada treba završiti:', - 'There is no start date or due date for this task.' => 'Nema početnog datuma ili datuma do kada treba završiti ovaj zadatak.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Premještanje ili promjena veličine zadatka će promijeniti datum početka i datum do kada treba završiti zadatak.', - 'There is no task in your project.' => 'Nema zadataka u tvom projektu.', - 'Gantt chart' => 'Gantogram', - 'People who are project managers' => 'Osobe koji su menadžeri projekta', - 'People who are project members' => 'Osobe koje su članovi projekta', - 'NOK - Norwegian Krone' => 'NOK - Norveška kruna', - 'Show this column' => 'Prikaži ovu kolonu', - 'Hide this column' => 'Sakrij ovu kolonu', - 'open file' => 'otvori fajl', - 'End date' => 'Datum završetka', - 'Users overview' => 'Opšti pregled korisnika', - 'Members' => 'Članovi', - 'Shared project' => 'Dijeljeni projekti', - 'Project managers' => 'Menadžeri projekta', - 'Gantt chart for all projects' => 'Gantogram za sve projekte', - 'Projects list' => 'Lista projekata', - 'Gantt chart for this project' => 'Gantogram za ovaj projekat', - 'Project board' => 'Ploča projekta', - 'End date:' => 'Datum završetka:', - 'There is no start date or end date for this project.' => 'Nema početnog ili krajnjeg datuma za ovaj projekat.', - 'Projects Gantt chart' => 'Gantogram projekata', - 'Change task color when using a specific task link' => 'Promijeni boju zadatka kada se koristi određena veza na zadatku', - 'Task link creation or modification' => 'Veza na zadatku je napravljena ili izmijenjena', - 'Milestone' => 'Prekretnica', - 'Documentation: %s' => 'Dokumentacija: %s', - 'Switch to the Gantt chart view' => 'Promijeni u gantogram pregled', - 'Reset the search/filter box' => 'Vrati na početno pretragu/filtere', - 'Documentation' => 'Dokumentacija', - 'Table of contents' => 'Sadržaj', - 'Gantt' => 'Gantogram', - 'Author' => 'Autor', - 'Version' => 'Verzija', - 'Plugins' => 'Dodaci', - 'There is no plugin loaded.' => 'Nema učitanih dodataka.', - 'Set maximum column height' => 'Postavi maksimalnu visinu kolone', - 'Remove maximum column height' => 'Ukloni maksimalnu visinu kolone', - 'My notifications' => 'Moja obavještenja', - 'Custom filters' => 'Prilagođeni filteri', - 'Your custom filter have been created successfully.' => 'Tvoj prilagođeni filter je uspješno napravljen.', - 'Unable to create your custom filter.' => 'Nemoguće napraviti prilagođeni filter.', - 'Custom filter removed successfully.' => 'Prilagođeni filter uspješno uklonjen.', - 'Unable to remove this custom filter.' => 'Nemoguće ukloniti prilagođeni filter.', - 'Edit custom filter' => 'Uredi prilagođeni filter', - 'Your custom filter have been updated successfully.' => 'Prilagođeni filter uspješno ažuriran.', - 'Unable to update custom filter.' => 'Nemoguće ažurirati prilagođeni filter', - 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Novi priložak na zadatku #%d: %s', - 'New comment on task #%d' => 'Novi komentar na zadatku #%d', - 'Comment updated on task #%d' => 'Ažuriran komentar na zadatku #%d', - 'New subtask on task #%d' => 'Novi pod-zadatak na zadatku #%d', - 'Subtask updated on task #%d' => 'Pod-zadatak ažuriran na zadatku #%d', - 'New task #%d: %s' => 'Novi zadatak #%d: %s', - 'Task updated #%d' => 'Zadatak ažuriran #%d', - 'Task #%d closed' => 'Zadatak #%d zatvoren', - 'Task #%d opened' => 'Zadatak #%d otvoren', - 'Column changed for task #%d' => 'Promijenjena kolona za zadatak #%d', - 'New position for task #%d' => 'Nova pozicija za zadatak #%d', - 'Swimlane changed for task #%d' => 'Swimline traka promijenjena za zadatak #%d', - 'Assignee changed on task #%d' => 'Promijenjen izvršilac na zadatku #%d', - '%d overdue tasks' => '%d zadataka kasni', - 'Task #%d is overdue' => 'Zadatak #%d kasni', - 'No new notifications.' => 'Nema novih obavještenja.', - 'Mark all as read' => 'Označi sve kao pročitano', - 'Mark as read' => 'Označi kao pročitano', - 'Total number of tasks in this column across all swimlanes' => 'Ukupan broj zadataka u ovoj koloni u svim swimline trakama', - 'Collapse swimlane' => 'Skupi swimline trake', - 'Expand swimlane' => 'Proširi swimline trake', - 'Add a new filter' => 'Dodaj novi filter', - 'Share with all project members' => 'Podijeli sa svim članovima projekta', - 'Shared' => 'Podijeljeno', - '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!', - 'Import users from CSV file' => 'Uvezi korisnike putem CSV fajla', - '%d user(s) have been imported successfully.' => '%d korisnika uspješno uvezeno.', - 'Comma' => 'Zarez', - 'Semi-colon' => 'Tačka-zarez', - 'Tab' => 'Tab', - 'Vertical bar' => 'Vertikalna traka', - 'Double Quote' => 'Dvostruki navodnici', - 'Single Quote' => 'Jednostruki navodnici', - '%s attached a file to the task #%d' => '%s je dodao novi fajl u zadatak %d', - 'There is no column or swimlane activated in your project!' => 'Nema kolone ili swimline trake aktivirane za ovaj projekat!', - 'Append filter (instead of replacement)' => 'Dodaj filter (umjesto zamjene postojećeg)', - 'Append/Replace' => 'Dodaj/Zamijeni', - 'Append' => 'Dodaj', - 'Replace' => 'Zamijeni', - 'Import' => 'Uvoz', - 'change sorting' => 'Promijeni sortiranje', - 'Tasks Importation' => 'Uvoz zadataka', - 'Delimiter' => 'Djelilac', - 'Enclosure' => 'Prilog', - 'CSV File' => 'CSV File', - 'Instructions' => 'Uputstva', - 'Your file must use the predefined CSV format' => 'File mora biti predefinisani CSV format', - 'Your file must be encoded in UTF-8' => 'File mora biti u UTF-8 kodu', - 'The first row must be the header' => 'Prvi red mora biti zaglavlje', - 'Duplicates are not verified for you' => 'Dupliciranja neće biti provjeravana (to ćeš morati uraditi ručno)', - 'The due date must use the ISO format: YYYY-MM-DD' => 'Datum do kog se treba izvršiti mora biti u ISO formatu: GGGG-MM-DD', - 'Download CSV template' => 'Preuzmi CSV šablon', - 'No external integration registered.' => 'Nema registrovanih vanjskih integracija.', - 'Duplicates are not imported' => 'Duplikati nisu uvezeni', - 'Usernames must be lowercase and unique' => 'Korisničko ime mora biti malim slovima i jedinstveno', - 'Passwords will be encrypted if present' => 'Šifra će biti kriptovana', - '%s attached a new file to the task %s' => '%s je dodano novi fajl u zadatak %s', - 'Link type' => 'Tip veze', - 'Assign automatically a category based on a link' => 'Automatsko pridruživanje kategorije bazirano na vezi', - 'BAM - Konvertible Mark' => 'BAM - Konvertibilna marka', - 'Assignee Username' => 'Pridruži korisničko ime', - 'Assignee Name' => 'Pridruži ime', - 'Groups' => 'Grupe', - 'Members of %s' => 'Članovi %s', - 'New group' => 'Nova grupa', - 'Group created successfully.' => 'Grupa uspješno kreirana.', - 'Unable to create your group.' => 'Nemoguće kreirati grupu.', - 'Edit group' => 'Uredi grupu', - 'Group updated successfully.' => 'Grupa uspješno ažurirana.', - 'Unable to update your group.' => 'Nemoguće ažurirati grupu', - 'Add group member to "%s"' => 'Dodaj člana grupe u ""%s"', - 'Group member added successfully.' => 'Uspješno dodan član grupe.', - 'Unable to add group member.' => 'Nemoguće dodati člana grupe.', - 'Remove user from group "%s"' => 'Ukloni korisnika iz grupe "%s"', - 'User removed successfully from this group.' => 'Korisnik uspješno uklonjen iz grupe.', - 'Unable to remove this user from the group.' => 'Nemoguće ukloniti korisnika iz grupe.', - 'Remove group' => 'Ukloni grupu', - 'Group removed successfully.' => 'Grupa uspješno uklonjena.', - 'Unable to remove this group.' => 'Nemoguće ukloniti grupu.', - 'Project Permissions' => 'Prava na projektu', - 'Manager' => 'Menadžer', - 'Project Manager' => 'Menadžer projekta', - 'Project Member' => 'Član projekta', - 'Project Viewer' => 'Preglednik projekta', - 'Your account is locked for %d minutes' => 'Tvoj korisnički račun je zaključan za narednih %d minuta', - 'Invalid captcha' => 'Pogrešna captcha', - 'The name must be unique' => 'Ime mora biti jedinstveno', - 'View all groups' => 'Pregledaj sve grupe', - 'View group members' => 'Pregledaj članove grupe', - 'There is no user available.' => 'Trenutno nema dostupnih korisnika.', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Da li zaista želiš ukloniti korisnika "%s" iz grupe "%s"?', - 'There is no group.' => 'Trenutno nema grupa.', - 'External Id' => 'Vanjski Id', - 'Add group member' => 'Dodaj člana grupe', - 'Do you really want to remove this group: "%s"?' => 'Da li zaista želiš ukloniti ovu grupu: "%s"?', - 'There is no user in this group.' => 'Trenutno nema korisnika u grupi.', - 'Remove this user' => 'Ukloni ovog korisnika', - 'Permissions' => 'Prava', - 'Allowed Users' => 'Dozvoljeni korisnici', - 'No user have been allowed specifically.' => 'Nema korisnika sa specijalnim dozvolama.', - 'Role' => 'Uloge', - 'Enter user name...' => 'Unesi korisničko ime...', - 'Allowed Groups' => 'Dozvoljene grupe', - 'No group have been allowed specifically.' => 'Nema grupa sa specijalnim dozvolama.', - 'Group' => 'Grupa', - 'Group Name' => 'Ime grupe', - 'Enter group name...' => 'Unesi ime grupe...', - 'Role:' => 'Uloga:', - 'Project members' => 'Članovi projekta', - 'Compare hours for "%s"' => 'Poredi sate za "%s"', - '%s mentioned you in the task #%d' => '%s te spomenuo u zadatku #%d', - '%s mentioned you in a comment on the task #%d' => '%s te spomenuo u komentaru zadatka #%d', - 'You were mentioned in the task #%d' => 'Spomenut si u zadatku #%d', - 'You were mentioned in a comment on the task #%d' => 'Spomenut si u komentaru zadatka #%d', - 'Mentioned' => 'Spominjanja', - 'Compare Estimated Time vs Actual Time' => 'Poređenje očekivanog i aktuelnog vremena', - 'Estimated hours: ' => 'Očekivani sati:', - 'Actual hours: ' => 'Aktuelni sati:', - 'Hours Spent' => 'Utrošeni sati:', - 'Hours Estimated' => 'Očekivani sati', - 'Estimated Time' => 'Očekivano vrijeme', - 'Actual Time' => 'Aktuelno vrijeme', - 'Estimated vs actual time' => 'Očekivano nasuprot aktuelnog vremena', - 'RUB - Russian Ruble' => 'RUB - Ruski rubij', - 'Assign the task to the person who does the action when the column is changed' => 'Dodijeli zadatak osobi koja izvrši akciju promjene kolone', - 'Close a task in a specific column' => 'Zatvori zadatak u određenoj koloni', - 'Time-based One-time Password Algorithm' => 'Vremenski bazirani One-time Algoritam šifri', - 'Two-Factor Provider: ' => 'Two-Factor provajder', - 'Disable two-factor authentication' => 'Onemogući two-factor autentifikaciju', - 'Enable two-factor authentication' => 'Omogući two-factor autentifikaciju', - 'There is no integration registered at the moment.' => 'Trenutno nema registrovanih integracija.', - 'Password Reset for Kanboard' => 'Promjena šifre za Kanboard', - 'Forgot password?' => 'Ne mogu da se sjetim šifre?', - 'Enable "Forget Password"' => 'Omogući "Ne mogu da se sjetim šifre"', - 'Password Reset' => 'Promijena šifre', - 'New password' => 'Nova šifra', - 'Change Password' => 'Promijeni šifru', - 'To reset your password click on this link:' => 'Da bi promijenio šifru klikni na ovaj link:', - 'Last Password Reset' => 'Posljednja promjena šifre', - 'The password has never been reinitialized.' => 'Šifra nije nikada promijenjena.', - 'Creation' => 'Napravljena', - 'Expiration' => 'Ističe', - 'Password reset history' => 'Hitorija promjena šifri', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Svi zadaci kolone "%s" i swimline-a "%s" uspješno su zatvoreni.', - 'Do you really want to close all tasks of this column?' => 'Da li zaista želiš zatvoriti sve zadatke ove kolone?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d zadatak(ci) u koloni "%s" i swimline-u "%s" će biti zatvoreni.', - 'Close all tasks of this column' => 'Zatvori sve zadatke ove kolone', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nema posebnog plugin-a za obavještenja. Još uvijek možeš koristiti individualne postavke obavještenja na svom profilu.', - 'My dashboard' => 'Moj panel', - 'My profile' => 'Moj profil', - 'Project owner: ' => 'Vlasnik projekta:', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Identifikator projekta je opcionalan i mora biti alfanumerički, na primjer: MOJPROJEKAT.', - 'Project owner' => 'Vlasnik projekta', - 'Those dates are useful for the project Gantt chart.' => 'Ovi datumi su korisni za pravljenje Gantt dijagrama za projekat.', - 'Private projects do not have users and groups management.' => 'Privatni projekti ne mogu imati korisnike ili grupe korisnika.', - 'There is no project member.' => 'Nema članova projekta.', - 'Priority' => 'Prioritet', - 'Task priority' => 'Prioritet zadatka', - 'General' => 'Opšte', - 'Dates' => 'Datumi', - 'Default priority' => 'Podrazumijevani prioritet', - 'Lowest priority' => 'Najmanji prioritet', - 'Highest priority' => 'Najveći prioritet', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Ako upišeš nulu za najmanji i najveći prioritet, ova opcija će biti onemogućena.', - 'Close a task when there is no activity' => 'Zatvori zadatak kada nema aktivnosti', - 'Duration in days' => 'Dužina trajanja u danima', - 'Send email when there is no activity on a task' => 'Pošalji email kada nema aktivnosti na zadatku', - 'Unable to fetch link information.' => 'Ne mogu da pribavim informacije o vezi.', - 'Daily background job for tasks' => 'Dnevni pozadinski poslovi na zadacima', - 'Auto' => 'Automatski', - 'Related' => 'Povezani', - 'Attachment' => 'Dodijeljeni', - 'Title not found' => 'Bez naslova', - 'Web Link' => 'Web veza', - 'External links' => 'Vanjska veza', - 'Add external link' => 'Dodaj vanjsku vezu', - 'Type' => 'Vrsta', - 'Dependency' => 'Zavisnost', - 'Add internal link' => 'Dodaj unutrašnju vezu', - 'Add a new external link' => 'Dodaj novu vanjsku vezu', - 'Edit external link' => 'Uredi vanjsku vezu', - 'External link' => 'Vanjska veza', - 'Copy and paste your link here...' => 'Kopiraj i zalijepi svoju vezu ovdje...', - 'URL' => 'URL', - 'Internal links' => 'Unutrašnje veze', - 'Assign to me' => 'Dodijeli meni', - 'Me' => 'Za mene', - 'Do not duplicate anything' => 'Ništa ne dupliciraj', - 'Projects management' => 'Menadžment projekata', - 'Users management' => 'Menadžment korisnika', - 'Groups management' => 'Menadžment grupa', - 'Create from another project' => 'Napravi iz drugog projekta', - 'open' => 'otvoreno', - 'closed' => 'zatvoreno', - 'Priority:' => 'Prioritet:', - 'Reference:' => 'Preporuka:', - 'Complexity:' => 'Složenost:', - 'Swimlane:' => 'Swimline:', - 'Column:' => 'Kolona:', - 'Position:' => 'Pozicija:', - 'Creator:' => 'Kreator:', - 'Time estimated:' => 'Očekivano vrijeme:', - '%s hours' => '%s sati', - 'Time spent:' => 'Utrošeno vrijeme:', - 'Created:' => 'Kreirao:', - 'Modified:' => 'Uredio:', - 'Completed:' => 'Završio:', - 'Started:' => 'Početo:', - 'Moved:' => 'Pomjereno:', - 'Task #%d' => 'Zadatak #%d', - 'Date and time format' => 'Format za datum i vrijeme', - 'Time format' => 'Format za vrijeme', - 'Start date: ' => 'Početni datum:', - 'End date: ' => 'Krajnji datum:', - 'New due date: ' => 'Novi datum očekivanja:', - 'Start date changed: ' => 'Početni datum promijenjen:', - 'Disable private projects' => 'Onemogući privatne projekte', - 'Do you really want to remove this custom filter: "%s"?' => 'Da li zaista želiš ukloniti ovaj prilagođeni filter "%s"?', - 'Remove a custom filter' => 'Ukloni prilagođeni filter', - 'User activated successfully.' => 'Korisnik uspješno aktiviran.', - 'Unable to enable this user.' => 'Nemoguće omogućiti ovog korisnika.', - 'User disabled successfully.' => 'Korisnik uspješno onemogućen.', - 'Unable to disable this user.' => 'Nemoguće onemogućiti ovog korisnika.', - 'All files have been uploaded successfully.' => 'Svi fajlovi su uspješno dodani.', - 'View uploaded files' => 'Pregled dodanih fajlova', - 'The maximum allowed file size is %sB.' => 'Maksimalna dozvoljena veličina fajla je %sB.', - 'Choose files again' => 'Izaberi ponovo fajlove', - 'Drag and drop your files here' => 'Povuci i spusti svoje fajlove ovdje', - 'choose files' => 'izaberi fajlove', - 'View profile' => 'Pregledaj profil', - 'Two Factor' => 'Dva faktora', - 'Disable user' => 'Onemogući korisnika', - 'Do you really want to disable this user: "%s"?' => 'Da li zaista želiš onemogućiti ovog korisnika: "%s"?', - 'Enable user' => 'Omogući korisnika', - 'Do you really want to enable this user: "%s"?' => 'Da li zaista želiš omogućiti ovog korisnika: "%s"?', - 'Download' => 'Preuzeto', - 'Uploaded: %s' => 'Dodano: %s', - 'Size: %s' => 'Veličina: %s', - 'Uploaded by %s' => 'Dodao %s', - 'Filename' => 'Ime fajla', - 'Size' => 'Veličina', - 'Column created successfully.' => 'Kolona uspješno napravljena.', - 'Another column with the same name exists in the project' => 'Već postoji kolona s istim imenom u ovom projektu.', - 'Default filters' => 'Podrazumijevani filteri', - 'Your board doesn\'t have any columns!' => 'Vaš panel nema ni jednu kolonu!', - 'Change column position' => 'Promijeni poziciju kolone', - 'Switch to the project overview' => 'Promijeni u pregled projekta', - 'User filters' => 'Korisnički filteri', - 'Category filters' => 'Kategorija filtera', - 'Upload a file' => 'Dodaj fajl', - 'View file' => 'Pregled fajla', - 'Last activity' => 'Posljednja aktivnost', - 'Change subtask position' => 'Promijeni poziciju pod-zadatka', - 'This value must be greater than %d' => 'Ova vrijednost mora biti veća od %d', - 'Another swimlane with the same name exists in the project' => 'Već postoji swimline sa istim imenom u ovom projektu', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Na primjer: http://example.kanboard.net/ (koristi se za pravljenje apsolutnog URL-a)', - 'Actions duplicated successfully.' => 'Akcije uspješno duplicirane.', - 'Unable to duplicate actions.' => 'Nemoguće duplicirati akcije.', - 'Add a new action' => 'Dodaj novu akciju', - 'Import from another project' => 'Uvezi iz drugog projekta', - 'There is no action at the moment.' => 'Trenutno nema akcija.', - 'Import actions from another project' => 'Uvezi akcije iz drugog projekta', - 'There is no available project.' => 'Trenutno nema dostupnih projekata.', - 'Local File' => 'Lokalni fajl', - 'Configuration' => 'Konfiguracija', - 'PHP version:' => 'Verzija PHP-a:', - 'PHP SAPI:' => 'Verzija SAPI-a:', - 'OS version:' => 'Verzija OS-a:', - 'Database version:' => 'Verzija baze podataka:', - 'Browser:' => 'Pretraživač:', - 'Task view' => 'Pregled zadatka', - 'Edit task' => 'Uredi zadatak', - 'Edit description' => 'Uredi opis', - 'New internal link' => 'Nova unutrašnja veza', - 'Display list of keyboard shortcuts' => 'Prikaži listu prečica na tastaturi', - 'Menu' => 'Meni', - 'Set start date' => 'Postavi početni datum', - 'Avatar' => 'Avatar', - 'Upload my avatar image' => 'Dodaj sliku za moj avatar', - 'Remove my image' => 'Ukloni moju sliku', - 'The OAuth2 state parameter is invalid' => 'OAuth2 status parametar nije validan', - 'User not found.' => 'Korisnik nije pronađen.', - 'Search in activity stream' => 'Pretraži aktivnosti', - 'My activities' => 'Moje aktivnosti', - 'Activity until yesterday' => 'Aktivnosti do jučer', - 'Activity until today' => 'Aktivnosti do danas', - 'Search by creator: ' => 'Pretraga po kreatoru: ', - 'Search by creation date: ' => 'Pretraga po datumu kreiranja: ', - 'Search by task status: ' => 'Pretraga po statusu zadatka: ', - 'Search by task title: ' => 'Pretraga po naslovu zadatka: ', - 'Activity stream search' => 'Pretraga aktivnosti', - 'Projects where "%s" is manager' => 'Projekti gdje je "%s" menadžer', - 'Projects where "%s" is member' => 'Projekti gdje je "%s" član', - 'Open tasks assigned to "%s"' => 'Otvoreni zadaci dodijeljeni "%s"', - 'Closed tasks assigned to "%s"' => 'Zatvoreni zadaci dodijeljeni "%s"', - // 'Assign automatically a color based on a priority' => '', - 'Overdue tasks for the project(s) "%s"' => 'Zadaci u kašnjenju za projekat(te) "%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' => '', -); diff --git a/sources/app/Locale/cs_CZ/translations.php b/sources/app/Locale/cs_CZ/translations.php deleted file mode 100644 index 78df7ec..0000000 --- a/sources/app/Locale/cs_CZ/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'žádné', - 'edit' => 'editovat', - 'Edit' => 'Editovat', - 'remove' => 'odstranit', - 'Remove' => 'Odstranit', - 'Yes' => 'Ano', - 'No' => 'Ne', - 'cancel' => 'Zrušit', - 'or' => 'nebo', - 'Yellow' => 'Žlutá', - 'Blue' => 'Modrá', - 'Green' => 'Zelená', - 'Purple' => 'Fialová', - 'Red' => 'Červená', - 'Orange' => 'Oranžová', - 'Grey' => 'Šedá', - // 'Brown' => '', - // 'Deep Orange' => '', - // 'Dark Grey' => '', - // 'Pink' => '', - // 'Teal' => '', - // 'Cyan' => '', - // 'Lime' => '', - // 'Light Green' => '', - // 'Amber' => '', - 'Save' => 'Uložit', - 'Login' => 'Přihlásit se', - 'Official website:' => 'Oficiální stránky:', - 'Unassigned' => 'Nepřiřazeno', - 'View this task' => 'Zobrazit úkol', - 'Remove user' => 'Odebrat uživatele', - 'Do you really want to remove this user: "%s"?' => 'Opravdu chcete odebrat uživatele: "%s"?', - 'All users' => 'Všichni uživatelé', - 'Username' => 'Uživatelské jméno', - 'Password' => 'Heslo', - 'Administrator' => 'Administrátor', - 'Sign in' => 'Registrace', - 'Users' => 'Uživatelé', - 'No user' => 'Žádný uživatel', - 'Forbidden' => 'Zakázat projekt', - 'Access Forbidden' => 'Přístup zakázán', - 'Edit user' => 'Upravit uživatele', - 'Logout' => 'Odhlásit', - 'Bad username or password' => 'Chybné uživatelské jméno nebo heslo', - 'Edit project' => 'Editovat projekt', - 'Name' => 'Jméno', - 'Projects' => 'Projekty', - 'No project' => 'Žádný projekt', - 'Project' => 'Projekt', - 'Status' => 'Status', - 'Tasks' => 'Úkoly', - 'Board' => 'Nástěnka', - 'Actions' => 'Akce', - 'Inactive' => 'Neaktivní', - 'Active' => 'Aktivní', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Opravdu chcete vyjmout projekt: "%s"?', - 'Remove project' => 'Vyjmout projekt', - 'Edit the board for "%s"' => 'Editace nástěnky pro "%s" ', - 'All projects' => 'Všechny projekty', - 'Add a new column' => 'Přidat nový sloupec', - '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!', - 'Settings' => 'Nastavení', - 'Application settings' => 'Nastavení aplikace', - 'Language' => 'Čeština', - 'Webhook token:' => 'Webhook Token:', - 'API token:' => 'API Token:', - 'Database size:' => 'Velikost databáze:', - 'Download the database' => 'Stáhnout databázi', - 'Optimize the database' => 'Optimalizovat databázi', - '(VACUUM command)' => '(Vyčištění)', - '(Gzip compressed Sqlite file)' => '(Gzip )', - 'Close a task' => 'Uzavřít úkol', - 'Edit a task' => 'Editovat úkol', - 'Column' => 'Sloupec', - 'Color' => 'Barva', - 'Assignee' => 'Přiřazeno uživateli', - 'Create another task' => 'Vytvořit další úkol', - 'New task' => 'Nový úkol', - 'Open a task' => 'Otevřít úkol', - 'Do you really want to open this task: "%s"?' => 'Opravdu chcete znovuotevřít tento úkol: "%s"?', - 'Back to the board' => 'Zpět na nástěnku', - 'There is nobody assigned' => 'Není přiřazeno žádnému uživateli', - 'Column on the board:' => 'Sloupec:', - 'Close this task' => 'Uzavřít úkol', - 'Open this task' => 'Otevřít tento úkol', - 'There is no description.' => 'Bez popisu', - 'Add a new task' => 'Přidat nový úkol', - 'The username is required' => 'Uživatelské jméno je vyžadováno', - 'The maximum length is %d characters' => 'Maximální délka je %d znaků', - 'The minimum length is %d characters' => 'Minimální délka je %d znaků', - 'The password is required' => 'Heslo je vyžadováno', - 'This value must be an integer' => 'Je vyžadována číselná hodnota', - 'The username must be unique' => 'Uživatelské jméno musí být jedinečné', - 'The user id is required' => 'Uživatelské ID je vyžadováno', - 'Passwords don\'t match' => 'Heslo se neshoduje', - 'The confirmation is required' => 'Je vyžadováno potvrzení', - 'The project is required' => 'Projekt je vyžadován', - 'The id is required' => 'ID je vyžadováno', - 'The project id is required' => 'ID projektu je vyžadováno', - 'The project name is required' => 'Jméno projektu je vyžadováno', - 'The title is required' => 'Nadpis je vyžadován', - 'Settings saved successfully.' => 'Nastavení bylo úspěšně uloženo', - 'Unable to save your settings.' => 'Vaše nastavení nelze uložit.', - 'Database optimization done.' => 'Optimalizace databáze byla provedena.', - 'Your project have been created successfully.' => 'Projekt byl úspěšně vytvořen.', - 'Unable to create your project.' => 'Projekt nelze vytvořit.', - 'Project updated successfully.' => 'Projekt byl úspěšně aktualizován', - 'Unable to update this project.' => 'Projekt nebylo možné aktualizovat.', - 'Unable to remove this project.' => 'Projekt nebylo možné odstranit.', - 'Project removed successfully.' => 'Projekt byl odstraněn.', - 'Project activated successfully.' => 'Projekt byl povolen.', - 'Unable to activate this project.' => 'Aktivace projektu selhala.', - 'Project disabled successfully.' => 'Projekt byl zakázán.', - 'Unable to disable this project.' => 'Zakázání projektu selhalo.', - 'Unable to open this task.' => 'Nelze otevření tento úkol.', - 'Task opened successfully.' => 'Úkol byl úspěšně otevřen.', - 'Unable to close this task.' => 'Nelze uzavřít tento úkol.', - 'Task closed successfully.' => 'Úkol byl úspěšně uzavřen.', - 'Unable to update your task.' => 'Aktualizace úkolu se nezdařila.', - 'Task updated successfully.' => 'Úkol byl úspěšně aktualizován.', - 'Unable to create your task.' => 'Úkol nelze vytvořit.', - 'Task created successfully.' => 'Úkol byl úspěšně vytvořen.', - 'User created successfully.' => 'Uživatel byl úspěšně vytvořen.', - 'Unable to create your user.' => 'Uživatele nebylo možné vytvořit.', - 'User updated successfully.' => 'Uživatel byl úspěšně aktualizován.', - 'Unable to update your user.' => 'Uživatele nebylo možné aktualizovat.', - 'User removed successfully.' => 'Uživatel byl vymazán.', - 'Unable to remove this user.' => 'Uživatele nebylo možné odebrat.', - 'Board updated successfully.' => 'Nástěnka byla úspěšně aktualizována.', - 'Ready' => 'Připraveno', - 'Backlog' => 'Nevyřízené', - 'Work in progress' => 'V řešení', - 'Done' => 'Dokončeno', - 'Application version:' => 'Verze:', - 'Id' => 'ID', - '%d closed tasks' => '%d dokončených úkolů', - 'No task for this project' => 'Tento projekt nemá žádné úkoly', - 'Public link' => 'Veřejný odkaz', - 'Timezone' => 'Časová zóna', - 'Sorry, I didn\'t find this information in my database!' => 'Omlouváme se, tuto informaci nelze nalézt!', - 'Page not found' => 'Stránka nenalezena', - 'Complexity' => 'Složitost', - 'Task limit' => 'Maximální počet úkolů', - '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í', - 'Invalid date' => 'Neplatné datum', - 'Automatic actions' => 'Automaticky vykonávané akce', - 'Your automatic action have been created successfully.' => 'Vaše akce byla úspěšně vytvořena.', - 'Unable to create your automatic action.' => 'Vaší akci nebylo možné vytvořit.', - 'Remove an action' => 'Odstranit akci', - 'Unable to remove this action.' => 'Tuto akci nelze odstranit.', - 'Action removed successfully.' => 'Akce byla úspěšně odstraněna.', - 'Automatic actions for the project "%s"' => 'Automaticky vykonávané akce pro projekt "%s"', - 'Add an action' => 'Přidat akci', - 'Event name' => 'Název události', - 'Action name' => 'Název akce', - 'Action parameters' => 'Parametry akce', - 'Action' => 'Akce', - 'Event' => 'Událost', - 'When the selected event occurs execute the corresponding action.' => 'Kdykoliv se vybraná událost objeví, vykonat odpovídající akci.', - 'Next step' => 'Další krok', - 'Define action parameters' => 'Definovat parametry akce', - 'Do you really want to remove this action: "%s"?' => 'Skutečně chcete odebrat tuto akci: "%s"?', - 'Remove an automatic action' => 'Odebrat automaticky prováděnou akci', - 'Assign the task to a specific user' => 'Přiřadit tento úkol konkrétnímu uživateli', - 'Assign the task to the person who does the action' => 'Přiřadit úkol osobě, která akci provádí', - 'Duplicate the task to another project' => 'Duplikovat úkol do jiného projektu', - 'Move a task to another column' => 'Přesun úkolu do jiného sloupce', - 'Task modification' => 'Modifikace úkolu', - 'Task creation' => 'Vytváření úkolu', - 'Closing a task' => 'Uzavření úkolu', - 'Assign a color to a specific user' => 'Přiřadit barvu konkrétnímu uživateli', - 'Column title' => 'Název sloupce', - 'Position' => 'Pozice', - 'Duplicate to another project' => 'Vytvořit kopii v jiném projektu', - 'Duplicate' => 'Vytvořit kopii', - 'link' => 'Link', - 'Comment updated successfully.' => 'Komentář byl úspěšně aktualizován.', - 'Unable to update your comment.' => 'Nelze upravit Váš komentář.', - 'Remove a comment' => 'Odebrat komentář', - 'Comment removed successfully.' => 'Komentář byl smazán.', - 'Unable to remove this comment.' => 'Komentář nelze odebrat.', - 'Do you really want to remove this comment?' => 'Skutečně chcete odebrat tento komentář?', - 'Current password for the user "%s"' => 'Aktuální heslo pro uživatele "%s"', - 'The current password is required' => 'Heslo je vyžadováno', - 'Wrong password' => 'Neplatné heslo', - 'Unknown' => 'Neznámý', - 'Last logins' => 'Poslední přihlášení', - 'Login date' => 'Datum přihlášení', - 'Authentication method' => 'Autentifikační metoda', - 'IP address' => 'IP adresa', - 'User agent' => 'User Agent', - 'Persistent connections' => 'Trvalé připojení', - 'No session.' => 'doposud žádná relace.', - 'Expiration date' => 'Datum expirace', - 'Remember Me' => 'Zapamatovat si', - 'Creation date' => 'Datum vytvoření', - 'Everybody' => 'Kdokoliv', - 'Open' => 'Otevřené', - 'Closed' => 'Uzavřené', - '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ář', - 'Email address invalid' => 'Neplatná e-mailová adresa', - // 'Your external account is not linked anymore to your profile.' => '', - // 'Unable to unlink your external account.' => '', - // 'External authentication failed' => '', - // 'Your external account is linked to your profile successfully.' => '', - 'Email' => 'E-Mail', - 'Task removed successfully.' => 'Úkol byl úspěšně odebrán.', - 'Unable to remove this task.' => 'Tento úkol nelze odebrat.', - 'Remove a task' => 'Odebrat úkol', - 'Do you really want to remove this task: "%s"?' => 'Opravdu chcete odebrat úkol: "%s"?', - 'Assign automatically a color based on a category' => 'Automaticky přiřadit barvu v závislosti na kategorii', - 'Assign automatically a category based on a color' => 'Automaticky přiřadit kategorii v závislosti na barvě', - 'Task creation or modification' => 'Vytváření nebo úprava úkolu', - 'Category' => 'Kategorie', - 'Category:' => 'Kategorie:', - 'Categories' => 'Kategorie', - 'Your category have been created successfully.' => 'Kategorie byla úspěšně vytvořena.', - 'Unable to create your category.' => 'Kategorii nelze vytvořit.', - 'Your category have been updated successfully.' => 'Kategorie byla úspěšně aktualizována.', - 'Unable to update your category.' => 'Kategorii nelze aktualizovat.', - 'Remove a category' => 'Odstranit kategorii', - 'Category removed successfully.' => 'Kategorie byla odstraněna.', - 'Unable to remove this category.' => 'Kategorie nemhla být odstraněna.', - 'Category modification for the project "%s"' => 'Aktualizace kategoire pro projekt "%s" ', - 'Category Name' => 'Název kategorie', - 'Add a new category' => 'Přidat kategorii', - 'Do you really want to remove this category: "%s"?' => 'Skutečně chcete odebrat kategorii: "%s"?', - 'All categories' => 'Všechny kategorie', - 'No category' => 'Žádná kategorie', - 'The name is required' => 'Název je vyžadován', - 'Remove a file' => 'Odstranit sougor', - 'Unable to remove this file.' => 'Soubor nelze odebrat.', - 'File removed successfully.' => 'Soubor byl úspěšně odebrán.', - 'Attach a document' => 'Vložit dokument', - 'Do you really want to remove this file: "%s"?' => 'Skutečně chcete odebrat soubor: "%s"?', - 'Attachments' => 'Přílohy', - 'Edit the task' => 'Upravit úkol', - 'Add a comment' => 'Přidat komentář', - 'Edit a comment' => 'Upravit komentář', - 'Summary' => 'Souhrn', - 'Time tracking' => 'Sledování času', - 'Estimate:' => 'Odhad:', - 'Spent:' => 'Stráveno:', - 'Do you really want to remove this sub-task?' => 'Skutečně chcete odebrat dílčí úkol?', - 'Remaining:' => 'Zbývá:', - 'hours' => 'hodin', - 'spent' => 'Stráveno', - 'estimated' => 'odhadnuto', - 'Sub-Tasks' => 'Dílčí úkoly', - 'Add a sub-task' => 'Přidat dílčí úkol', - 'Original estimate' => 'Časový odhad', - 'Create another sub-task' => 'Vytvořit další dílčí úkol', - 'Time spent' => 'Strávený čas', - 'Edit a sub-task' => 'Upravid dílčí úkol', - 'Remove a sub-task' => 'Odstranit dílčí úkol', - 'The time must be a numeric value' => 'Zadejte numerickou hodnotu času', - 'Todo' => 'Seznam úkolů', - 'In progress' => 'Zpracováváme', - 'Sub-task removed successfully.' => 'Dílčí úkol byl smazán.', - 'Unable to remove this sub-task.' => 'Tento dílčí úkol nelze odebrat.', - 'Sub-task updated successfully.' => 'Dílčí úkol byl aktualizován.', - 'Unable to update your sub-task.' => 'Nelze aktualizovat dílčí úkol.', - 'Unable to create your sub-task.' => 'Nelze vytvořit dílčí úkol.', - 'Sub-task added successfully.' => 'Dílčí úkol byl úspěšně přidán.', - 'Maximum size: ' => 'Maximální velikost: ', - 'Unable to upload the file.' => 'Soubor nelze nahrát.', - 'Display another project' => 'Zobrazit jiný projekt', - 'Created by %s' => 'Vytvořeno uživatelem %s', - 'Tasks Export' => 'Export úkolů', - 'Tasks exportation for "%s"' => 'Export úkolů pro "%s"', - 'Start Date' => 'Počáteční datum', - 'End Date' => 'Konečné datum', - 'Execute' => 'Spustit', - 'Task Id' => 'Úkol ID', - 'Creator' => 'Vlastník', - 'Modification date' => 'Datum úpravy', - 'Completion date' => 'Datum dokončení', - 'Clone' => 'Kopie', - 'Project cloned successfully.' => 'Kopie projektu byla úspěšně vytvořena.', - 'Unable to clone this project.' => 'Kopii projektu nelze vytvořit.', - 'Enable email notifications' => 'Povolit upozornění pomocí e-mailů', - 'Task position:' => 'Pořadí úkolu:', - 'The task #%d have been opened.' => 'Úkol #%d byl znovu otevřen.', - 'The task #%d have been closed.' => 'Úkol #%d byl uzavřen.', - 'Sub-task updated' => 'Dílčí úkol byl aktualizován', - 'Title:' => 'Nadpis', - 'Status:' => 'Stav', - 'Assignee:' => 'Přiřazeno:', - 'Time tracking:' => 'Sledování času:', - 'New sub-task' => 'Nový dílčí úkol', - 'New attachment added "%s"' => 'Byla přidána nová příloha "%s".', - 'New comment posted by %s' => 'Nový komentář publikovaný uživatelem %s', - 'New attachment' => 'Nová příloha', - 'New comment' => 'Nový komentář', - 'Comment updated' => 'Komentář byl aktualizován.', - 'New subtask' => 'Nový dílčí úkol', - 'Subtask updated' => 'Dílčí úkol byl aktualizován', - 'Task updated' => 'Úkol byl aktualizován', - 'Task closed' => 'Úkol byl uzavřen', - 'Task opened' => 'Úkol byl otevřen', - 'I want to receive notifications only for those projects:' => 'Přeji si dostávat upozornění pouze pro následující projekty:', - 'view the task on Kanboard' => 'Zobrazit úkol na Kanboard', - 'Public access' => 'Veřejný přístup', - 'Active tasks' => 'Aktivní úkoly', - 'Disable public access' => 'Zakázat veřejný přístup', - 'Enable public access' => 'Povolit veřejný přístup', - 'Public access disabled' => 'Veřejný přístup zakázán', - 'Do you really want to disable this project: "%s"?' => 'Opravdu chcete zakázat projekt: "%s"', - 'Do you really want to enable this project: "%s"?' => 'Opravdu chcete znovu povolit projekt: "%s"', - 'Project activation' => 'Aktivace projektu', - 'Move the task to another project' => 'Přesunutí úkolu do jiného projektu', - 'Move to another project' => 'Přesunout do jiného projektu', - 'Do you really want to duplicate this task?' => 'Opravdu chcete vytořit kopii tohoto úkolu?', - 'Duplicate a task' => 'Vytvořit kopii úkolu', - 'External accounts' => 'Externí účty', - 'Account type' => 'typ účtu', - 'Local' => 'Lokální', - 'Remote' => 'Vzdálený', - 'Enabled' => 'Povoleno', - 'Disabled' => 'Zakázáno', - 'Username:' => 'Uživatelské jméno:', - 'Name:' => 'Jméno:', - 'Email:' => 'e-mail', - 'Notifications:' => 'Upozornění:', - 'Notifications' => 'Upozornění', - 'Account type:' => 'Typ účtu:', - 'Edit profile' => 'Upravit profil', - 'Change password' => 'Změnit heslo', - 'Password modification' => 'Změna hesla', - 'External authentications' => 'Vzdálená autorizace', - 'Never connected.' => 'Zatím nikdy nespojen.', - 'No external authentication enabled.' => 'Není povolena žádná vzdálená autorizace.', - 'Password modified successfully.' => 'Heslo bylo úspěšně změněno.', - 'Unable to change the password.' => 'Nelze změnit heslo.', - 'Change category' => 'Změna kategorie', - '%s updated the task %s' => '%s aktualizoval úkol %s ', - '%s opened the task %s' => '%s znovu otevřel úkol %s ', - '%s moved the task %s to the position #%d in the column "%s"' => '%s přesunul úkol %s na pozici #%d ve sloupci "%s" ', - '%s moved the task %s to the column "%s"' => '%s přesunul úkol %s do sloupce "%s" ', - '%s created the task %s' => '%s vytvořil úkol %s ', - '%s closed the task %s' => '%s uzavřel %s ', - '%s created a subtask for the task %s' => '%s vytvořil dílčí úkol pro úkol %s ', - '%s updated a subtask for the task %s' => '%s aktualizoval dílčí úkol pro úkol %s ', - 'Assigned to %s with an estimate of %s/%sh' => 'Přiřazeno uživateli %s s časovým odhadem práce %s/%s dní', - 'Not assigned, estimate of %sh' => 'Nepřiřazeno, časový odhad práce je %s dní', - '%s updated a comment on the task %s' => '%s aktualizoval komentář k úkolu %s ', - '%s commented the task %s' => '%s přidal komentář k úkolu %s ', - '%s\'s activity' => 'Aktivity projektu %s', - 'RSS feed' => 'RSS kanál', - '%s updated a comment on the task #%d' => '%s aktualizoval komnetář k úkolu #%d ', - '%s commented on the task #%d' => '%s přidal komentář k úkolu #%d ', - '%s updated a subtask for the task #%d' => '%s aktualizoval dílčí úkol úkolu #%d ', - '%s created a subtask for the task #%d' => '%s vytvořil dílčí úkol úkolu #%d ', - '%s updated the task #%d' => '%s aktualizoval úkol #%d ', - '%s created the task #%d' => '%s vytvořil úkol #%d ', - '%s closed the task #%d' => '%s uzavřel úkol #%d ', - '%s open the task #%d' => '%s znovu otevřel úkol #%d ', - '%s moved the task #%d to the column "%s"' => '%s přesunul úkol #%d do sloupce "%s" ', - '%s moved the task #%d to the position %d in the column "%s"' => '%s přesunul úkol #%d na pozici %d ve sloupci "%s" ', - 'Activity' => 'Aktivity', - 'Default values are "%s"' => 'Standardní hodnoty jsou: "%s"', - 'Default columns for new projects (Comma-separated)' => 'Výchozí sloupce pro nové projekty (odděleny čárkou)', - 'Task assignee change' => 'Změna přiřazení uživatelů', - '%s change the assignee of the task #%d to %s' => '%s změnil přidělení úkolu #%d na uživatele %s', - '%s changed the assignee of the task %s to %s' => '%s změnil přidělení úkolu %s na uživatele %s', - 'New password for the user "%s"' => 'Nové heslo pro uživatele "%s"', - 'Choose an event' => 'Vybrat událost', - 'Create a task from an external provider' => 'Vytvořit úkol externím poskytovatelem', - 'Change the assignee based on an external username' => 'Změna přiřazení uživatele závislá na externím uživateli', - 'Change the category based on an external label' => 'Změna kategorie závislá na externím popisku', - 'Reference' => 'Reference', - // 'Label' => '', - 'Database' => 'Datenbank', - 'About' => 'O projektu', - 'Database driver:' => 'Databáze', - 'Board settings' => 'Nastavení nástěnky', - 'Webhook settings' => 'Webhook nastavení', - 'Reset token' => 'Token reset', - 'API endpoint:' => 'API endpoint', - 'Refresh interval for private board' => 'Interval automatického obnovování pro soukromé nástěnky', - 'Refresh interval for public board' => 'Interval automatického obnovování pro veřejné nástěnky', - 'Task highlight period' => 'Task highlight period', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Interval (v sekundách), ve kterém je považovány úpravy úkolů za aktuální (0 pro zakázání, 2 dny ve výchozím nastavení)', - 'Frequency in second (60 seconds by default)' => 'Frekvence v sekundách (60 sekund ve výchozím nastavení)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvence v sekundách (0 pro zákaz této vlastnosti, 10 sekund ve výchozím nastavení)', - 'Application URL' => 'URL aplikace', - 'Token regenerated.' => 'Token byl opětovně generován.', - 'Date format' => 'Formát datumu', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formát je vždy akceptován, například: "%s" a "%s"', - 'New private project' => 'Nový soukromý projekt', - 'This project is private' => 'Tento projekt je soukromuý', - 'Add' => 'Přidat', - 'Start date' => 'Počáteční datum', - 'Time estimated' => 'Odhadovaný čas', - 'There is nothing assigned to you.' => 'Nemáte přiřazenou žádnou položku.', - 'My tasks' => 'Moje úkoly', - 'Activity stream' => 'Přehled aktivit', - 'Dashboard' => 'Nástěnka', - 'Confirmation' => 'Potvrzení', - 'Allow everybody to access to this project' => 'Umožní přístup komukoliv k tomuto projektu', - 'Everybody have access to this project.' => 'Přístup k tomuto projektu má kdokoliv.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Vytvořit komentář pomocí externího poskytovatele', - 'Project management' => 'Správa projektů', - 'My projects' => 'Moje projekty', - 'Columns' => 'Sloupce', - 'Task' => 'Úkol', - 'Your are not member of any project.' => 'V žádném projektu nejste členem.', - 'Percentage' => 'Procenta', - 'Number of tasks' => 'Počet úkolů', - 'Task distribution' => 'Rozdělení úkolů', - 'Reportings' => 'Reporty', - 'Task repartition for "%s"' => 'Rozdělení úkolů pro "%s"', - 'Analytics' => 'Analýza', - 'Subtask' => 'Dílčí úkoly', - 'My subtasks' => 'Moje dílčí úkoly', - 'User repartition' => 'Rozdělení podle uživatelů', - 'User repartition for "%s"' => 'Rozdělení podle uživatelů pro "%s"', - 'Clone this project' => 'Duplokovat projekt', - 'Column removed successfully.' => 'Sloupec byl odstraněn.', - 'Not enough data to show the graph.' => 'Pro zobrazení grafu není dostatek dat.', - 'Previous' => 'Předchozí', - 'The id must be an integer' => 'ID musí být celé číslo', - 'The project id must be an integer' => 'ID projektu musí být celé číslo', - 'The status must be an integer' => 'Status musí být celé číslo', - 'The subtask id is required' => 'Je požadováno id dílčího úkolu', - 'The subtask id must be an integer' => 'ID dílčího úkolu musí být číslo', - 'The task id is required' => 'ID úkolu je povinné', - 'The task id must be an integer' => 'ID úkolu musí být číslo', - 'The user id must be an integer' => 'ID uživatele musí být číslo', - 'This value is required' => 'Hodnota je povinná', - 'This value must be numeric' => 'Hodnota musí být číselná', - 'Unable to create this task.' => 'Nelze vytvořit tento úkol', - 'Cumulative flow diagram' => 'Kumulativní diagram', - 'Cumulative flow diagram for "%s"' => 'Kumulativní diagram pro "%s"', - 'Daily project summary' => 'Denní přehledy', - 'Daily project summary export' => 'Export denních přehledů', - 'Daily project summary export for "%s"' => 'Export denních přehledů pro "%s"', - 'Exports' => 'Exporty', - 'This export contains the number of tasks per column grouped per day.' => 'Tento export obsahuje počet úkolů pro jednotlivé sloupce seskupených podle dní.', - 'Active swimlanes' => 'Aktivní dráhy', - 'Add a new swimlane' => 'Přidat novou dráhu', - 'Change default swimlane' => 'Změnit výchozí dráhu', - 'Default swimlane' => 'Výchozí dráha', - 'Do you really want to remove this swimlane: "%s"?' => 'Opravdu si přejete odstranit tuto dráhu: "%s"?', - 'Inactive swimlanes' => 'Neaktivní dráha', - 'Remove a swimlane' => 'Odstranit dráhu', - 'Show default swimlane' => 'Zobrazit výchozí dráhu', - 'Swimlane modification for the project "%s"' => 'Změny dráhy pro projekt "%s"', - 'Swimlane removed successfully.' => 'Dráha byla odstraněna.', - 'Swimlanes' => 'Dráhy', - 'Swimlane updated successfully.' => 'Dráha byla upravena.', - 'The default swimlane have been updated successfully.' => 'Výchozí dráha byla upravena', - 'Unable to remove this swimlane.' => 'Tuto dráhu nelze odstranit.', - 'Unable to update this swimlane.' => 'Tuto dráhu nelze upravit.', - 'Your swimlane have been created successfully.' => 'Dráha byla vytvořena.', - 'Example: "Bug, Feature Request, Improvement"' => 'Například: "Chyba", "Nápad", "Požadavek"...', - 'Default categories for new projects (Comma-separated)' => 'Výchozí kategorie pro nové projekty (oddělené čárkou)', - 'Integrations' => 'Integrace', - 'Integration with third-party services' => 'Integrace se službami třetích stran', - 'Subtask Id' => 'Dílčí úkol Id', - 'Subtasks' => 'Dílčí úkoly', - 'Subtasks Export' => 'Export dílčích úkolů', - 'Subtasks exportation for "%s"' => 'Export dílčích úkolů pro "%s"', - 'Task Title' => 'Název úkolu', - 'Untitled' => 'bez názvu', - 'Application default' => 'Standardní hodnoty', - 'Language:' => 'Jazyk:', - 'Timezone:' => 'Časová zóna:', - 'All columns' => 'Všechny sloupce', - 'Calendar' => 'Kalendář', - 'Next' => 'Další', - // '#%d' => '', - 'All swimlanes' => 'Alle Swimlanes', - 'All colors' => 'Všechny barvy', - 'Moved to column %s' => 'Přesunuto do sloupce %s ', - 'User dashboard' => 'Nástěnka uživatele', - 'Allow only one subtask in progress at the same time for a user' => 'Umožnit uživateli práci pouze na jednom dílčím úkolu ve stejném čase', - 'Edit column "%s"' => 'Upravit sloupec "%s" ', - 'Select the new status of the subtask: "%s"' => 'Vyberte nový stav pro podúkol: "%s"', - 'Subtask timesheet' => 'Časový rozvrh dílčích úkolů', - 'There is nothing to show.' => 'Žádná položka k zobrazení', - 'Time Tracking' => 'Sledování času', - 'You already have one subtask in progress' => 'Jeden dílčí úkol již aktuálně řešíte', - 'Which parts of the project do you want to duplicate?' => 'Které části projektu chcete duplikovat?', - // 'Disallow login form' => '', - 'Start' => 'Začátek', - 'End' => 'Konec', - 'Task age in days' => 'Doba trvání úkolu ve dnech', - 'Days in this column' => 'Dní v tomto sloupci', - '%dd' => '%d d', - 'Add a new link' => 'Přidat nový odkaz', - 'Do you really want to remove this link: "%s"?' => 'Opravdu chcete odstranit odkaz "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Opravdu chcete odstranit odkaz na úkol #%d ?', - 'Field required' => 'Povinné pole', - 'Link added successfully.' => 'Propojení bylo úspěšně přidáno.', - 'Link updated successfully.' => 'Propojení bylo úspěšně aktualizováno.', - 'Link removed successfully.' => 'Propojení bylo úspěšně odebráno.', - '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ý', - 'Unable to create your link.' => 'Nelze vytvořit toto propojení.', - 'Unable to update your link.' => 'Nelze aktualizovat toto propojení.', - 'Unable to remove this link.' => 'Nelze odstranit toto propojení', - 'relates to' => 'souvisí s', - 'blocks' => 'blokuje', - 'is blocked by' => 'je blokován', - 'duplicates' => 'duplikuje', - 'is duplicated by' => 'je duplikován', - 'is a child of' => 'je podřízený', - 'is a parent of' => 'je nadřízený', - 'targets milestone' => 'patří k milníku', - 'is a milestone of' => 'je milníkem', - 'fixes' => 'nahrazuje', - 'is fixed by' => 'je nahrazen', - 'This task' => 'Tento úkol', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Rozpbalit úkoly', - 'Collapse tasks' => 'Sbalit úkoly', - 'Expand/collapse tasks' => 'Rozbalit / sbalit úkoly', - 'Close dialog box' => 'Zavřít dialogové okno', - 'Submit a form' => 'Odeslat formulář', - 'Board view' => 'Zobrazení nástěnky', - 'Keyboard shortcuts' => 'Klávesnicové zkratky', - 'Open board switcher' => 'Otevřít přepínač nástěnek', - 'Application' => 'Aplikace', - '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' => '', - // 'CAD - Canadian Dollar' => '', - // 'CHF - Swiss Francs' => '', - 'Custom Stylesheet' => 'Vlastní šablony stylů', - 'download' => 'Stáhnout', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Britská Libra', - 'INR - Indian Rupee' => 'INR - Indische Rupien', - 'JPY - Japanese Yen' => 'JPY - Japanischer Yen', - 'NZD - New Zealand Dollar' => 'NZD - Neuseeland-Dollar', - 'RSD - Serbian dinar' => 'RSD - Serbische Dinar', - '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.', - 'Move the task to another column when assignee is cleared' => 'Přesunout úkol do jiného sloupce, když je pověření uživatele vymazáno.', - 'Source column' => 'Zdrojový sloupec', - 'Transitions' => 'Změny etap', - 'Executer' => 'Vykonavatel', - 'Time spent in the column' => 'Trvání jednotlivých etap', - 'Task transitions' => 'Přesuny úkolů', - 'Task transitions export' => 'Export přesunů mezi sloupci', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Tento seznam obsahuje všechny pohyby úkolů s daty, uživateli a časy strávenými na úkolu.', - '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', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s odstranil přiřazení úkolu %s ', - 'Enable Gravatar images' => 'Aktiviere Gravatar Bilder', - 'Information' => 'Informace', - 'Check two factor authentication code' => 'Zkontrolujte dvouúrovňový autentifikační klíč', - 'The two factor authentication code is not valid.' => 'Dvouúrovňový autentifikační klíč není platný.', - 'The two factor authentication code is valid.' => 'Dvouúrovňový autentifikační klíč je platný.', - 'Code' => 'Klíč', - 'Two factor authentication' => 'Dvouúrovňová autorizace', - 'This QR code contains the key URI: ' => 'Tento QR kód obsahuje adresu s klíčem', - 'Check my code' => 'Kontrola mého kódu', - 'Secret key: ' => 'Tajný klíč', - 'Test your device' => 'Test Vašeho zařízení', - 'Assign a color when the task is moved to a specific column' => 'Přiřadit barvu, když je úkol přesunut do konkrétního sloupce', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Burndown-Chart pro "%s"', - 'Burndown chart' => 'Burndown-Chart', - 'This chart show the task complexity over the time (Work Remaining).' => 'Graf zobrazuje složitost úkolů v čase (Zbývající práce).', - 'Screenshot taken %s' => 'Screenshot aufgenommen %s ', - 'Add a screenshot' => 'Přidat snímek obrazovky', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Pořiďte snímek obrazovky a v tomto poli stiskněte Ctrl+V nebo ⌘+V ', - 'Screenshot uploaded successfully.' => 'Snímek obrazovky byl úspěšně nahrán.', - 'SEK - Swedish Krona' => 'SEK - Schwedische Kronen', - 'Identifier' => 'Identifikátor', - 'Disable two factor authentication' => 'Zrušit dvouúrovňovou autorizaci', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Opravdu chcete vypnout dvouúrovňovou autentifikaci pro uživatele: "%s"?', - // 'Edit link' => '', - // 'Start to type task title...' => '', - // 'A task cannot be linked to itself' => '', - // 'The exact same link already exists' => '', - // 'Recurrent task is scheduled to be generated' => '', - // 'Score' => '', - // 'The identifier must be unique' => '', - // 'This linked task id doesn\'t exists' => '', - // 'This value must be alphanumeric' => '', - 'Edit recurrence' => 'Upravit opakování', - // 'Generate recurrent task' => '', - // 'Trigger to generate recurrent task' => '', - // 'Factor to calculate new due date' => '', - // 'Timeframe to calculate new due date' => '', - // 'Base date to calculate new due date' => '', - // 'Action date' => '', - // 'Base date to calculate new due date: ' => '', - // 'This task has created this child task: ' => '', - // 'Day(s)' => '', - // 'Existing due date' => '', - // 'Factor to calculate new due date: ' => '', - // 'Month(s)' => '', - // 'Recurrence' => '', - // 'This task has been created by: ' => '', - // 'Recurrent task has been generated:' => '', - // 'Timeframe to calculate new due date: ' => '', - // 'Trigger to generate recurrent task: ' => '', - // 'When task is closed' => '', - // 'When task is moved from first column' => '', - // 'When task is moved to last column' => '', - // 'Year(s)' => '', - 'Calendar settings' => 'Nastavení kalendáře', - // 'Project calendar view' => '', - 'Project settings' => 'Nastavení projektu', - 'Show subtasks based on the time tracking' => 'Zobrazit dílčí úkoly závislé na sledování času', - 'Show tasks based on the creation date' => 'Zobrazit úkoly podle datumu vytvoření', - 'Show tasks based on the start date' => 'Zobrazit úkoly podle datumu zahájení', - 'Subtasks time tracking' => 'Dílčí úkoly s časovačem', - 'User calendar view' => 'Zobrazení kalendáře uživatele', - 'Automatically update the start date' => 'Automaticky aktualizovat počáteční datum', - // 'iCal feed' => '', - 'Preferences' => 'Předvolby', - 'Security' => 'Zabezpečení ', - 'Two factor authentication disabled' => 'Dvouúrovňová autorizace zakázána.', - 'Two factor authentication enabled' => 'Dvouúrovňová autorizace povolena.', - 'Unable to update this user.' => 'Uživatele nelze aktualizovat.', - 'There is no user management for private projects.' => 'Pro soukromé projekty není aplikována správa uživatelů.', - 'User that will receive the email' => 'Uživatel, který dostane E-mail', - 'Email subject' => 'E-mail Předmět', - 'Date' => 'Datum', - 'Add a comment log when moving the task between columns' => 'Přidat komentář když je úkol přesouván mezi sloupci', - 'Move the task to another column when the category is changed' => 'Přesun úkolu do jiného sloupce když je změněna kategorie', - 'Send a task by email to someone' => 'Poslat někomu úkol poštou', - 'Reopen a task' => 'Znovu otevřít úkol', - 'Column change' => 'Změna sloupce', - 'Position change' => 'Změna pozice', - 'Swimlane change' => 'Změna dráhy', - 'Assignee change' => 'Změna přidělení', - '[%s] Overdue tasks' => '[%s] přetažených úkolů', - 'Notification' => 'Upozornění', - '%s moved the task #%d to the first swimlane' => '%s přesunul úkol #%d do první dráhy', - '%s moved the task #%d to the swimlane "%s"' => '%s přesunul úkol #%d do dráhy "%s"', - // 'Swimlane' => '', - // 'Gravatar' => '', - '%s moved the task %s to the first swimlane' => '%s přesunul úkol %s do první dráhy', - '%s moved the task %s to the swimlane "%s"' => '%s přesunul úkol %s do dráhy "%s"', - 'This report contains all subtasks information for the given date range.' => 'Report obsahuje všechny informace o dílčích úkolech pro daný časový úsek', - 'This report contains all tasks information for the given date range.' => 'Report obsahuje informace o všech úkolech pro daný časový úsek.', - 'Project activities for %s' => 'Aktivity projektu %s', - 'view the board on Kanboard' => 'Zobrazit nástěnku', - 'The task have been moved to the first swimlane' => 'Úkol byl přesunut do první dráhy', - 'The task have been moved to another swimlane:' => 'Úkol byl přesunut do další dráhy', - 'New title: %s' => 'Nový název: %s', - 'The task is not assigned anymore' => 'Úkol již není přidělen', - 'New assignee: %s' => 'přidělení: %s', - 'There is no category now' => 'Nyní neexistuje žádná kategorie', - 'New category: %s' => 'Nová kategorie: %s', - 'New color: %s' => 'Nová barva: %s', - 'New complexity: %d' => 'Nová složitost: %d', - 'The due date have been removed' => 'Datum dokončení byl odstraněn', - 'There is no description anymore' => 'Ještě neexistuje žádný popis', - 'Recurrence settings have been modified' => 'Nastavení opakování bylo změněno', - 'Time spent changed: %sh' => 'Strávený čas se změnil: %sh', - 'Time estimated changed: %sh' => 'Odhadovaný čas se změnil: %sh', - 'The field "%s" have been updated' => 'Sloupec "%s" byl upraven', - 'The description has been modified:' => 'Popis byl upraven:', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Opravdu si přejete úkol "%s" uzavřít? (včetně podúkolů)', - 'I want to receive notifications for:' => 'Chci dostávat upozornění na:', - 'All tasks' => 'Všechny úkoly', - 'Only for tasks assigned to me' => 'pouze pro moje úkoly', - 'Only for tasks created by me' => 'pouze pro mnou vytvořené úkoly', - 'Only for tasks created by me and assigned to me' => 'pouze pro mnou vytvořené a mě přiřazené úkoly', - // '%%Y-%%m-%%d' => '', - 'Total for all columns' => 'S', - 'You need at least 2 days of data to show the chart.' => 'Potřebujete nejméně data ze dvou dnů pro zobrazení grafu', - '<15m' => '<15min.', - '<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ů', - 'Reset filters' => 'Resetovat filtry', - 'My tasks due tomorrow' => 'Moje zítřejší úkoly', - 'Tasks due today' => 'Dnešní úkoly', - 'Tasks due tomorrow' => 'Zítřejší úkoly', - 'Tasks due yesterday' => 'Včerejší úkoly', - 'Closed tasks' => 'Uzavřené úkoly', - 'Open tasks' => 'Otevřené úkoly', - 'Not assigned' => 'Nepřiřazené', - 'View advanced search syntax' => 'Zobrazit syntaxi rozšířeného vyhledávání', - 'Overview' => 'Přehled', - 'Board/Calendar/List view' => 'Nástěnka/Kalendář/Zobrazení seznamu', - 'Switch to the board view' => 'Přepnout na nástěnku', - 'Switch to the calendar view' => 'Přepnout na kalendář', - 'Switch to the list view' => 'Přepnout na seznam zobrazení', - 'Go to the search/filter box' => 'Zobrazit vyhledávání/filtrování', - 'There is no activity yet.' => 'Doposud nejsou žádné aktivity.', - 'No tasks found.' => 'Nenalezen žádný úkol.', - 'Keyboard shortcut: "%s"' => 'Klávesová zkratka: "%s"', - 'List' => 'Seznam', - 'Filter' => 'Filtr', - 'Advanced search' => 'Rozšířené hledání', - 'Example of query: ' => 'Příklad dotazu: ', - 'Search by project: ' => 'Hledat podle projektu: ', - 'Search by column: ' => 'Hledat podle sloupce: ', - 'Search by assignee: ' => 'Hledat podle přiřazené osoby: ', - 'Search by color: ' => 'Hledat podle barvy: ', - 'Search by category: ' => 'Hledat podle kategorie: ', - 'Search by description: ' => 'Hledat podle popisu: ', - 'Search by due date: ' => 'Hledat podle termínu: ', - 'Lead and Cycle time for "%s"' => 'Dodací lhůta a doba cyklu pro "%s"', - 'Average time spent into each column for "%s"' => 'Průměrná doba strávená v každé fázi pro "%s"', - 'Average time spent into each column' => 'Průměrná doba strávená v každé fázi', - 'Average time spent' => 'Průměrná strávená doba', - // 'This chart show the average time spent into each column for the last %d tasks.' => '', - 'Average Lead and Cycle time' => 'Průměrná dodací lhůta a doba cyklu', - 'Average lead time: ' => 'Průměrná dodací lhůta: ', - 'Average cycle time: ' => 'Průměrná doba cyklu: ', - 'Cycle Time' => 'Doba cyklu', - 'Lead Time' => 'Dodací lhůta', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Graf ukazuje průměrnou dodací lhůtu a dobu cyklu pro posledních %d úkolů v průběhu času', - 'Average time into each column' => 'Průměrná doba v každé fázi', - 'Lead and cycle time' => 'Dodací lhůta a doba cyklu', - 'Lead time: ' => 'Dodací lhůta: ', - 'Cycle time: ' => 'Doba cyklu: ', - 'Time spent into each column' => 'Čas strávený v každé fázi', - 'The lead time is the duration between the task creation and the completion.' => 'Lead time (dodací lhůta) je čas od založení úkolu do jeho dokončení.', - 'The cycle time is the duration between the start date and the completion.' => 'Doba cyklu je doba trvání mezi zahájením a dokončením úkolu.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Jestliže není úkol uzavřen, místo termínu dokončení je použit aktuální čas.', - 'Set automatically the start date' => 'Nastavit automaticky počáteční datum', - 'Edit Authentication' => 'Upravit ověřování', - '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.', - // 'Trigger automatically subtask time tracking' => '', - 'Include closed tasks in the cumulative flow diagram' => 'začlenit dokončené úkoly do kumulativního flow diagramu', - 'Current swimlane: %s' => 'Aktuální swimlane: %s', - 'Current column: %s' => 'Aktuální fáze: %s', - 'Current category: %s' => 'Aktuální kategorie: %s', - 'no category' => 'kategorie nenastavena', - 'Current assignee: %s' => 'Aktuálně přiřazený uživatel: %s', - 'not assigned' => 'nepřiřazeno', - 'Author:' => 'Autor:', - 'contributors' => 'přispěvatelé', - 'License:' => 'Licence:', - 'License' => 'Licence', - 'Enter the text below' => 'Zadejte text níže', - 'Gantt chart for %s' => 'Gantt graf pro %s', - 'Sort by position' => 'Třídit podle pozice', - 'Sort by date' => 'Třídit podle datumu', - 'Add task' => 'Přidat úkol', - 'Start date:' => 'Termín zahájení:', - 'Due date:' => 'Termín dokončení:', - 'There is no start date or due date for this task.' => 'Úkol nemá nastaven termín zahájení a dokončení.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Posunutím nebo prodloužením úkolu se změní počáteční a konečné datum úkolu. ', - 'There is no task in your project.' => 'Projekt neobsahuje žádné úkoly.', - 'Gantt chart' => 'Gantt graf', - // 'People who are project managers' => '', - // 'People who are project members' => '', - // 'NOK - Norwegian Krone' => '', - // 'Show this column' => '', - // 'Hide this column' => '', - // 'open file' => '', - // 'End date' => '', - // 'Users overview' => '', - // 'Members' => '', - // 'Shared project' => '', - // 'Project managers' => '', - // 'Gantt chart for all projects' => '', - // 'Projects list' => '', - // 'Gantt chart for this project' => '', - // 'Project board' => '', - // 'End date:' => '', - // 'There is no start date or end date for this project.' => '', - // 'Projects Gantt chart' => '', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - // 'Milestone' => '', - // 'Documentation: %s' => '', - // 'Switch to the Gantt chart view' => '', - // 'Reset the search/filter box' => '', - // 'Documentation' => '', - // 'Table of contents' => '', - // 'Gantt' => '', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - // 'Link type' => '', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - // 'Project members' => '', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/da_DK/translations.php b/sources/app/Locale/da_DK/translations.php deleted file mode 100644 index bf595a0..0000000 --- a/sources/app/Locale/da_DK/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => 'Ingen', - 'edit' => 'rediger', - 'Edit' => 'Rediger', - 'remove' => 'fjern', - 'Remove' => 'Fjern', - 'Yes' => 'Ja', - 'No' => 'Nej', - 'cancel' => 'annuller', - 'or' => 'eller', - 'Yellow' => 'Gul', - 'Blue' => 'Blå', - 'Green' => 'Grøn', - 'Purple' => 'Lilla', - 'Red' => 'Rød', - 'Orange' => 'Orange', - 'Grey' => 'Grå', - // 'Brown' => '', - // 'Deep Orange' => '', - // 'Dark Grey' => '', - // 'Pink' => '', - // 'Teal' => '', - // 'Cyan' => '', - // 'Lime' => '', - // 'Light Green' => '', - // 'Amber' => '', - 'Save' => 'Gem', - 'Login' => 'Login', - 'Official website:' => 'Officielt website:', - 'Unassigned' => 'Ingen ansvarlig', - 'View this task' => 'Se denne opgave', - 'Remove user' => 'Fjern bruger', - 'Do you really want to remove this user: "%s"?' => 'Ønsker du virkelig at fjerne denne bruger: "%s"?', - 'All users' => 'Alle brugere', - 'Username' => 'Brugernavn', - 'Password' => 'Password', - 'Administrator' => 'Administrator', - 'Sign in' => 'Log ind', - 'Users' => 'Brugere', - 'No user' => 'Ingen bruger', - 'Forbidden' => 'Forbudt', - 'Access Forbidden' => 'Adgang nægtet', - 'Edit user' => 'Rediger bruger', - 'Logout' => 'Log ud', - 'Bad username or password' => 'Forkert brugernavn eller adgangskode', - 'Edit project' => 'Rediger projekt', - 'Name' => 'Navn', - 'Projects' => 'Projekter', - 'No project' => 'Intet projekt', - 'Project' => 'Projekt', - 'Status' => 'Status', - 'Tasks' => 'Opgave', - 'Board' => 'Board', - 'Actions' => 'Handlinger', - 'Inactive' => 'Inaktiv', - 'Active' => 'Aktiv', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Vil du virkelig fjerne dette projekt: "%s"?', - 'Remove project' => 'Fjern projekt', - 'Edit the board for "%s"' => 'Rediger boardet for "%s"', - 'All projects' => 'Alle Projekter', - 'Add a new column' => 'Tilføj en ny kolonne', - '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', - 'Settings' => 'Indstillinger', - 'Application settings' => 'Applikationsindstillinger', - 'Language' => 'Sprog', - 'Webhook token:' => 'Webhook token:', - 'API token:' => 'API Token:', - 'Database size:' => 'Databasestørrelse:', - 'Download the database' => 'Download databasen', - 'Optimize the database' => 'Optimer databasen', - '(VACUUM command)' => '(VACUUM kommando)', - '(Gzip compressed Sqlite file)' => '(Gzip-komprimeret Sqlite fil)', - 'Close a task' => 'Luk en opgave', - 'Edit a task' => 'Rediger en opgave', - 'Column' => 'Kolonne', - 'Color' => 'Farve', - 'Assignee' => 'Ansvarlig', - 'Create another task' => 'Opret en anden opgave', - 'New task' => 'Ny opgave', - 'Open a task' => 'Åben en opgave', - 'Do you really want to open this task: "%s"?' => 'Vil du virkelig åbne denne opgave: "%s"?', - 'Back to the board' => 'Tilbage til boardet', - 'There is nobody assigned' => 'Der er ingen tilføjet', - 'Column on the board:' => 'Kolonne:', - 'Close this task' => 'Luk denne opgave', - 'Open this task' => 'Åben denne opgave', - 'There is no description.' => 'Der er ingen beskrivning.', - 'Add a new task' => 'Tilføj en ny opgave', - 'The username is required' => 'Brugernavn er krævet', - 'The maximum length is %d characters' => 'Den maksimale længde er %d karakterer', - 'The minimum length is %d characters' => 'Den minimale længde er %d karakterer', - 'The password is required' => 'Adgangskode er krævet', - 'This value must be an integer' => 'Denne værdig skal være et tal', - 'The username must be unique' => 'Brugernavn skal være unikt', - 'The user id is required' => 'Bruger id er krævet', - 'Passwords don\'t match' => 'Adgangskoderne stemmer ikke overens', - 'The confirmation is required' => 'Verifikation er nødvendigt', - 'The project is required' => 'Projektet er krævet', - 'The id is required' => 'Id\'et er krævet', - 'The project id is required' => 'Projektets id er krævet', - 'The project name is required' => 'Projektets navn er krævet', - 'The title is required' => 'Titel er krævet', - 'Settings saved successfully.' => 'Indstillinger gemt.', - 'Unable to save your settings.' => 'Indstillinger kunne ikke gemmes.', - 'Database optimization done.' => 'Databaseoptimeringen er fuldført.', - 'Your project have been created successfully.' => 'Dit projekt er oprettet.', - 'Unable to create your project.' => 'Projektet kunne ikke oprettes', - 'Project updated successfully.' => 'Projektet er opdateret.', - 'Unable to update this project.' => 'Projektet kunne ikke opdateres.', - 'Unable to remove this project.' => 'Projektet kunne ikke slettes.', - 'Project removed successfully.' => 'Projektet er slettet.', - 'Project activated successfully.' => 'Projektet er aktiveret.', - 'Unable to activate this project.' => 'Projektet kunne ikke aktiveres.', - 'Project disabled successfully.' => 'Projektet er deaktiveret.', - 'Unable to disable this project.' => 'Projektet kunne ikke deaktiveres.', - 'Unable to open this task.' => 'Opgaven kunne ikke ånnes.', - 'Task opened successfully.' => 'Opgaven er åbnet.', - 'Unable to close this task.' => 'Opgaven kunne ikke åbnes.', - 'Task closed successfully.' => 'Opgaven er lukket.', - 'Unable to update your task.' => 'Opgaven kunne ikke opdateres.', - 'Task updated successfully.' => 'Opgaven er opdateret.', - 'Unable to create your task.' => 'Opgave kunne ikke oprettes.', - 'Task created successfully.' => 'Opgaven er oprettet.', - 'User created successfully.' => 'Brugeren er oprettet.', - 'Unable to create your user.' => 'Brugeren kunne ikke oprettes.', - 'User updated successfully.' => 'Brugeren er opdateret', - 'Unable to update your user.' => 'Din bruger kunne ikke opdateres.', - 'User removed successfully.' => 'Brugeren er fjernet.', - 'Unable to remove this user.' => 'Brugeren kunne ikke fjernes.', - 'Board updated successfully.' => 'Boardet er opdateret.', - 'Ready' => 'Klar', - 'Backlog' => 'Backlog', - 'Work in progress' => 'Igangværende', - 'Done' => 'Færdig', - 'Application version:' => 'Version:', - 'Id' => 'ID', - '%d closed tasks' => '%d lukket opgavet', - 'No task for this project' => 'Ingen opgaver i dette projekt', - 'Public link' => 'Offentligt link', - 'Timezone' => 'Tidszone', - 'Sorry, I didn\'t find this information in my database!' => 'Denne information kunne ikke findes i databasen!', - 'Page not found' => 'Siden er ikke fundet', - 'Complexity' => 'Kompleksitet', - 'Task limit' => 'Opgave begrænsning', - // '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', - 'Invalid date' => 'Ugyldig dato', - 'Automatic actions' => 'Automatiske handlinger', - 'Your automatic action have been created successfully.' => 'Din automatiske handling er oprettet.', - 'Unable to create your automatic action.' => 'Din automatiske handling kunne ikke oprettes.', - 'Remove an action' => 'Fjern an handling', - 'Unable to remove this action.' => 'Handlingen kunne ikke fjernes.', - 'Action removed successfully.' => 'Handlingen er fjernet.', - 'Automatic actions for the project "%s"' => 'Automatiske handlinger for projektet "%s"', - 'Add an action' => 'Tilføj en handling', - 'Event name' => 'Begivenhed', - 'Action name' => 'Handling', - 'Action parameters' => 'Handlingsparametre', - 'Action' => 'Handling', - 'Event' => 'Begivenhed', - 'When the selected event occurs execute the corresponding action.' => 'Når den valgte begivenhed opstår, udfør den tilsvarende handling.', - 'Next step' => 'Næste', - 'Define action parameters' => 'Definer Handlingsparametre', - 'Do you really want to remove this action: "%s"?' => 'Vil du virkelig slette denne handling: "%s"?', - 'Remove an automatic action' => 'Fjern en automatisk handling', - 'Assign the task to a specific user' => 'Tildel opgaven til en bestem bruger', - 'Assign the task to the person who does the action' => 'Tildel opgaven til den person, der udfører handlingen', - 'Duplicate the task to another project' => 'Kopier opgaven til et andet projekt', - 'Move a task to another column' => 'Flyt opgaven til en anden kolonne', - 'Task modification' => 'Opgave forandring', - 'Task creation' => 'Opgave oprettelse', - 'Closing a task' => 'Lukke en opgave', - 'Assign a color to a specific user' => 'Tildel en farve til en bestemt bruger', - 'Column title' => 'Kolonne titel', - 'Position' => 'Position', - 'Duplicate to another project' => 'Kopier til et andet projekt', - 'Duplicate' => 'Kopier', - 'link' => 'link', - 'Comment updated successfully.' => 'Kommentar opdateret.', - 'Unable to update your comment.' => 'Din kommentar kunne ikke opdateres.', - 'Remove a comment' => 'Fjern en kommentar', - 'Comment removed successfully.' => 'Kommentaren blev fjernet.', - 'Unable to remove this comment.' => 'Kommentaren kunne ikke fjernes.', - 'Do you really want to remove this comment?' => 'Vil du virkelig fjerne denne kommentar?', - 'Current password for the user "%s"' => 'Aktuelle adgangskode for brugeren "%s"', - 'The current password is required' => 'Den aktuelle adgangskode er krævet', - 'Wrong password' => 'Forkert adgangskode', - 'Unknown' => 'Ukendt', - 'Last logins' => 'Sidste login', - 'Login date' => 'Login dato', - 'Authentication method' => 'Godkendelsesmetode', - 'IP address' => 'IP Adresse', - 'User agent' => 'User Agent', - 'Persistent connections' => 'Vedvarende forbindelser', - 'No session.' => 'Ingen session.', - 'Expiration date' => 'Udløbsdato', - 'Remember Me' => 'Husk mig', - 'Creation date' => 'Oprettelsesdato', - 'Everybody' => 'Alle', - 'Open' => 'Åben', - 'Closed' => 'Lukket', - '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', - 'Email address invalid' => 'Ugyldig email', - // 'Your external account is not linked anymore to your profile.' => '', - // 'Unable to unlink your external account.' => '', - // 'External authentication failed' => '', - // 'Your external account is linked to your profile successfully.' => '', - 'Email' => 'E-Mail', - 'Task removed successfully.' => 'Opgaven er fjernet.', - 'Unable to remove this task.' => 'Opgaven kunne ikke fjernes.', - 'Remove a task' => 'Fjern en opgave', - 'Do you really want to remove this task: "%s"?' => 'Vil du virkelig fjerne denne opgave: "%s"?', - 'Assign automatically a color based on a category' => 'Tildel automatisk en farve baseret for en kategori', - 'Assign automatically a category based on a color' => 'Tildel automatisk en kategori baseret op en farve', - 'Task creation or modification' => 'Opgave oprettelse eller forandring', - 'Category' => 'Kategori', - 'Category:' => 'Kategori:', - 'Categories' => 'Kategorier', - 'Your category have been created successfully.' => 'Kategorien er oprettet.', - 'Unable to create your category.' => 'Kategorien kunne ikke oprettes.', - 'Your category have been updated successfully.' => 'Kategorien er opdateret.', - 'Unable to update your category.' => 'Kategorien kunne ikke opdateres.', - 'Remove a category' => 'Fjern en kategori', - 'Category removed successfully.' => 'Kategorien er fjernet.', - 'Unable to remove this category.' => 'Kategorien kunne ikke fjernes.', - 'Category modification for the project "%s"' => 'Forandring af kategori for projektet "%s"', - 'Category Name' => 'Kategorinavn', - 'Add a new category' => 'Tilfæj en ny kategori', - 'Do you really want to remove this category: "%s"?' => 'Vil du virkelig fjerne denne kategori: "%s"?', - 'All categories' => 'Alle kategorier', - 'No category' => 'Ingen kategori', - 'The name is required' => 'Navnet er krævet', - 'Remove a file' => 'Fjern en fil', - 'Unable to remove this file.' => 'Filen kunne ikke fjernes.', - 'File removed successfully.' => 'Filen er fjernet.', - 'Attach a document' => 'Vedhæft et dokument', - 'Do you really want to remove this file: "%s"?' => 'Vil du virkelig fjerne denne fil: "%s"?', - 'Attachments' => 'Vedhæftninger', - 'Edit the task' => 'Rediger opgaven', - 'Add a comment' => 'Tilføj en kommentar', - 'Edit a comment' => 'Rediger en kommentar', - 'Summary' => 'Resumé', - 'Time tracking' => 'Tidsregistrering', - 'Estimate:' => 'Estimering:', - 'Spent:' => 'Brugt:', - 'Do you really want to remove this sub-task?' => 'Vil du virkeligt fjerne denne under-opgave?', - 'Remaining:' => 'Tilbageværende:', - 'hours' => 'timer', - 'spent' => 'brugt', - 'estimated' => 'estimeret', - 'Sub-Tasks' => 'Under-opgave', - 'Add a sub-task' => 'Tilføj en under-opgave', - 'Original estimate' => 'Original estimering', - 'Create another sub-task' => 'Tilføj endnu en under-opgave', - 'Time spent' => 'Tidsforbrug', - 'Edit a sub-task' => 'Rediger en under-opgave', - 'Remove a sub-task' => 'Fjern en under-opgave', - 'The time must be a numeric value' => 'Tiden skal være en nummerisk værdi', - 'Todo' => 'Todo', - 'In progress' => 'I gang', - 'Sub-task removed successfully.' => 'Under-opgaven er fjernet.', - 'Unable to remove this sub-task.' => 'Under-opgaven kunne ikke fjernes.', - 'Sub-task updated successfully.' => 'Under-opgaven er opdateret.', - 'Unable to update your sub-task.' => 'Under-opgaven kunne ikke opdateres.', - 'Unable to create your sub-task.' => 'Under-opgaven kunne ikke oprettes.', - 'Sub-task added successfully.' => 'Under-opgaven er tilføjet.', - 'Maximum size: ' => 'Maksimum størrelse: ', - 'Unable to upload the file.' => 'Filen kunne ikke uploades.', - 'Display another project' => 'Vis et andet projekt...', - 'Created by %s' => 'Oprettet af %s', - 'Tasks Export' => 'Opgave eksport', - 'Tasks exportation for "%s"' => 'Opgave eksport for "%s"', - 'Start Date' => 'Start-dato', - 'End Date' => 'Slut-dato', - 'Execute' => 'Udfør', - 'Task Id' => 'Opgave ID', - 'Creator' => 'Skaber', - 'Modification date' => 'Ændringsdato', - 'Completion date' => 'Afslutningsdato', - 'Clone' => 'Kopier', - 'Project cloned successfully.' => 'Projektet er kopieret.', - 'Unable to clone this project.' => 'Projektet kunne ikke kopieres', - 'Enable email notifications' => 'Aktivér email notifikationer', - 'Task position:' => 'Opgave position:', - 'The task #%d have been opened.' => 'Opgaven #%d er blevet åbnet.', - 'The task #%d have been closed.' => 'Opgaven #%d er blevet lukket.', - 'Sub-task updated' => 'Under-opgave opdateret', - 'Title:' => 'Titel:', - 'Status:' => 'Status:', - 'Assignee:' => 'Ansvarlig:', - 'Time tracking:' => 'Tidsmåling:', - 'New sub-task' => 'Ny under-opgave', - 'New attachment added "%s"' => 'Ny vedhæftning tilføjet "%s"', - 'New comment posted by %s' => 'Ny kommentar af %s', - // 'New attachment' => '', - // 'New comment' => '', - 'Comment updated' => 'Kommentar opdateret', - // 'New subtask' => '', - // 'Subtask updated' => '', - // 'Task updated' => '', - // 'Task closed' => '', - // 'Task opened' => '', - 'I want to receive notifications only for those projects:' => 'Jeg vil kun have notifikationer for disse projekter:', - 'view the task on Kanboard' => 'se opgaven på Kanboard', - 'Public access' => 'Offentlig adgang', - 'Active tasks' => 'Aktive opgaver', - 'Disable public access' => 'Deaktiver offentlig adgang', - 'Enable public access' => 'Aktivér offentlig adgang', - 'Public access disabled' => 'Offentlig adgang deaktiveret', - 'Do you really want to disable this project: "%s"?' => 'Vil du virkelig deaktivere dette projekt: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Vil du virkelig aktiverer dette projekt: "%s"?', - 'Project activation' => 'Projekt aktivering', - 'Move the task to another project' => 'Flyt opgaven til et andet projekt', - 'Move to another project' => 'Flyt til et andet projekt', - 'Do you really want to duplicate this task?' => 'Vil du virkelig kopiere denne opgave?', - 'Duplicate a task' => 'Kopier en opgave', - 'External accounts' => 'Eksterne kontoer', - 'Account type' => 'Kontotype', - 'Local' => 'Lokal', - 'Remote' => 'Remote', - 'Enabled' => 'Aktiv', - 'Disabled' => 'Deaktiveret', - 'Username:' => 'Brugernavn', - 'Name:' => 'Navn:', - 'Email:' => 'Email:', - 'Notifications:' => 'Notifikationer:', - 'Notifications' => 'Notifikationer', - 'Account type:' => 'Konto type:', - 'Edit profile' => 'Rediger profil', - 'Change password' => 'Skift adgangskode', - 'Password modification' => 'Adgangskode ændring', - 'External authentications' => 'Ekstern autentificering', - 'Never connected.' => 'Aldrig forbundet.', - 'No external authentication enabled.' => 'Ingen eksterne autentificering aktiveret.', - 'Password modified successfully.' => 'Adgangskode ændret.', - 'Unable to change the password.' => 'Adgangskoden kunne ikke ændres.', - 'Change category' => 'Skift kategori', - '%s updated the task %s' => '%s opdatert opgaven %s', - '%s opened the task %s' => '%s åben opgaven %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s flyt opgaven %s til positionen #%d i kolonnen "%s"', - '%s moved the task %s to the column "%s"' => '%s flyttede opgaven %s til kolonnen "%s"', - '%s created the task %s' => '%s oprettede opgaven %s', - // '%s closed the task %s' => '', - '%s created a subtask for the task %s' => '%s oprettede en under-opgave for opgaven %s', - '%s updated a subtask for the task %s' => '%s opdaterede en under-opgave for opgaven %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Tildelt til %s med en estimering på %s/%sh', - 'Not assigned, estimate of %sh' => 'Ikke tildelt, estimeret til %sh', - '%s updated a comment on the task %s' => '%s opdateret en kommentar på opgaven %s', - '%s commented the task %s' => '%s har kommenteret opgaven %s', - '%s\'s activity' => '%s\'s aktvitet', - 'RSS feed' => 'RSS feed', - '%s updated a comment on the task #%d' => '%s opdaterede en kommentar på opgaven #%d', - '%s commented on the task #%d' => '%s kommenteret op opgaven #%d', - '%s updated a subtask for the task #%d' => '%s opdaterede en under-opgave for opgaven #%d', - '%s created a subtask for the task #%d' => '%s oprettede en under-opgave for opgaven #%d', - '%s updated the task #%d' => '%s opdaterede opgaven #%d', - '%s created the task #%d' => '%s oprettede opgaven #%d', - '%s closed the task #%d' => '%s lukkede opgaven #%d', - '%s open the task #%d' => '%s åbnede opgaven #%d', - '%s moved the task #%d to the column "%s"' => '%s flyttede opgaven #%d til kolonnen "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s flyttede opgaven #%d til position %d i kolonnen "%s"', - 'Activity' => 'Aktivitet', - 'Default values are "%s"' => 'Standard værdier er "%s"', - 'Default columns for new projects (Comma-separated)' => 'Standard kolonne for nye projekter (kommasepareret)', - 'Task assignee change' => 'Opgaven ansvarlig ændring', - '%s change the assignee of the task #%d to %s' => '%s skrift ansvarlig for opgaven #%d til %s', - '%s changed the assignee of the task %s to %s' => '%s skift ansvarlig for opgaven %s til %s', - 'New password for the user "%s"' => 'Ny adgangskode for brugeren "%s"', - 'Choose an event' => 'Vælg et event', - 'Create a task from an external provider' => 'Opret en opgave fra en ekstern udbyder', - 'Change the assignee based on an external username' => 'Skift den ansvarlige baseret på et eksternt brugernavn', - 'Change the category based on an external label' => 'Skift kategorien baseret på en ekstern label', - 'Reference' => 'Reference', - 'Label' => 'Label', - 'Database' => 'Database', - 'About' => 'Om', - 'Database driver:' => 'Database driver:', - 'Board settings' => 'Baord indstillinger', - 'Webhook settings' => 'Webhook indstillinger', - 'Reset token' => 'Reset endpoint', - 'API endpoint:' => 'API endpoint:', - 'Refresh interval for private board' => 'Refresh interval for privat board', - 'Refresh interval for public board' => 'Refresh interval for offentligt board', - 'Task highlight period' => 'Opgave fremhævet periode', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Periode for at antage en opgave er ændret fornylig (0 for at deaktivere, 2 dage som standard)', - 'Frequency in second (60 seconds by default)' => 'Frekevens i sekunder (60 sekunder som standard)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvens i sekunder (0 for at deaktivere denne funktion, 10 sekunder som standard)', - 'Application URL' => 'Applikation URL', - 'Token regenerated.' => 'Token regenereret.', - 'Date format' => 'Dato format', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format er altid accepteret, eksempelvis: "%s" og "%s"', - 'New private project' => 'Nyt privat projekt', - 'This project is private' => 'Dette projekt er privat', - 'Add' => 'Tilføj', - 'Start date' => 'Start dato', - 'Time estimated' => 'Tid estimeret', - 'There is nothing assigned to you.' => 'Der er ingenting tildelt til dig.', - 'My tasks' => 'Mine opgaver', - 'Activity stream' => 'Aktivitets strøm', - 'Dashboard' => 'Dashboard', - 'Confirmation' => 'Bekræftelse', - // 'Allow everybody to access to this project' => '', - // 'Everybody have access to this project.' => '', - // 'Webhooks' => '', - // 'API' => '', - // 'Create a comment from an external provider' => '', - // 'Project management' => '', - // 'My projects' => '', - // 'Columns' => '', - // 'Task' => '', - // 'Your are not member of any project.' => '', - // 'Percentage' => '', - // 'Number of tasks' => '', - // 'Task distribution' => '', - // 'Reportings' => '', - // 'Task repartition for "%s"' => '', - // 'Analytics' => '', - // 'Subtask' => '', - // 'My subtasks' => '', - // 'User repartition' => '', - // 'User repartition for "%s"' => '', - // 'Clone this project' => '', - // 'Column removed successfully.' => '', - // 'Not enough data to show the graph.' => '', - // 'Previous' => '', - // 'The id must be an integer' => '', - // 'The project id must be an integer' => '', - // 'The status must be an integer' => '', - // 'The subtask id is required' => '', - // 'The subtask id must be an integer' => '', - // 'The task id is required' => '', - // 'The task id must be an integer' => '', - // 'The user id must be an integer' => '', - // 'This value is required' => '', - // 'This value must be numeric' => '', - // 'Unable to create this task.' => '', - // 'Cumulative flow diagram' => '', - // 'Cumulative flow diagram for "%s"' => '', - // 'Daily project summary' => '', - // 'Daily project summary export' => '', - // 'Daily project summary export for "%s"' => '', - // 'Exports' => '', - // 'This export contains the number of tasks per column grouped per day.' => '', - // 'Active swimlanes' => '', - // 'Add a new swimlane' => '', - // 'Change default swimlane' => '', - // 'Default swimlane' => '', - // 'Do you really want to remove this swimlane: "%s"?' => '', - // 'Inactive swimlanes' => '', - // 'Remove a swimlane' => '', - // 'Show default swimlane' => '', - // 'Swimlane modification for the project "%s"' => '', - // 'Swimlane removed successfully.' => '', - // 'Swimlanes' => '', - // 'Swimlane updated successfully.' => '', - // 'The default swimlane have been updated successfully.' => '', - // 'Unable to remove this swimlane.' => '', - // 'Unable to update this swimlane.' => '', - // 'Your swimlane have been created successfully.' => '', - // 'Example: "Bug, Feature Request, Improvement"' => '', - // 'Default categories for new projects (Comma-separated)' => '', - // 'Integrations' => '', - // 'Integration with third-party services' => '', - // 'Subtask Id' => '', - // 'Subtasks' => '', - // 'Subtasks Export' => '', - // 'Subtasks exportation for "%s"' => '', - // 'Task Title' => '', - // 'Untitled' => '', - // 'Application default' => '', - // 'Language:' => '', - // 'Timezone:' => '', - // 'All columns' => '', - // 'Calendar' => '', - // 'Next' => '', - // '#%d' => '', - // 'All swimlanes' => '', - // 'All colors' => '', - // 'Moved to column %s' => '', - // 'User dashboard' => '', - // 'Allow only one subtask in progress at the same time for a user' => '', - // 'Edit column "%s"' => '', - // 'Select the new status of the subtask: "%s"' => '', - // 'Subtask timesheet' => '', - // 'There is nothing to show.' => '', - // 'Time Tracking' => '', - // 'You already have one subtask in progress' => '', - // 'Which parts of the project do you want to duplicate?' => '', - // 'Disallow login form' => '', - // 'Start' => '', - // 'End' => '', - // 'Task age in days' => '', - // 'Days in this column' => '', - // '%dd' => '', - // 'Add a new link' => '', - // 'Do you really want to remove this link: "%s"?' => '', - // 'Do you really want to remove this link with task #%d?' => '', - // 'Field required' => '', - // 'Link added successfully.' => '', - // 'Link updated successfully.' => '', - // 'Link removed successfully.' => '', - // 'Link labels' => '', - // 'Link modification' => '', - // 'Links' => '', - // 'Link settings' => '', - // 'Opposite label' => '', - // 'Remove a link' => '', - // 'Task\'s links' => '', - // 'The labels must be different' => '', - // 'There is no link.' => '', - // 'This label must be unique' => '', - // 'Unable to create your link.' => '', - // 'Unable to update your link.' => '', - // 'Unable to remove this link.' => '', - // 'relates to' => '', - // 'blocks' => '', - // 'is blocked by' => '', - // 'duplicates' => '', - // 'is duplicated by' => '', - // 'is a child of' => '', - // 'is a parent of' => '', - // 'targets milestone' => '', - // 'is a milestone of' => '', - // 'fixes' => '', - // 'is fixed by' => '', - // 'This task' => '', - // '<1h' => '', - // '%dh' => '', - // 'Expand tasks' => '', - // 'Collapse tasks' => '', - // 'Expand/collapse tasks' => '', - // 'Close dialog box' => '', - // 'Submit a form' => '', - // 'Board view' => '', - // 'Keyboard shortcuts' => '', - // 'Open board switcher' => '', - // 'Application' => '', - // 'Compact view' => '', - // 'Horizontal scrolling' => '', - // 'Compact/wide view' => '', - // 'No results match:' => '', - // 'Currency' => '', - // 'Private project' => '', - // 'AUD - Australian Dollar' => '', - // 'CAD - Canadian Dollar' => '', - // 'CHF - Swiss Francs' => '', - // 'Custom Stylesheet' => '', - // 'download' => '', - // 'EUR - Euro' => '', - // 'GBP - British Pound' => '', - // 'INR - Indian Rupee' => '', - // 'JPY - Japanese Yen' => '', - // 'NZD - New Zealand Dollar' => '', - // 'RSD - Serbian dinar' => '', - // 'USD - US Dollar' => '', - // 'Destination column' => '', - // 'Move the task to another column when assigned to a user' => '', - // 'Move the task to another column when assignee is cleared' => '', - // 'Source column' => '', - // 'Transitions' => '', - // 'Executer' => '', - // 'Time spent in the column' => '', - // 'Task transitions' => '', - // 'Task transitions export' => '', - // 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '', - // 'Currency rates' => '', - // 'Rate' => '', - // 'Change reference currency' => '', - // 'Add a new currency rate' => '', - // 'Reference currency' => '', - // 'The currency rate have been added successfully.' => '', - // 'Unable to add this currency rate.' => '', - // 'Webhook URL' => '', - // '%s remove the assignee of the task %s' => '', - // 'Enable Gravatar images' => '', - // 'Information' => '', - // 'Check two factor authentication code' => '', - // 'The two factor authentication code is not valid.' => '', - // 'The two factor authentication code is valid.' => '', - // 'Code' => '', - // 'Two factor authentication' => '', - // 'This QR code contains the key URI: ' => '', - // 'Check my code' => '', - // 'Secret key: ' => '', - // 'Test your device' => '', - // 'Assign a color when the task is moved to a specific column' => '', - // '%s via Kanboard' => '', - // 'Burndown chart for "%s"' => '', - // 'Burndown chart' => '', - // 'This chart show the task complexity over the time (Work Remaining).' => '', - // 'Screenshot taken %s' => '', - // 'Add a screenshot' => '', - // 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '', - // 'Screenshot uploaded successfully.' => '', - // 'SEK - Swedish Krona' => '', - // 'Identifier' => '', - // 'Disable two factor authentication' => '', - // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', - // 'Edit link' => '', - // 'Start to type task title...' => '', - // 'A task cannot be linked to itself' => '', - // 'The exact same link already exists' => '', - // 'Recurrent task is scheduled to be generated' => '', - // 'Score' => '', - // 'The identifier must be unique' => '', - // 'This linked task id doesn\'t exists' => '', - // 'This value must be alphanumeric' => '', - // 'Edit recurrence' => '', - // 'Generate recurrent task' => '', - // 'Trigger to generate recurrent task' => '', - // 'Factor to calculate new due date' => '', - // 'Timeframe to calculate new due date' => '', - // 'Base date to calculate new due date' => '', - // 'Action date' => '', - // 'Base date to calculate new due date: ' => '', - // 'This task has created this child task: ' => '', - // 'Day(s)' => '', - // 'Existing due date' => '', - // 'Factor to calculate new due date: ' => '', - // 'Month(s)' => '', - // 'Recurrence' => '', - // 'This task has been created by: ' => '', - // 'Recurrent task has been generated:' => '', - // 'Timeframe to calculate new due date: ' => '', - // 'Trigger to generate recurrent task: ' => '', - // 'When task is closed' => '', - // 'When task is moved from first column' => '', - // 'When task is moved to last column' => '', - // 'Year(s)' => '', - // 'Calendar settings' => '', - // 'Project calendar view' => '', - // 'Project settings' => '', - // 'Show subtasks based on the time tracking' => '', - // 'Show tasks based on the creation date' => '', - // 'Show tasks based on the start date' => '', - // 'Subtasks time tracking' => '', - // 'User calendar view' => '', - // 'Automatically update the start date' => '', - // 'iCal feed' => '', - // 'Preferences' => '', - // 'Security' => '', - // 'Two factor authentication disabled' => '', - // 'Two factor authentication enabled' => '', - // 'Unable to update this user.' => '', - // 'There is no user management for private projects.' => '', - // 'User that will receive the email' => '', - // 'Email subject' => '', - // 'Date' => '', - // 'Add a comment log when moving the task between columns' => '', - // 'Move the task to another column when the category is changed' => '', - // 'Send a task by email to someone' => '', - // 'Reopen a task' => '', - // 'Column change' => '', - // 'Position change' => '', - // 'Swimlane change' => '', - // 'Assignee change' => '', - // '[%s] Overdue tasks' => '', - // 'Notification' => '', - // '%s moved the task #%d to the first swimlane' => '', - // '%s moved the task #%d to the swimlane "%s"' => '', - // 'Swimlane' => '', - // 'Gravatar' => '', - // '%s moved the task %s to the first swimlane' => '', - // '%s moved the task %s to the swimlane "%s"' => '', - // 'This report contains all subtasks information for the given date range.' => '', - // 'This report contains all tasks information for the given date range.' => '', - // 'Project activities for %s' => '', - // 'view the board on Kanboard' => '', - // 'The task have been moved to the first swimlane' => '', - // 'The task have been moved to another swimlane:' => '', - // 'New title: %s' => '', - // 'The task is not assigned anymore' => '', - // 'New assignee: %s' => '', - // 'There is no category now' => '', - // 'New category: %s' => '', - // 'New color: %s' => '', - // 'New complexity: %d' => '', - // 'The due date have been removed' => '', - // 'There is no description anymore' => '', - // 'Recurrence settings have been modified' => '', - // 'Time spent changed: %sh' => '', - // 'Time estimated changed: %sh' => '', - // 'The field "%s" have been updated' => '', - // 'The description has been modified:' => '', - // 'Do you really want to close the task "%s" as well as all subtasks?' => '', - // 'I want to receive notifications for:' => '', - // 'All tasks' => '', - // 'Only for tasks assigned to me' => '', - // 'Only for tasks created by me' => '', - // 'Only for tasks created by me and assigned to me' => '', - // '%%Y-%%m-%%d' => '', - // 'Total for all columns' => '', - // 'You need at least 2 days of data to show the chart.' => '', - // '<15m' => '', - // '<30m' => '', - // 'Stop timer' => '', - // 'Start timer' => '', - // 'Add project member' => '', - // 'My activity stream' => '', - // 'My calendar' => '', - // 'Search tasks' => '', - // 'Reset filters' => '', - // 'My tasks due tomorrow' => '', - // 'Tasks due today' => '', - // 'Tasks due tomorrow' => '', - // 'Tasks due yesterday' => '', - // 'Closed tasks' => '', - // 'Open tasks' => '', - // 'Not assigned' => '', - // 'View advanced search syntax' => '', - // 'Overview' => '', - // 'Board/Calendar/List view' => '', - // 'Switch to the board view' => '', - // 'Switch to the calendar view' => '', - // 'Switch to the list view' => '', - // 'Go to the search/filter box' => '', - // 'There is no activity yet.' => '', - // 'No tasks found.' => '', - // 'Keyboard shortcut: "%s"' => '', - // 'List' => '', - // 'Filter' => '', - // 'Advanced search' => '', - // 'Example of query: ' => '', - // 'Search by project: ' => '', - // 'Search by column: ' => '', - // 'Search by assignee: ' => '', - // 'Search by color: ' => '', - // 'Search by category: ' => '', - // 'Search by description: ' => '', - // 'Search by due date: ' => '', - // 'Lead and Cycle time for "%s"' => '', - // 'Average time spent into each column for "%s"' => '', - // 'Average time spent into each column' => '', - // 'Average time spent' => '', - // 'This chart show the average time spent into each column for the last %d tasks.' => '', - // 'Average Lead and Cycle time' => '', - // 'Average lead time: ' => '', - // 'Average cycle time: ' => '', - // 'Cycle Time' => '', - // 'Lead Time' => '', - // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', - // 'Average time into each column' => '', - // 'Lead and cycle time' => '', - // 'Lead time: ' => '', - // 'Cycle time: ' => '', - // 'Time spent into each column' => '', - // 'The lead time is the duration between the task creation and the completion.' => '', - // 'The cycle time is the duration between the start date and the completion.' => '', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - // 'Set automatically the start date' => '', - // 'Edit Authentication' => '', - // 'Remote user' => '', - // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', - // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - // 'New remote user' => '', - // 'New local user' => '', - // 'Default task color' => '', - // 'This feature does not work with all browsers.' => '', - // 'There is no destination project available.' => '', - // 'Trigger automatically subtask time tracking' => '', - // 'Include closed tasks in the cumulative flow diagram' => '', - // 'Current swimlane: %s' => '', - // 'Current column: %s' => '', - // 'Current category: %s' => '', - // 'no category' => '', - // 'Current assignee: %s' => '', - // 'not assigned' => '', - // 'Author:' => '', - // 'contributors' => '', - // 'License:' => '', - // 'License' => '', - // 'Enter the text below' => '', - // 'Gantt chart for %s' => '', - // 'Sort by position' => '', - // 'Sort by date' => '', - // 'Add task' => '', - // 'Start date:' => '', - // 'Due date:' => '', - // 'There is no start date or due date for this task.' => '', - // 'Moving or resizing a task will change the start and due date of the task.' => '', - // 'There is no task in your project.' => '', - // 'Gantt chart' => '', - // 'People who are project managers' => '', - // 'People who are project members' => '', - // 'NOK - Norwegian Krone' => '', - // 'Show this column' => '', - // 'Hide this column' => '', - // 'open file' => '', - // 'End date' => '', - // 'Users overview' => '', - // 'Members' => '', - // 'Shared project' => '', - // 'Project managers' => '', - // 'Gantt chart for all projects' => '', - // 'Projects list' => '', - // 'Gantt chart for this project' => '', - // 'Project board' => '', - // 'End date:' => '', - // 'There is no start date or end date for this project.' => '', - // 'Projects Gantt chart' => '', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - // 'Milestone' => '', - // 'Documentation: %s' => '', - // 'Switch to the Gantt chart view' => '', - // 'Reset the search/filter box' => '', - // 'Documentation' => '', - // 'Table of contents' => '', - // 'Gantt' => '', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - // 'Link type' => '', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - // 'Project members' => '', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/de_DE/translations.php b/sources/app/Locale/de_DE/translations.php deleted file mode 100644 index 81df4e5..0000000 --- a/sources/app/Locale/de_DE/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'Keines', - 'edit' => 'Bearbeiten', - 'Edit' => 'Bearbeiten', - 'remove' => 'Entfernen', - 'Remove' => 'Entfernen', - 'Yes' => 'Ja', - 'No' => 'Nein', - 'cancel' => 'Abbrechen', - 'or' => 'oder', - 'Yellow' => 'Gelb', - 'Blue' => 'Blau', - 'Green' => 'Grün', - 'Purple' => 'Violett', - 'Red' => 'Rot', - 'Orange' => 'Orange', - 'Grey' => 'Grau', - 'Brown' => 'Braun', - 'Deep Orange' => 'Dunkelorange', - 'Dark Grey' => 'Dunkelgrau', - 'Pink' => 'Pink', - 'Teal' => 'Türkis', - 'Cyan' => 'Cyan', - 'Lime' => 'Limette', - 'Light Green' => 'Hellgrün', - 'Amber' => 'Bernstein', - 'Save' => 'Speichern', - 'Login' => 'Anmelden', - 'Official website:' => 'Offizielle Webseite:', - 'Unassigned' => 'Nicht zugeordnet', - 'View this task' => 'Aufgabe ansehen', - 'Remove user' => 'Benutzer löschen', - 'Do you really want to remove this user: "%s"?' => 'Soll dieser Benutzer wirklich gelöscht werden: "%s"?', - 'All users' => 'Alle Benutzer', - 'Username' => 'Benutzername', - 'Password' => 'Passwort', - 'Administrator' => 'Administrator', - 'Sign in' => 'Anmelden', - 'Users' => 'Benutzer', - 'No user' => 'Kein Benutzer', - 'Forbidden' => 'Verboten', - 'Access Forbidden' => 'Zugriff verboten', - 'Edit user' => 'Benutzer bearbeiten', - 'Logout' => 'Abmelden', - 'Bad username or password' => 'Falscher Benutzername oder Passwort', - 'Edit project' => 'Projekt bearbeiten', - 'Name' => 'Name', - 'Projects' => 'Projekte', - 'No project' => 'Keine Projekte', - 'Project' => 'Projekt', - 'Status' => 'Status', - 'Tasks' => 'Aufgaben', - 'Board' => 'Pinnwand', - 'Actions' => 'Aktionen', - 'Inactive' => 'Inaktiv', - 'Active' => 'Aktiv', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Soll dieses Projekt wirklich gelöscht werden: "%s"?', - 'Remove project' => 'Projekt löschen', - 'Edit the board for "%s"' => 'Pinnwand für "%s" bearbeiten', - 'All projects' => 'Alle Projekte', - 'Add a new column' => 'Neue Spalte hinzufügen', - '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!', - 'Settings' => 'Einstellungen', - 'Application settings' => 'Anwendungskonfiguration', - 'Language' => 'Sprache', - 'Webhook token:' => 'Webhook Token:', - 'API token:' => 'API Token:', - 'Database size:' => 'Datenbankgröße:', - 'Download the database' => 'Datenbank herunterladen', - 'Optimize the database' => 'Datenbank optimieren', - '(VACUUM command)' => '(VACUUM Befehl)', - '(Gzip compressed Sqlite file)' => '(Gzip-komprimierte SQLite-Datei)', - 'Close a task' => 'Aufgabe abschließen', - 'Edit a task' => 'Aufgabe bearbeiten', - 'Column' => 'Spalte', - 'Color' => 'Farbe', - 'Assignee' => 'Zuständiger', - 'Create another task' => 'Weitere Aufgabe erstellen', - 'New task' => 'Neue Aufgabe', - 'Open a task' => 'Öffne eine Aufgabe', - 'Do you really want to open this task: "%s"?' => 'Soll diese Aufgabe wirklich wieder geöffnet werden: "%s"?', - 'Back to the board' => 'Zurück zur Pinnwand', - 'There is nobody assigned' => 'Die Aufgabe wurde niemandem zugewiesen', - 'Column on the board:' => 'Spalte:', - 'Close this task' => 'Aufgabe schließen', - 'Open this task' => 'Aufgabe wieder öffnen', - 'There is no description.' => 'Keine Beschreibung vorhanden.', - 'Add a new task' => 'Neue Aufgabe hinzufügen', - 'The username is required' => 'Der Benutzername wird benötigt', - 'The maximum length is %d characters' => 'Die maximale Länge beträgt %d Zeichen', - 'The minimum length is %d characters' => 'Die minimale Länge beträgt %d Zeichen', - 'The password is required' => 'Das Passwort wird benötigt', - 'This value must be an integer' => 'Dieser Wert muss eine ganze Zahl sein', - 'The username must be unique' => 'Der Benutzername muss eindeutig sein', - 'The user id is required' => 'Die Benutzer-ID ist anzugeben', - 'Passwords don\'t match' => 'Passwörter nicht gleich', - 'The confirmation is required' => 'Die Bestätigung ist erforderlich', - 'The project is required' => 'Das Projekt ist anzugeben', - 'The id is required' => 'Die ID ist anzugeben', - 'The project id is required' => 'Die Projekt ID ist anzugeben', - 'The project name is required' => 'Der Projektname ist anzugeben', - 'The title is required' => 'Der Titel ist anzugeben', - 'Settings saved successfully.' => 'Einstellungen erfolgreich gespeichert.', - 'Unable to save your settings.' => 'Speichern der Einstellungen nicht möglich.', - 'Database optimization done.' => 'Optimieren der Datenbank abgeschlossen.', - 'Your project have been created successfully.' => 'Das Projekt wurde erfolgreich erstellt.', - 'Unable to create your project.' => 'Erstellen des Projekts nicht möglich.', - 'Project updated successfully.' => 'Projekt erfolgreich geändert.', - 'Unable to update this project.' => 'Änderung des Projekts nicht möglich.', - 'Unable to remove this project.' => 'Löschen des Projekts nicht möglich.', - 'Project removed successfully.' => 'Projekt erfolgreich gelöscht.', - 'Project activated successfully.' => 'Projekt erfolgreich aktiviert.', - 'Unable to activate this project.' => 'Aktivieren des Projekts nicht möglich.', - 'Project disabled successfully.' => 'Projekt erfolgreich deaktiviert.', - 'Unable to disable this project.' => 'Deaktivieren des Projekts nicht möglich.', - 'Unable to open this task.' => 'Wiedereröffnung der Aufgabe nicht möglich.', - 'Task opened successfully.' => 'Aufgabe erfolgreich wieder geöffnet.', - 'Unable to close this task.' => 'Abschließen der Aufgabe nicht möglich.', - 'Task closed successfully.' => 'Aufgabe erfolgreich geschlossen.', - 'Unable to update your task.' => 'Aktualisieren der Aufgabe nicht möglich.', - 'Task updated successfully.' => 'Aufgabe erfolgreich aktualisiert.', - 'Unable to create your task.' => 'Erstellen der Aufgabe nicht möglich.', - 'Task created successfully.' => 'Aufgabe erfolgreich erstellt.', - 'User created successfully.' => 'Benutzer erfolgreich erstellt.', - 'Unable to create your user.' => 'Erstellen des Benutzers nicht möglich.', - 'User updated successfully.' => 'Benutzer erfolgreich geändert.', - 'Unable to update your user.' => 'Änderung des Benutzers nicht möglich.', - 'User removed successfully.' => 'Benutzer erfolgreich gelöscht.', - 'Unable to remove this user.' => 'Löschen des Benutzers nicht möglich.', - 'Board updated successfully.' => 'Pinnwand erfolgreich geändert.', - 'Ready' => 'Bereit', - 'Backlog' => 'Ideen', - 'Work in progress' => 'In Arbeit', - 'Done' => 'Erledigt', - 'Application version:' => 'Version:', - 'Id' => 'ID', - '%d closed tasks' => '%d abgeschlossene Aufgaben', - 'No task for this project' => 'Keine Aufgaben in diesem Projekt', - 'Public link' => 'Öffentlicher Link', - 'Timezone' => 'Zeitzone', - 'Sorry, I didn\'t find this information in my database!' => 'Diese Information wurde in der Datenbank nicht gefunden!', - 'Page not found' => 'Seite nicht gefunden', - 'Complexity' => 'Komplexität', - 'Task limit' => 'Maximale Anzahl von Aufgaben', - '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', - 'Invalid date' => 'Ungültiges Datum', - 'Automatic actions' => 'Automatische Aktionen', - 'Your automatic action have been created successfully.' => 'Die automatische Aktion wurde erfolgreich erstellt.', - 'Unable to create your automatic action.' => 'Erstellen der automatischen Aktion nicht möglich.', - 'Remove an action' => 'Aktion löschen', - 'Unable to remove this action.' => 'Löschen der Aktion nicht möglich.', - 'Action removed successfully.' => 'Aktion erfolgreich gelöscht.', - 'Automatic actions for the project "%s"' => 'Automatische Aktionen für das Projekt "%s"', - 'Add an action' => 'Aktion hinzufügen', - 'Event name' => 'Ereignisname', - 'Action name' => 'Aktionsname', - 'Action parameters' => 'Aktionsparameter', - 'Action' => 'Aktion', - 'Event' => 'Ereignis', - 'When the selected event occurs execute the corresponding action.' => 'Wenn das gewählte Ereignis eintritt, führe die zugehörige Aktion aus.', - 'Next step' => 'Weiter', - 'Define action parameters' => 'Aktionsparameter definieren', - 'Do you really want to remove this action: "%s"?' => 'Soll diese Aktion wirklich gelöscht werden: "%s"?', - 'Remove an automatic action' => 'Löschen einer automatischen Aktion', - 'Assign the task to a specific user' => 'Aufgabe einem Benutzer zuordnen', - 'Assign the task to the person who does the action' => 'Aufgabe dem Benutzer zuordnen, der die Aktion ausgeführt hat', - 'Duplicate the task to another project' => 'Aufgabe in ein anderes Projekt kopieren', - 'Move a task to another column' => 'Aufgabe in andere Spalte verschieben', - 'Task modification' => 'Aufgabe ändern', - 'Task creation' => 'Aufgabe erstellen', - 'Closing a task' => 'Aufgabe abschließen', - 'Assign a color to a specific user' => 'Einem Benutzer eine Farbe zuordnen', - 'Column title' => 'Spaltentitel', - 'Position' => 'Position', - 'Duplicate to another project' => 'In ein anderes Projekt duplizieren', - 'Duplicate' => 'Duplizieren', - 'link' => 'Link', - 'Comment updated successfully.' => 'Kommentar erfolgreich aktualisiert.', - 'Unable to update your comment.' => 'Aktualisierung des Kommentars nicht möglich.', - 'Remove a comment' => 'Kommentar löschen', - 'Comment removed successfully.' => 'Kommentar erfolgreich gelöscht.', - 'Unable to remove this comment.' => 'Löschen des Kommentars nicht möglich.', - 'Do you really want to remove this comment?' => 'Soll dieser Kommentar wirklich gelöscht werden?', - 'Current password for the user "%s"' => 'Aktuelles Passwort des Benutzers "%s"', - 'The current password is required' => 'Das aktuelle Passwort wird benötigt', - 'Wrong password' => 'Falsches Passwort', - 'Unknown' => 'Unbekannt', - 'Last logins' => 'Letzte Anmeldungen', - 'Login date' => 'Anmeldedatum', - 'Authentication method' => 'Authentisierungsmethode', - 'IP address' => 'IP-Adresse', - 'User agent' => 'User-Agent', - 'Persistent connections' => 'Bestehende Verbindungen', - 'No session.' => 'Keine Sitzung.', - 'Expiration date' => 'Ablaufdatum', - 'Remember Me' => 'Angemeldet bleiben', - 'Creation date' => 'Erstellungsdatum', - 'Everybody' => 'Alle', - 'Open' => 'Offen', - 'Closed' => 'Abgeschlossen', - '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', - 'Email address invalid' => 'Ungültige E-Mail-Adresse', - 'Your external account is not linked anymore to your profile.' => 'Dein externer Account ist nicht mehr mit deinem Profil verbunden.', - 'Unable to unlink your external account.' => 'Externer Account konnte nicht getrennt werden.', - 'External authentication failed' => 'Externe Authentifizierung fehlgeschlagen', - 'Your external account is linked to your profile successfully.' => 'Dein externer Account wurde erfolgreich mit deinem Profil verbunden', - 'Email' => 'E-Mail', - 'Task removed successfully.' => 'Aufgabe erfolgreich gelöscht.', - 'Unable to remove this task.' => 'Löschen der Aufgabe nicht möglich.', - 'Remove a task' => 'Aufgabe löschen', - 'Do you really want to remove this task: "%s"?' => 'Soll diese Aufgabe wirklich gelöscht werden: "%s"?', - 'Assign automatically a color based on a category' => 'Automatisch eine Farbe anhand der Kategorie zuweisen', - 'Assign automatically a category based on a color' => 'Automatisch eine Kategorie anhand der Farbe zuweisen', - 'Task creation or modification' => 'Aufgabe erstellen oder ändern', - 'Category' => 'Kategorie', - 'Category:' => 'Kategorie:', - 'Categories' => 'Kategorien', - 'Your category have been created successfully.' => 'Kategorie erfolgreich erstellt.', - 'Unable to create your category.' => 'Erstellung der Kategorie nicht möglich.', - 'Your category have been updated successfully.' => 'Kategorie erfolgreich aktualisiert.', - 'Unable to update your category.' => 'Änderung der Kategorie nicht möglich.', - 'Remove a category' => 'Kategorie löschen', - 'Category removed successfully.' => 'Kategorie erfolgreich gelöscht.', - 'Unable to remove this category.' => 'Löschen der Kategorie nicht möglich.', - 'Category modification for the project "%s"' => 'Kategorie für das Projekt "%s" bearbeiten', - 'Category Name' => 'Kategoriename', - 'Add a new category' => 'Neue Kategorie', - 'Do you really want to remove this category: "%s"?' => 'Soll diese Kategorie wirklich gelöscht werden: "%s"?', - 'All categories' => 'Alle Kategorien', - 'No category' => 'Keine Kategorie', - 'The name is required' => 'Der Name ist erforderlich', - 'Remove a file' => 'Datei löschen', - 'Unable to remove this file.' => 'Löschen der Datei nicht möglich.', - 'File removed successfully.' => 'Datei erfolgreich gelöscht.', - 'Attach a document' => 'Dokument anhängen', - 'Do you really want to remove this file: "%s"?' => 'Soll diese Datei wirklich gelöscht werden: "%s"?', - 'Attachments' => 'Anhänge', - 'Edit the task' => 'Aufgabe bearbeiten', - 'Add a comment' => 'Kommentar hinzufügen', - 'Edit a comment' => 'Kommentar bearbeiten', - 'Summary' => 'Zusammenfassung', - 'Time tracking' => 'Zeiterfassung', - 'Estimate:' => 'Geschätzt:', - 'Spent:' => 'Aufgewendet:', - 'Do you really want to remove this sub-task?' => 'Soll diese Teilaufgabe wirklich gelöscht werden?', - 'Remaining:' => 'Verbleibend:', - 'hours' => 'Stunden', - 'spent' => 'aufgewendet', - 'estimated' => 'geschätzt', - 'Sub-Tasks' => 'Teilaufgaben', - 'Add a sub-task' => 'Teilaufgabe anlegen', - 'Original estimate' => 'Geschätzter Aufwand', - 'Create another sub-task' => 'Weitere Teilaufgabe anlegen', - 'Time spent' => 'Aufgewendete Zeit', - 'Edit a sub-task' => 'Teilaufgabe bearbeiten', - 'Remove a sub-task' => 'Teilaufgabe löschen', - 'The time must be a numeric value' => 'Zeit nur als nummerische Angabe', - 'Todo' => 'Nicht gestartet', - 'In progress' => 'In Bearbeitung', - 'Sub-task removed successfully.' => 'Teilaufgabe erfolgreich gelöscht.', - 'Unable to remove this sub-task.' => 'Löschen der Teilaufgabe nicht möglich.', - 'Sub-task updated successfully.' => 'Teilaufgabe erfolgreich aktualisiert.', - 'Unable to update your sub-task.' => 'Aktualisieren der Teilaufgabe nicht möglich.', - 'Unable to create your sub-task.' => 'Erstellen der Teilaufgabe nicht möglich.', - 'Sub-task added successfully.' => 'Teilaufgabe erfolgreich angelegt.', - 'Maximum size: ' => 'Maximalgröße: ', - 'Unable to upload the file.' => 'Hochladen der Datei nicht möglich.', - 'Display another project' => 'Zu Projekt wechseln', - 'Created by %s' => 'Erstellt durch %s', - 'Tasks Export' => 'Aufgaben exportieren', - 'Tasks exportation for "%s"' => 'Aufgaben exportieren für "%s"', - 'Start Date' => 'Anfangsdatum', - 'End Date' => 'Enddatum', - 'Execute' => 'Ausführen', - 'Task Id' => 'Aufgaben ID', - 'Creator' => 'Erstellt von', - 'Modification date' => 'Änderungsdatum', - 'Completion date' => 'Abschlussdatum', - 'Clone' => 'duplizieren', - 'Project cloned successfully.' => 'Projekt wurde dupliziert.', - 'Unable to clone this project.' => 'Duplizieren dieses Projekts schlug fehl.', - 'Enable email notifications' => 'E-Mail-Benachrichtigungen einschalten', - 'Task position:' => 'Position der Aufgabe:', - 'The task #%d have been opened.' => 'Die Aufgabe #%d wurde geöffnet.', - 'The task #%d have been closed.' => 'Die Aufgabe #%d wurde geschlossen.', - 'Sub-task updated' => 'Teilaufgabe aktualisiert', - 'Title:' => 'Titel:', - 'Status:' => 'Status:', - 'Assignee:' => 'Zuständigkeit:', - 'Time tracking:' => 'Zeittracking:', - 'New sub-task' => 'Neue Teilaufgabe', - 'New attachment added "%s"' => 'Neuer Anhang "%s" wurde hinzugefügt.', - 'New comment posted by %s' => 'Neuer Kommentar verfasst durch %s', - 'New attachment' => 'Neuer Anhang', - 'New comment' => 'Neuer Kommentar', - 'Comment updated' => 'Kommentar wurde aktualisiert', - 'New subtask' => 'Neue Teilaufgabe', - 'Subtask updated' => 'Teilaufgabe aktualisiert', - 'Task updated' => 'Aufgabe aktualisiert', - 'Task closed' => 'Aufgabe geschlossen', - 'Task opened' => 'Aufgabe geöffnet', - 'I want to receive notifications only for those projects:' => 'Ich möchte nur für diese Projekte Benachrichtigungen erhalten:', - 'view the task on Kanboard' => 'diese Aufgabe auf dem Kanboard zeigen', - 'Public access' => 'Öffentlicher Zugriff', - 'Active tasks' => 'Aktive Aufgaben', - 'Disable public access' => 'Öffentlichen Zugriff deaktivieren', - 'Enable public access' => 'Öffentlichen Zugriff aktivieren', - 'Public access disabled' => 'Öffentlicher Zugriff deaktiviert', - 'Do you really want to disable this project: "%s"?' => 'Möchten Sie dieses Projekt wirklich deaktivieren: "%s"', - 'Do you really want to enable this project: "%s"?' => 'Möchten Sie dieses Projekt wirklich aktivieren: "%s"', - 'Project activation' => 'Projektaktivierung', - 'Move the task to another project' => 'Aufgabe in ein anderes Projekt verschieben', - 'Move to another project' => 'In anderes Projekt verschieben', - 'Do you really want to duplicate this task?' => 'Möchten Sie diese Aufgabe wirklich duplizieren?', - 'Duplicate a task' => 'Aufgabe duplizieren', - 'External accounts' => 'Externe Accounts', - 'Account type' => 'Accounttyp', - 'Local' => 'Lokal', - 'Remote' => 'Remote', - 'Enabled' => 'angeschaltet', - 'Disabled' => 'abgeschaltet', - 'Username:' => 'Benutzername:', - 'Name:' => 'Name:', - 'Email:' => 'E-Mail:', - 'Notifications:' => 'Benachrichtigungen:', - 'Notifications' => 'Benachrichtigungen', - 'Account type:' => 'Accounttyp:', - 'Edit profile' => 'Profil bearbeiten', - 'Change password' => 'Passwort ändern', - 'Password modification' => 'Passwortänderung', - 'External authentications' => 'Externe Authentisierungsmethoden', - 'Never connected.' => 'Noch nie verbunden.', - 'No external authentication enabled.' => 'Es sind keine externen Authentisierungsmethoden aktiv.', - 'Password modified successfully.' => 'Passwort wurde erfolgreich geändert.', - 'Unable to change the password.' => 'Passwort konnte nicht geändert werden.', - 'Change category' => 'Kategorie ändern', - '%s updated the task %s' => '%s hat die Aufgabe %s aktualisiert', - '%s opened the task %s' => '%s hat die Aufgabe %s geöffnet', - '%s moved the task %s to the position #%d in the column "%s"' => '%s hat die Aufgabe %s auf die Position #%d in der Spalte "%s" verschoben', - '%s moved the task %s to the column "%s"' => '%s hat die Aufgabe %s in die Spalte "%s" verschoben', - '%s created the task %s' => '%s hat die Aufgabe %s angelegt', - '%s closed the task %s' => '%s hat die Aufgabe %s geschlossen', - '%s created a subtask for the task %s' => '%s hat eine Teilaufgabe für die Aufgabe %s angelegt', - '%s updated a subtask for the task %s' => '%s hat eine Teilaufgabe der Aufgabe %s verändert', - 'Assigned to %s with an estimate of %s/%sh' => 'An %s zugewiesen mit einer Schätzung von %s/%s Stunden', - 'Not assigned, estimate of %sh' => 'Nicht zugewiesen, Schätzung von %s Stunden', - '%s updated a comment on the task %s' => '%s hat einen Kommentar der Aufgabe %s aktualisiert', - '%s commented the task %s' => '%s hat die Aufgabe %s kommentiert', - '%s\'s activity' => '%s\'s Aktivität', - 'RSS feed' => 'RSS Feed', - '%s updated a comment on the task #%d' => '%s hat einen Kommentar der Aufgabe #%d aktualisiert', - '%s commented on the task #%d' => '%s hat die Aufgabe #%d kommentiert', - '%s updated a subtask for the task #%d' => '%s hat eine Teilaufgabe der Aufgabe #%d aktualisiert', - '%s created a subtask for the task #%d' => '%s hat eine Teilaufgabe der Aufgabe #%d angelegt', - '%s updated the task #%d' => '%s hat die Aufgabe #%d aktualisiert', - '%s created the task #%d' => '%s hat die Aufgabe #%d angelegt', - '%s closed the task #%d' => '%s hat die Aufgabe #%d geschlossen', - '%s open the task #%d' => '%s hat die Aufgabe #%d geöffnet', - '%s moved the task #%d to the column "%s"' => '%s hat die Aufgabe #%d in die Spalte "%s" verschoben', - '%s moved the task #%d to the position %d in the column "%s"' => '%s hat die Aufgabe #%d an die Position %d in der Spalte "%s" verschoben', - 'Activity' => 'Aktivität', - 'Default values are "%s"' => 'Die Standardwerte sind "%s"', - 'Default columns for new projects (Comma-separated)' => 'Standardspalten für neue Projekte (komma-getrennt)', - 'Task assignee change' => 'Zuständigkeit geändert', - '%s change the assignee of the task #%d to %s' => '%s hat die Zusständigkeit der Aufgabe #%d geändert um %s', - '%s changed the assignee of the task %s to %s' => '%s hat die Zuständigkeit der Aufgabe %s geändert um %s', - 'New password for the user "%s"' => 'Neues Passwort des Benutzers "%s"', - 'Choose an event' => 'Aktion wählen', - 'Create a task from an external provider' => 'Eine Aufgabe durch einen externen Provider hinzufügen', - 'Change the assignee based on an external username' => 'Zuordnung ändern basierend auf externem Benutzernamen', - 'Change the category based on an external label' => 'Kategorie basierend auf einer externen Kennzeichnung ändern', - 'Reference' => 'Referenz', - 'Label' => 'Kennzeichnung', - 'Database' => 'Datenbank', - 'About' => 'Über', - 'Database driver:' => 'Datenbanktreiber:', - 'Board settings' => 'Pinnwandeinstellungen', - 'Webhook settings' => 'Webhook-Einstellungen', - 'Reset token' => 'Token zurücksetzen', - 'API endpoint:' => 'API-Endpunkt:', - 'Refresh interval for private board' => 'Aktualisierungsintervall für private Pinnwände', - 'Refresh interval for public board' => 'Aktualisierungsintervall für öffentliche Pinnwände', - 'Task highlight period' => 'Aufgaben-Hervorhebungsdauer', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Dauer (in Sekunden), wie lange eine Aufgabe als kürzlich verändert gilt (0 um diese Funktion zu deaktivieren, standardmäßig 2 Tage)', - 'Frequency in second (60 seconds by default)' => 'Frequenz in Sekunden (standardmäßig 60 Sekunden)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frequenz in Sekunden (0 um diese Funktion zu deaktivieren, standardmäßig 10 Sekunden)', - 'Application URL' => 'Applikations-URL', - 'Token regenerated.' => 'Token wurde neu generiert.', - 'Date format' => 'Datumsformat', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO Format wird immer akzeptiert, z.B.: "%s" und "%s"', - 'New private project' => 'Neues privates Projekt', - 'This project is private' => 'Dieses Projekt ist privat', - 'Add' => 'Hinzufügen', - 'Start date' => 'Startdatum', - 'Time estimated' => 'Geschätzte Zeit', - 'There is nothing assigned to you.' => 'Ihnen ist nichts zugewiesen.', - 'My tasks' => 'Meine Aufgaben', - 'Activity stream' => 'Letzte Aktivitäten', - 'Dashboard' => 'Dashboard', - 'Confirmation' => 'Wiederholung', - 'Allow everybody to access to this project' => 'Jedem Zugriff zu diesem Projekt gewähren', - 'Everybody have access to this project.' => 'Jeder hat Zugriff zu diesem Projekt', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Kommentar eines externen Providers hinzufügen', - 'Project management' => 'Projektmanagement', - 'My projects' => 'Meine Projekte', - 'Columns' => 'Spalten', - 'Task' => 'Aufgabe', - 'Your are not member of any project.' => 'Sie sind nicht Mitglied eines Projekts.', - 'Percentage' => 'Prozentsatz', - 'Number of tasks' => 'Anzahl an Aufgaben', - 'Task distribution' => 'Aufgabenverteilung', - 'Reportings' => 'Berichte', - 'Task repartition for "%s"' => 'Aufgabenzuweisung für "%s"', - 'Analytics' => 'Analyse', - 'Subtask' => 'Teilaufgabe', - 'My subtasks' => 'Meine Teilaufgaben', - 'User repartition' => 'Benutzerverteilung', - 'User repartition for "%s"' => 'Benutzerverteilung für "%s"', - 'Clone this project' => 'Projekt kopieren', - 'Column removed successfully.' => 'Spalte erfolgreich entfernt.', - 'Not enough data to show the graph.' => 'Nicht genügend Daten, um die Grafik zu zeigen.', - 'Previous' => 'Vorherige', - 'The id must be an integer' => 'Die Id muss eine ganze Zahl sein', - 'The project id must be an integer' => 'Der Projekt-ID muss eine ganze Zahl sein', - 'The status must be an integer' => 'Der Status muss eine ganze Zahl sein', - 'The subtask id is required' => 'Die Teilaufgaben-ID ist benötigt', - 'The subtask id must be an integer' => 'Die Teilaufgaben-ID muss eine ganze Zahl sein', - 'The task id is required' => 'Die Aufgaben-ID ist benötigt', - 'The task id must be an integer' => 'Die Aufgaben-ID muss eine ganze Zahl sein', - 'The user id must be an integer' => 'Die User-ID muss eine ganze Zahl sein', - 'This value is required' => 'Dieser Wert ist erforderlich', - 'This value must be numeric' => 'Dieser Wert muss nummerisch sein', - 'Unable to create this task.' => 'Diese Aufgabe kann nicht erstellt werden', - 'Cumulative flow diagram' => 'Kumulatives Flussdiagramm', - 'Cumulative flow diagram for "%s"' => 'Kumulatives Flussdiagramm für "%s"', - 'Daily project summary' => 'Tägliche Projektzusammenfassung', - 'Daily project summary export' => 'Export der täglichen Projektzusammenfassung', - 'Daily project summary export for "%s"' => 'Export der täglichen Projektzusammenfassung für "%s"', - 'Exports' => 'Exporte', - 'This export contains the number of tasks per column grouped per day.' => 'Dieser Export enthält die Anzahl der Aufgaben pro Spalte nach Tagen gruppiert.', - 'Active swimlanes' => 'Aktive Swimlane', - 'Add a new swimlane' => 'Eine neue Swimlane hinzufügen', - 'Change default swimlane' => 'Standard-Swimlane ändern', - 'Default swimlane' => 'Standard-Swimlane', - 'Do you really want to remove this swimlane: "%s"?' => 'Diese Swimlane wirklich ändern: "%s"?', - 'Inactive swimlanes' => 'Inaktive Swimlane', - 'Remove a swimlane' => 'Swimlane entfernen', - 'Show default swimlane' => 'Standard-Swimlane anzeigen', - 'Swimlane modification for the project "%s"' => 'Swimlane-Änderung für das Projekt "%s"', - 'Swimlane removed successfully.' => 'Swimlane erfolgreich entfernt.', - 'Swimlanes' => 'Swimlanes', - 'Swimlane updated successfully.' => 'Swimlane erfolgreich geändert.', - 'The default swimlane have been updated successfully.' => 'Die Standard-Swimlane wurden erfolgreich aktualisiert. Die Standard-Swimlane wurden erfolgreich aktualisiert.', - 'Unable to remove this swimlane.' => 'Es ist nicht möglich, die Swimlane zu entfernen.', - 'Unable to update this swimlane.' => 'Es ist nicht möglich, die Swimlane zu ändern.', - 'Your swimlane have been created successfully.' => 'Die Swimlane wurde erfolgreich angelegt.', - 'Example: "Bug, Feature Request, Improvement"' => 'Beispiel: "Bug, Funktionswünsche, Verbesserung"', - 'Default categories for new projects (Comma-separated)' => 'Standard-Kategorien für neue Projekte (Komma-getrennt)', - 'Integrations' => 'Integration', - 'Integration with third-party services' => 'Integration von externen Diensten', - 'Subtask Id' => 'Teilaufgaben-ID', - 'Subtasks' => 'Teilaufgaben', - 'Subtasks Export' => 'Export von Teilaufgaben', - 'Subtasks exportation for "%s"' => 'Export von Teilaufgaben für "%s"', - 'Task Title' => 'Aufgaben-Titel', - 'Untitled' => 'unbetitelt', - 'Application default' => 'Anwendungsstandard', - 'Language:' => 'Sprache:', - 'Timezone:' => 'Zeitzone:', - 'All columns' => 'Alle Spalten', - 'Calendar' => 'Kalender', - 'Next' => 'Nächste', - '#%d' => 'Nr %d', - 'All swimlanes' => 'Alle Swimlanes', - 'All colors' => 'Alle Farben', - 'Moved to column %s' => 'In Spalte %s verschoben', - 'User dashboard' => 'Benutzer-Dashboard', - 'Allow only one subtask in progress at the same time for a user' => 'Erlaube nur eine Teilaufgabe pro Benutzer zu bearbeiten', - 'Edit column "%s"' => 'Spalte "%s" bearbeiten', - 'Select the new status of the subtask: "%s"' => 'Wähle einen neuen Status für Teilaufgabe: "%s"', - 'Subtask timesheet' => 'Teilaufgaben Zeiterfassung', - 'There is nothing to show.' => 'Es ist nichts zum Anzeigen vorhanden.', - 'Time Tracking' => 'Zeiterfassung', - 'You already have one subtask in progress' => 'Bereits eine Teilaufgabe in Bearbeitung', - 'Which parts of the project do you want to duplicate?' => 'Welcher Teil des Projekts soll kopiert werden?', - 'Disallow login form' => 'Verbiete Login-Formular', - 'Start' => 'Start', - 'End' => 'Ende', - 'Task age in days' => 'Aufgabenalter in Tagen', - 'Days in this column' => 'Tage in dieser Spalte', - '%dd' => '%dT', - 'Add a new link' => 'Neue Verbindung hinzufügen', - 'Do you really want to remove this link: "%s"?' => 'Die Verbindung "%s" wirklich löschen?', - 'Do you really want to remove this link with task #%d?' => 'Die Verbindung mit der Aufgabe #%d wirklich löschen?', - 'Field required' => 'Feld erforderlich', - 'Link added successfully.' => 'Verbindung erfolgreich hinzugefügt.', - 'Link updated successfully.' => 'Verbindung erfolgreich aktualisiert.', - 'Link removed successfully.' => 'Verbindung erfolgreich gelöscht.', - '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', - 'Unable to create your link.' => 'Verbindung kann nicht erstellt werden.', - 'Unable to update your link.' => 'Verbindung kann nicht aktualisiert werden.', - 'Unable to remove this link.' => 'Verbindung kann nicht entfernt werden', - 'relates to' => 'gehört zu', - 'blocks' => 'blockiert', - 'is blocked by' => 'ist blockiert von', - 'duplicates' => 'doppelt', - 'is duplicated by' => 'ist gedoppelt von', - 'is a child of' => 'ist ein untergeordnetes Element von', - 'is a parent of' => 'ist ein übergeordnetes Element von', - 'targets milestone' => 'betrifft Meilenstein', - 'is a milestone of' => 'ist ein Meilenstein von', - 'fixes' => 'behebt', - 'is fixed by' => 'wird behoben von', - 'This task' => 'Diese Aufgabe', - '<1h' => '<1Std', - '%dh' => '%dStd', - 'Expand tasks' => 'Aufgaben aufklappen', - 'Collapse tasks' => 'Aufgaben zusammenklappen', - 'Expand/collapse tasks' => 'Aufgaben auf/zuklappen', - 'Close dialog box' => 'Dialog schließen', - 'Submit a form' => 'Formular abschicken', - 'Board view' => 'Pinnwand Ansicht', - 'Keyboard shortcuts' => 'Tastaturkürzel', - 'Open board switcher' => 'Pinnwandauswahl öffnen', - 'Application' => 'Anwendung', - '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', - 'CAD - Canadian Dollar' => 'CAD - Kanadische Dollar', - 'CHF - Swiss Francs' => 'CHF - Schweizer Franken', - 'Custom Stylesheet' => 'benutzerdefiniertes Stylesheet', - 'download' => 'Download', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Britische Pfund', - 'INR - Indian Rupee' => 'INR - Indische Rupien', - 'JPY - Japanese Yen' => 'JPY - Japanische Yen', - 'NZD - New Zealand Dollar' => 'NZD - Neuseeland-Dollar', - 'RSD - Serbian dinar' => 'RSD - Serbische Dinar', - '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.', - 'Move the task to another column when assignee is cleared' => 'Aufgabe in eine andere Spalte verschieben, wenn die Zuordnung gelöscht wurde.', - 'Source column' => 'Quellspalte', - 'Transitions' => 'Übergänge', - 'Executer' => 'Ausführender', - 'Time spent in the column' => 'Zeit in Spalte verbracht', - 'Task transitions' => 'Aufgaben-Übergänge', - 'Task transitions export' => 'Aufgaben-Übergänge exportieren', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Diese Auswertung enthält alle Spaltenbewegungen für jede Aufgabe mit Datum, Benutzer und Zeit vor jedem Wechsel.', - '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', - 'Webhook URL' => 'Webhook-URL', - '%s remove the assignee of the task %s' => '%s Zuordnung für die Aufgabe %s entfernen', - 'Enable Gravatar images' => 'Aktiviere Gravatar-Bilder', - 'Information' => 'Information', - 'Check two factor authentication code' => 'Prüfe Zwei-Faktor-Authentifizierungscode', - 'The two factor authentication code is not valid.' => 'Der Zwei-Faktor-Authentifizierungscode ist ungültig.', - 'The two factor authentication code is valid.' => 'Der Zwei-Faktor-Authentifizierungscode ist gültig.', - 'Code' => 'Code', - 'Two factor authentication' => 'Zwei-Faktor-Authentifizierung', - 'This QR code contains the key URI: ' => 'Dieser QR-Code beinhaltet die Schlüssel-URI: ', - 'Check my code' => 'Überprüfe meinen Code', - 'Secret key: ' => 'Geheimer Schlüssel: ', - 'Test your device' => 'Teste dein Gerät', - 'Assign a color when the task is moved to a specific column' => 'Weise eine Farbe zu, wenn die Aufgabe zu einer bestimmten Spalte bewegt wird', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Burndown-Diagramm für "%s"', - 'Burndown chart' => 'Burndown-Diagramm', - 'This chart show the task complexity over the time (Work Remaining).' => 'Dieses Diagramm zeigt die Aufgabenkomplexität über den Faktor Zeit (Verbleibende Arbeit).', - 'Screenshot taken %s' => 'Screenshot aufgenommen %s ', - 'Add a screenshot' => 'Screenshot hinzufügen', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Nimm einen Screenshot auf und drücke STRG+V oder ⌘+V um ihn hier einzufügen.', - 'Screenshot uploaded successfully.' => 'Screenshot erfolgreich hochgeladen.', - 'SEK - Swedish Krona' => 'SEK - Schwedische Kronen', - 'Identifier' => 'Identifikator', - 'Disable two factor authentication' => 'Deaktiviere Zwei-Faktor-Authentifizierung', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Willst du wirklich für folgenden Nutzer die Zwei-Faktor-Authentifizierung deaktivieren: "%s"?', - 'Edit link' => 'Verbindung bearbeiten', - 'Start to type task title...' => 'Beginne mit der Titeleingabe...', - 'A task cannot be linked to itself' => 'Eine Aufgabe kann nicht mit sich selber verbunden werden', - 'The exact same link already exists' => 'Diese Verbindung existiert bereits', - 'Recurrent task is scheduled to be generated' => 'Wiederkehrende Aufgabe ist zur Generierung eingeplant', - 'Score' => 'Wertung', - 'The identifier must be unique' => 'Der Schlüssel muss einzigartig sein', - 'This linked task id doesn\'t exists' => 'Die verbundene Aufgabe existiert nicht', - 'This value must be alphanumeric' => 'Der Wert muss alphanumerisch sein', - 'Edit recurrence' => 'Wiederholung bearbeiten', - 'Generate recurrent task' => 'Wiederkehrende Aufgabe generieren', - 'Trigger to generate recurrent task' => 'Auslöser für wiederkehrende Aufgabe', - 'Factor to calculate new due date' => 'Faktor zur Berechnung für neues Ablaufdatum', - 'Timeframe to calculate new due date' => 'Zeitfenster zur Berechnung für neues Ablaufdatum', - 'Base date to calculate new due date' => 'Basisdatum zur Berechnung für neues Ablaufdatum', - 'Action date' => 'Aktionsdatum', - 'Base date to calculate new due date: ' => 'Basisdatum zur Berechnung für neues Ablaufdatum: ', - 'This task has created this child task: ' => 'Diese Aufgabe hat diese Teilaufgabe erstellt: ', - 'Day(s)' => 'Tag(e)', - 'Existing due date' => 'Existierendes Ablaufdatum', - '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: ', - '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 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)', - 'Calendar settings' => 'Kalender-Einstellungen', - 'Project calendar view' => 'Projekt-Kalendarsicht', - 'Project settings' => 'Projekteinstellungen', - 'Show subtasks based on the time tracking' => 'Zeige Teilaufgaben basierend auf Zeiterfassung', - 'Show tasks based on the creation date' => 'Zeige Aufgaben basierend auf Erstelldatum', - 'Show tasks based on the start date' => 'Zeige Aufgaben basierend auf Beginndatum', - 'Subtasks time tracking' => 'Teilaufgaben-Zeiterfassung', - 'User calendar view' => 'Benutzer-Kalendersicht', - 'Automatically update the start date' => 'Beginndatum automatisch aktualisieren', - 'iCal feed' => 'iCal Feed', - 'Preferences' => 'Einstellungen', - 'Security' => 'Sicherheit', - 'Two factor authentication disabled' => 'Zwei-Faktor-Authentifizierung deaktiviert', - 'Two factor authentication enabled' => 'Zwei-Faktor-Authentifizierung aktiviert', - 'Unable to update this user.' => 'Benutzer kann nicht bearbeitet werden', - 'There is no user management for private projects.' => 'Es gibt keine Benutzerverwaltung für private Projekte', - 'User that will receive the email' => 'Empfänger der E-Mail', - 'Email subject' => 'E-Mail-Betreff', - 'Date' => 'Datum', - 'Add a comment log when moving the task between columns' => 'Kommentar hinzufügen, wenn Aufgabe in andere Spalte verschoben wird', - 'Move the task to another column when the category is changed' => 'Aufgabe in andere Spalte verschieben, wenn Kategorie geändert wird', - 'Send a task by email to someone' => 'Aufgabe per E-Mail versenden', - 'Reopen a task' => 'Aufgabe wieder öffnen', - 'Column change' => 'Spalte geändert', - 'Position change' => 'Position geändert', - 'Swimlane change' => 'Swimlane geändert', - 'Assignee change' => 'Zuordnung geändert', - '[%s] Overdue tasks' => '[%s] überfallige Aufgaben', - 'Notification' => 'Benachrichtigungen', - '%s moved the task #%d to the first swimlane' => '%s hat die Aufgabe #%d in die erste Swimlane verschoben', - '%s moved the task #%d to the swimlane "%s"' => '%s hat die Aufgabe #%d in die Swimlane "%s" verschoben', - 'Swimlane' => 'Swimlane', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s hat die Aufgabe %s in die erste Swimlane verschoben', - '%s moved the task %s to the swimlane "%s"' => '%s hat die Aufgaben %s in die Swimlane "%s" verschoben', - 'This report contains all subtasks information for the given date range.' => 'Der Bericht beinhaltet alle Teilaufgaben im gewählten Zeitraum', - 'This report contains all tasks information for the given date range.' => 'Der Bericht beinhaltet alle Aufgaben im gewählten Zeitraum', - 'Project activities for %s' => 'Projektaktivitäten für %s', - 'view the board on Kanboard' => 'Pinnwand in Kanboard anzeigen', - 'The task have been moved to the first swimlane' => 'Die Aufgabe wurde in die erste Swimlane verschoben', - 'The task have been moved to another swimlane:' => 'Die Aufgaben wurde in eine andere Swimlane verschoben:', - 'New title: %s' => 'Neuer Titel: %s', - 'The task is not assigned anymore' => 'Die Aufgabe ist nicht mehr zugewiesen', - 'New assignee: %s' => 'Neue Zuordnung: %s', - 'There is no category now' => 'Es gibt keine Kategorie im Moment', - 'New category: %s' => 'Neue Kategorie: %s', - 'New color: %s' => 'Neue Farbe: %s', - 'New complexity: %d' => 'Neue Komplexität: %d', - 'The due date have been removed' => 'Das Ablaufdatum wurde entfernt', - 'There is no description anymore' => 'Es gibt keine Beschreibung mehr', - 'Recurrence settings have been modified' => 'Die Einstellungen für Wiederholung wurden geändert', - 'Time spent changed: %sh' => 'Verbrauchte Zeit geändert: %sh', - 'Time estimated changed: %sh' => 'Geschätzte Zeit geändert: %sh', - 'The field "%s" have been updated' => 'Das Feld "%s" wurde verändert', - 'The description has been modified:' => 'Die Beschreibung wurde geändert:', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Soll die Aufgabe "%s" wirklich geschlossen werden? (einschließlich Teilaufgaben)', - 'I want to receive notifications for:' => 'Ich möchte Benachrichtigungen erhalten für:', - 'All tasks' => 'Alle Aufgaben', - 'Only for tasks assigned to me' => 'nur mir zugeordnete Aufgane', - 'Only for tasks created by me' => 'nur von mir erstellte Aufgaben', - 'Only for tasks created by me and assigned to me' => 'nur mir zugeordnete und von mir erstellte Aufgaben', - '%%Y-%%m-%%d' => '%%d.%%m.%%Y', - 'Total for all columns' => 'Gesamt für alle Spalten', - 'You need at least 2 days of data to show the chart.' => 'Es werden mindestens 2 Tage zur Darstellung benötigt', - '<15m' => '<15min', - '<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', - 'Reset filters' => 'Filter zurücksetzen', - 'My tasks due tomorrow' => 'Meine morgen fälligen Aufgaben', - 'Tasks due today' => 'Heute fällige Aufgaben', - 'Tasks due tomorrow' => 'Morgen fällige Aufgaben', - 'Tasks due yesterday' => 'Gestern fällige Aufgaben', - 'Closed tasks' => 'Abgeschlossene Aufgaben', - 'Open tasks' => 'Offene Aufgaben', - 'Not assigned' => 'Nicht zugewiesen', - 'View advanced search syntax' => 'Zur erweiterten Suchsyntax', - 'Overview' => 'Überblick', - 'Board/Calendar/List view' => 'Board-/Kalender-/Listen-Ansicht', - 'Switch to the board view' => 'Zur Board-Ansicht', - 'Switch to the calendar view' => 'Zur Kalender-Ansicht', - 'Switch to the list view' => 'Zur Listen-Ansicht', - 'Go to the search/filter box' => 'Zum Such- und Filterfeld', - 'There is no activity yet.' => 'Es gibt bislang keine Aktivitäten.', - 'No tasks found.' => 'Keine Aufgaben gefunden.', - 'Keyboard shortcut: "%s"' => 'Tastaturkürzel: "%s"', - 'List' => 'Liste', - 'Filter' => 'Filter', - 'Advanced search' => 'Fortgeschrittene Suche', - 'Example of query: ' => 'Beispiel einer Abfrage: ', - 'Search by project: ' => 'Suche nach Projekt: ', - 'Search by column: ' => 'Suche nach Spalte: ', - 'Search by assignee: ' => 'Suche nach zugeordnetem Benutzer: ', - 'Search by color: ' => 'Suche nach Farbe: ', - 'Search by category: ' => 'Suche nach Kategorie: ', - 'Search by description: ' => 'Suche nach Beschreibung: ', - 'Search by due date: ' => 'Suche nach Fälligkeitsdatum: ', - 'Lead and Cycle time for "%s"' => 'Durchlauf und Zykluszeit für "%s"', - 'Average time spent into each column for "%s"' => 'Durchschnittliche Zeit in jeder Spalte für "%s"', - 'Average time spent into each column' => 'Durchschnittszeit in jeder Spalte', - 'Average time spent' => 'Durchschnittlicher Zeitverbrauch', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Dieses Diagramm zeigt die durchschnittliche Zeit in jeder Spalte der letzten %d Aufgaben.', - 'Average Lead and Cycle time' => 'Durchschnittliche Zyklus- und Durchlaufzeit', - 'Average lead time: ' => 'Durchschnittliche Durchlaufzeit: ', - 'Average cycle time: ' => 'Durchschnittliche Zykluszeit: ', - 'Cycle Time' => 'Zykluszeit', - 'Lead Time' => 'Durchlaufzeit', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Das Diagramm zeigt die durchschnittliche Durchlauf- und Zykluszeit der letzten %d Aufgaben über die Zeit an.', - 'Average time into each column' => 'Durchschnittzeit in jeder Spalte', - 'Lead and cycle time' => 'Durchlauf- und Zykluszeit', - 'Lead time: ' => 'Durchlaufzeit: ', - 'Cycle time: ' => 'Zykluszeit: ', - 'Time spent into each column' => 'zeit verbracht in jeder Spalte', - 'The lead time is the duration between the task creation and the completion.' => 'Die Durchlaufzeit ist die Dauer zwischen Erstellung und Fertigstellung.', - 'The cycle time is the duration between the start date and the completion.' => 'Die Zykluszeit ist die Dauer zwischen Start und Fertigstellung.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Wenn die Aufgabe nicht geschlossen ist, wird die aktuelle Zeit statt der Fertigstellung verwendet.', - 'Set automatically the start date' => 'Setze Startdatum automatisch', - 'Edit Authentication' => 'Authentifizierung bearbeiten', - '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.', - 'Trigger automatically subtask time tracking' => 'Teilaufgaben Zeiterfassung automatisch starten', - 'Include closed tasks in the cumulative flow diagram' => 'Geschlossen Aufgaben ins kumulative Flussdiagramm einschließen', - 'Current swimlane: %s' => 'Aktuelle Swimlane: %s', - 'Current column: %s' => 'Aktuelle Spalte: %s', - 'Current category: %s' => 'Aktuelle Kategorie: %s', - 'no category' => 'keine Kategorie', - 'Current assignee: %s' => 'Aktuelle Zuordnung: %s', - 'not assigned' => 'nicht zugeordnet', - 'Author:' => 'Autor:', - 'contributors' => 'Mitwirkende', - 'License:' => 'Lizenz:', - 'License' => 'Lizenz', - 'Enter the text below' => 'Text unten eingeben', - 'Gantt chart for %s' => 'Gantt Diagramm für %s', - 'Sort by position' => 'Nach Position sortieren', - 'Sort by date' => 'Nach Datum sortieren', - 'Add task' => 'Aufgabe hinzufügen', - 'Start date:' => 'Startdatum:', - 'Due date:' => 'Ablaufdatum:', - 'There is no start date or due date for this task.' => 'Diese Aufgabe hat kein Start oder Ablaufdatum.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Aufgabe verschieben/ändern, ändert auch Start- und Ablaufdatum der Aufgabe.', - 'There is no task in your project.' => 'Es gibt keine Aufgabe in deinem Projekt', - 'Gantt chart' => 'Gantt Diagramm', - 'People who are project managers' => 'Benutzer die Projektmanager sind', - 'People who are project members' => 'Benutzer die Projektmitglieder sind', - 'NOK - Norwegian Krone' => 'NOK - Norwegische Kronen', - 'Show this column' => 'Spalte anzeigen', - 'Hide this column' => 'Spalte verstecken', - 'open file' => 'Datei öffnen', - 'End date' => 'Endedatum', - 'Users overview' => 'Benutzerübersicht', - 'Members' => 'Mitglieder', - 'Shared project' => 'Geteiltes Projekt', - 'Project managers' => 'Projektmanager', - 'Gantt chart for all projects' => 'Gantt Diagramm für alle Projekte', - 'Projects list' => 'Projektliste', - 'Gantt chart for this project' => 'Gantt Diagramm für dieses Projekt', - 'Project board' => 'Projekt Pinnwand', - 'End date:' => 'Endedatum:', - 'There is no start date or end date for this project.' => 'Es gibt kein Startdatum oder Endedatum für dieses Projekt', - 'Projects Gantt chart' => 'Projekt Gantt Diagramm', - 'Change task color when using a specific task link' => 'Aufgabefarbe ändern bei bestimmter Aufgabenverbindung', - 'Task link creation or modification' => 'Aufgabenverbindung erstellen oder bearbeiten', - 'Milestone' => 'Meilenstein', - 'Documentation: %s' => 'Dokumentation: %s', - 'Switch to the Gantt chart view' => 'Zur Gantt-Diagramm Ansicht wechseln', - 'Reset the search/filter box' => 'Suche/Filter-Box zurücksetzen', - 'Documentation' => 'Dokumentation', - 'Table of contents' => 'Inhaltsverzeichnis', - 'Gantt' => 'Gantt', - 'Author' => 'Autor', - 'Version' => 'Version', - 'Plugins' => 'Plugins', - 'There is no plugin loaded.' => 'Es ist kein Plugin geladen.', - 'Set maximum column height' => 'Setze maximale Spaltenhöhe', - 'Remove maximum column height' => 'Entferne maximale Spaltenhöhe', - 'My notifications' => 'Meine Benachrichtigungen', - 'Custom filters' => 'Benutzerdefinierte Filter', - 'Your custom filter have been created successfully.' => 'Benutzerdefinierten Filter erfolgreich erstellt.', - 'Unable to create your custom filter.' => 'Benutzerdefinierter Filter konnte nicht erstellt werden.', - 'Custom filter removed successfully.' => 'Benutzerdefinierten Filter erfolgreich entfernt.', - 'Unable to remove this custom filter.' => 'Benutzerdefinierten Filter konnte nicht entfernt werden.', - 'Edit custom filter' => 'Benutzerdefinierten Filter bearbeiten', - 'Your custom filter have been updated successfully.' => 'Benutzerdefinierten Filter erfolgreich bearbeitet.', - 'Unable to update custom filter.' => 'Benutzerdefinierter Filter konnte nicht geändert werden.', - 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Neuer Anhang für Aufgabe #%d: %s', - 'New comment on task #%d' => 'Neuer Kommentar für Aufgabe #%d', - 'Comment updated on task #%d' => 'Kommentar geändert für Aufgabe #%d', - 'New subtask on task #%d' => 'Neue Teilaufgabe für Aufgabe #%d', - 'Subtask updated on task #%d' => 'Teilaufgabe geändert für Aufgabe #%d', - 'New task #%d: %s' => 'Neue Aufgabe #%d: %s', - 'Task updated #%d' => 'Aufgabe bearbeitet #%d', - 'Task #%d closed' => 'Aufgabe #%d geschlossen', - 'Task #%d opened' => 'Aufgabe #%d eröffnet', - 'Column changed for task #%d' => 'Spalte geändert von Aufgabe #%d', - 'New position for task #%d' => 'Neue Position für Aufgabe #%d', - 'Swimlane changed for task #%d' => 'Neue Swimlane für Aufgabe #%d', - 'Assignee changed on task #%d' => 'Neue Zuordnung für Aufgabe #%d ', - '%d overdue tasks' => '%d überfällige Aufgaben', - 'Task #%d is overdue' => 'Aufgabe #%d ist überfällig', - 'No new notifications.' => 'Keine neuen Benachrichtigungen', - 'Mark all as read' => 'Alles als gelesen markieren', - 'Mark as read' => 'Als gelesen markieren', - 'Total number of tasks in this column across all swimlanes' => 'Anzahl an Aufgaben in dieser Spalte über alle Swimlanes', - 'Collapse swimlane' => 'Swimlane einklappen', - 'Expand swimlane' => 'Swimlane ausklappen', - 'Add a new filter' => 'Neuen Filter hinzufügen', - 'Share with all project members' => 'Mit allen Projektmitgliedern teilen.', - 'Shared' => 'Geteilt', - '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!', - 'Import users from CSV file' => 'Importiere Benutzer aus CSV Datei', - '%d user(s) have been imported successfully.' => '%d Benutzer wurde(n) erfolgreich importiert.', - 'Comma' => 'Komma', - 'Semi-colon' => 'Semikolon', - 'Tab' => 'Tabulator', - 'Vertical bar' => 'senkrechter Strich', - 'Double Quote' => 'Doppelte Anführungszeichen', - 'Single Quote' => 'Einfache Anführungszeichen', - '%s attached a file to the task #%d' => '%s hat eine Datei zur Aufgabe #%d hinzugefügt', - 'There is no column or swimlane activated in your project!' => 'Es ist keine Spalte oder Swimlane in Ihrem Projekt aktiviert!', - 'Append filter (instead of replacement)' => 'Filter anhängen (statt zu ersetzen)', - 'Append/Replace' => 'Anhängen/Ersetzen', - 'Append' => 'Anhängen', - 'Replace' => 'Ersetzen', - 'Import' => 'Import', - 'change sorting' => 'Sortierung ändern', - 'Tasks Importation' => 'Aufgaben Import', - 'Delimiter' => 'Trennzeichen', - 'Enclosure' => 'Textbegrenzer', - 'CSV File' => 'CSV Datei', - 'Instructions' => 'Anweisungen', - 'Your file must use the predefined CSV format' => 'Ihre Datei muss das vorgegebene CSV Format haben', - 'Your file must be encoded in UTF-8' => 'Ihre Datei muss UTF-8 kodiert sein', - 'The first row must be the header' => 'Die erste Zeile muss die Kopfzeile sein', - 'Duplicates are not verified for you' => 'Duplikate werden nicht für Sie geprüft', - 'The due date must use the ISO format: YYYY-MM-DD' => 'Das Fälligkeitsdatum muss das ISO Format haben: YYYY-MM-DD', - 'Download CSV template' => 'CSV Vorlage herunterladen', - 'No external integration registered.' => 'Keine externe Integration registriert', - 'Duplicates are not imported' => 'Duplikate wurden nicht importiert', - 'Usernames must be lowercase and unique' => 'Benutzernamen müssen in Kleinbuschstaben und eindeutig sein', - 'Passwords will be encrypted if present' => 'Passwörter werden verschlüsselt wenn vorhanden', - '%s attached a new file to the task %s' => '%s hat eine neue Datei zur Aufgabe %s hinzufgefügt', - 'Link type' => 'Verbindungstyp', - 'Assign automatically a category based on a link' => 'Linkbasiert eine Kategorie automatisch zuordnen', - 'BAM - Konvertible Mark' => 'BAM - Konvertible Mark', - 'Assignee Username' => 'Benutzername des Zuständigen', - 'Assignee Name' => 'Name des Zuständigen', - 'Groups' => 'Gruppen', - 'Members of %s' => 'Mitglied von %s', - 'New group' => 'Neue Gruppe', - 'Group created successfully.' => 'Gruppe erfolgreich angelegt.', - 'Unable to create your group.' => 'Gruppe konnte nicht angelegt werden', - 'Edit group' => 'Gruppe bearbeiten', - 'Group updated successfully.' => 'Gruppe erfolgreich aktualisiert', - 'Unable to update your group.' => 'Gruppe konnte nicht aktualisiert werden', - 'Add group member to "%s"' => 'Gruppenmitglied zu "%s" hinzufügen', - 'Group member added successfully.' => 'Gruppenmitglied erfolgreich hinzugefügt', - 'Unable to add group member.' => 'Gruppenmitglied konnte nicht hinzugefügt werden.', - 'Remove user from group "%s"' => 'Benutzer aus Gruppe "%s" löschen', - 'User removed successfully from this group.' => 'Benutzer erfolgreich aus dieser Gruppe gelöscht.', - 'Unable to remove this user from the group.' => 'Benutzer konnte nicht aus dieser Gruppe gelöscht werden.', - 'Remove group' => 'Gruppe löschen', - 'Group removed successfully.' => 'Gruppe erfolgreich gelöscht.', - 'Unable to remove this group.' => 'Gruppe konnte nicht gelöscht werden.', - 'Project Permissions' => 'Projekt Berechtigungen', - 'Manager' => 'Manager', - 'Project Manager' => 'Projekt Manager', - 'Project Member' => 'Projekt Mitglied', - 'Project Viewer' => 'Projekt Betrachter', - 'Your account is locked for %d minutes' => 'Ihr Zugang wurde für %d Minuten gesperrt', - 'Invalid captcha' => 'Ungültiges Captcha', - 'The name must be unique' => 'Der Name muss eindeutig sein', - 'View all groups' => 'Alle Gruppen anzeigen', - 'View group members' => 'Gruppenmitglieder anzeigen', - 'There is no user available.' => 'Es ist kein Benutzer verfügbar.', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Wollen Sie den Benutzer "%s" wirklich aus der Gruppe "%s" löschen?', - 'There is no group.' => 'Es gibt keine Gruppe.', - 'External Id' => 'Externe ID', - 'Add group member' => 'Gruppenmitglied hinzufügen', - 'Do you really want to remove this group: "%s"?' => 'Wollen Sie die Gruppe "%s" wirklich löschen?', - 'There is no user in this group.' => 'Es gibt keinen Benutzer in dieser Gruppe.', - 'Remove this user' => 'Diesen Benutzer entfernen', - 'Permissions' => 'Berechtigungen', - 'Allowed Users' => 'Berechtigte Benutzer', - 'No user have been allowed specifically.' => 'Keine Benutzer mit ausdrücklicher Berechtigung.', - 'Role' => 'Rolle', - 'Enter user name...' => 'Geben Sie den Benutzernamem ein...', - 'Allowed Groups' => 'Berechtigte Gruppen', - 'No group have been allowed specifically.' => 'Keine Gruppen mit ausdrücklicher Berechtigung.', - 'Group' => 'Gruppe', - 'Group Name' => 'Gruppenname', - 'Enter group name...' => 'Geben Sie den Gruppennamen ein...', - 'Role:' => 'Rolle:', - 'Project members' => 'Projektmitglieder', - 'Compare hours for "%s"' => 'Vergleich der Stunden für %s', - '%s mentioned you in the task #%d' => '%s erwähnte Sie in Aufgabe #%d', - '%s mentioned you in a comment on the task #%d' => '%s erwähnte Sie in einem Kommentar zur Aufgabe #%d', - 'You were mentioned in the task #%d' => 'Sie wurden in der Aufgabe #%d erwähnt', - 'You were mentioned in a comment on the task #%d' => 'Sie wurden in einem Kommentar zur Aufgabe #%d erwähnt', - 'Mentioned' => 'Erwähnt', - 'Compare Estimated Time vs Actual Time' => 'Vergleich zwischen erwartetem und tatsächlichem Zeitaufwand', - 'Estimated hours: ' => 'Erwarteter Zeitaufwand (Stunden): ', - 'Actual hours: ' => 'Tatsächlich aufgewändete Stunden: ', - 'Hours Spent' => 'Stunden aufgewändet', - 'Hours Estimated' => 'Stunden erwartet', - 'Estimated Time' => 'Erwartete Zeit', - 'Actual Time' => 'Aktuelle Zeit', - 'Estimated vs actual time' => 'Erwarteter vs. tatsächlicher Zeitaufwand', - 'RUB - Russian Ruble' => 'Russischer Rubel', - 'Assign the task to the person who does the action when the column is changed' => 'Aufgabe der Person zuordnen, die die Aktion durchführt, wenn die Spalte geändert wird', - 'Close a task in a specific column' => 'Schliesse eine Aufgabe in einer bestimmten Spalte', - 'Time-based One-time Password Algorithm' => 'Zeitbasierter Einmalpasswort Algorithmus', - 'Two-Factor Provider: ' => '2FA Anbieter: ', - 'Disable two-factor authentication' => 'Zwei-Faktor-Authentifizierung deaktivieren', - 'Enable two-factor authentication' => 'Zwei-Faktor-Authentifizierung aktivieren', - 'There is no integration registered at the moment.' => 'Derzeit ist kein externer Dienst registriert.', - 'Password Reset for Kanboard' => 'Zurücksetzen des Passwortes für Kanboard', - 'Forgot password?' => 'Passwort vergessen?', - 'Enable "Forget Password"' => 'Passwortrücksetzung aktivieren', - 'Password Reset' => 'Passwort zurücksetzen', - 'New password' => 'Neues Passwort', - 'Change Password' => 'Passwort ändern', - 'To reset your password click on this link:' => 'Bitte auf den Link klicken, um Ihr Passwort zurückzusetzen.', - 'Last Password Reset' => 'Verlauf der Passwortrücksetzung', - 'The password has never been reinitialized.' => 'Das Passwort wurde noch nie zurückgesetzt.', - 'Creation' => 'Erstellung', - 'Expiration' => 'Ablauf', - 'Password reset history' => 'Verlauf Passwortrücksetzung', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Alle Aufgaben der Spalte "%s" und der Swimlane "%s" wurden erfolgreich geschlossen', - 'Do you really want to close all tasks of this column?' => 'Wollen Sie wirklich alle Aufgaben in dieser Spalte schließen?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d Aufgabe(n) in der Spalte "%s" und in der Swimlane "%s" werden geschlossen.', - 'Close all tasks of this column' => 'Alle Aufgaben in dieser Spalte schließen', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Kein Plugin hat eine Projekt-Benachrichtigungsmethode registriert. Sie können individuelle Meldungen in Ihrem Benutzerprofil konfigurieren', - 'My dashboard' => 'Mein Dashboard', - 'My profile' => 'Mein Profil', - 'Project owner: ' => 'Projekt-Besitzer: ', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Die Projekt-Kennung ist optional und muss alphanumerisch sein, beispielsweise: MYPROJECT.', - 'Project owner' => 'Projekt-Besitzer', - 'Those dates are useful for the project Gantt chart.' => 'Diese Daten sind nützlich für das Gantt-Diagramm.', - 'Private projects do not have users and groups management.' => 'Private Projekte haben kein Benutzer- und Gruppen-Management.', - 'There is no project member.' => 'Es gibt kein Projekt-Mitglied.', - 'Priority' => 'Priorität', - 'Task priority' => 'Aufgaben-Priorität', - 'General' => 'Allgemein', - 'Dates' => 'Daten', - 'Default priority' => 'Standard-Priorität', - 'Lowest priority' => 'Niedrigste Priorität', - 'Highest priority' => 'Höchste Priorität', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Wenn Sie Null bei höchster und niedrigster Priorität eintragen, wird diese Funktion deaktiviert.', - 'Close a task when there is no activity' => 'Schliesse eine Aufgabe, wenn keine Aktivitäten vorhanden sind', - 'Duration in days' => 'Dauer in Tagen', - 'Send email when there is no activity on a task' => 'Versende eine Email, wenn keine Aktivitäten an einer Aufgabe vorhanden sind', - 'Unable to fetch link information.' => 'Kann keine Informationen über Verbindungen holen', - 'Daily background job for tasks' => 'Tägliche Hintergrundarbeit für Aufgaben', - 'Auto' => 'Auto', - 'Related' => 'Verbunden', - 'Attachment' => 'Anhang', - 'Title not found' => 'Titel nicht gefunden', - 'Web Link' => 'Weblink', - 'External links' => 'Externe Verbindungen', - 'Add external link' => 'Externe Verbindung hinzufügen', - 'Type' => 'Typ', - 'Dependency' => 'Abhängigkeit', - 'Add internal link' => 'Interne Verbindung hinzufügen', - 'Add a new external link' => 'Füge eine neue externe Verbindung hinzu', - 'Edit external link' => 'Externe Verbindung bearbeiten', - 'External link' => 'Externe Verbindung', - 'Copy and paste your link here...' => 'Kopieren Sie Ihren Link hier...', - 'URL' => 'URL', - 'Internal links' => 'Interne Verbindungen', - 'Assign to me' => 'Mir zuweisen', - 'Me' => 'Mich', - 'Do not duplicate anything' => 'Nichts duplizieren', - 'Projects management' => 'Projektmanagement', - 'Users management' => 'Benutzermanagement', - 'Groups management' => 'Gruppenmanagement', - 'Create from another project' => 'Von einem anderen Projekt erstellen', - 'open' => 'offen', - 'closed' => 'geschlossen', - 'Priority:' => 'Priorität:', - 'Reference:' => 'Bezug:', - 'Complexity:' => 'Komplexität:', - 'Swimlane:' => 'Swimlane:', - 'Column:' => 'Spalte:', - 'Position:' => 'Position:', - 'Creator:' => 'Ersteller:', - 'Time estimated:' => 'Geschätzte Zeit:', - '%s hours' => '%s Stunden', - 'Time spent:' => 'Aufgewendete Zeit:', - 'Created:' => 'Erstellt:', - 'Modified:' => 'Geändert:', - 'Completed:' => 'Abgeschlossen:', - 'Started:' => 'Gestarted:', - 'Moved:' => 'Verschoben:', - 'Task #%d' => 'Aufgabe #%d', - 'Date and time format' => 'Datums- und Zeitformat', - 'Time format' => 'Zeitformat', - 'Start date: ' => 'Anfangsdatum: ', - 'End date: ' => 'Enddatum: ', - 'New due date: ' => 'Neues Fälligkeitsdatum: ', - 'Start date changed: ' => 'Anfangsdatum geändert: ', - 'Disable private projects' => 'Private Projekte deaktivieren', - 'Do you really want to remove this custom filter: "%s"?' => 'Wollen Sie diesen benutzerdefinierten Filter wirklich entfernen: "%s"?', - 'Remove a custom filter' => 'Benutzerdefinierten Filter entfernen', - 'User activated successfully.' => 'Benutzer erfolgreich aktiviert.', - 'Unable to enable this user.' => 'Dieser Benutzer kann nicht aktiviert werden.', - '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', - 'Two Factor' => 'Zwei-Faktor', - 'Disable user' => 'Benutzer deaktivieren', - 'Do you really want to disable this user: "%s"?' => 'Wollen Sie diesen Benutzer wirklich deaktivieren: "%s"?', - 'Enable user' => 'Benutzer aktivieren', - 'Do you really want to enable this user: "%s"?' => 'Wollen Sie diesen Benutzer wirklich aktivieren: "%s"?', - 'Download' => 'Runterladen', - 'Uploaded: %s' => 'Heraufgeladen: %s', - 'Size: %s' => 'Größe: %s', - 'Uploaded by %s' => 'Heraufgeladen von %s', - 'Filename' => 'Dateiname', - 'Size' => 'Größe', - 'Column created successfully.' => 'Spalte erfolgreich erstellt.', - 'Another column with the same name exists in the project' => 'Es gibt bereits eine Spalte mit demselben Namen im Projekt', - 'Default filters' => 'Standard-Filter', - 'Your board doesn\'t have any columns!' => 'Es gibt keine Spalten in diesem Projekt!', - 'Change column position' => 'Position der Spalte ändern', - 'Switch to the project overview' => 'Zur Projektübersicht wechseln', - 'User filters' => 'Benutzer-Filter', - 'Category filters' => 'Kategorie-Filter', - 'Upload a file' => 'Eine Datei hochladen', - 'View file' => 'Datei ansehen', - 'Last activity' => 'Letzte Aktivität', - 'Change subtask position' => 'Position der Unteraufgabe ändern', - 'This value must be greater than %d' => 'Dieser Wert muss größer als %d sein', - 'Another swimlane with the same name exists in the project' => 'Es gibt bereits eine Swimlane mit diesem Namen im Projekt', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Beispiel: http://example.kanboard.net (wird zum Erstellen absoluter URLs genutzt)', - 'Actions duplicated successfully.' => 'Aktionen erfolgreich dupliziert', - 'Unable to duplicate actions.' => 'Aktionen können nicht dupliziert werden.', - 'Add a new action' => 'Neue Aktion hinzufügen', - 'Import from another project' => 'Von einem anderen Projekt importieren', - 'There is no action at the moment.' => 'Es gibt zur Zeit keine Aktionen.', - 'Import actions from another project' => 'Aktionen von einem anderen Projekt importieren', - 'There is no available project.' => 'Es ist kein Projekt verfügbar.', - 'Local File' => 'Lokale Datei', - 'Configuration' => 'Konfiguration', - 'PHP version:' => 'PHP Version:', - 'PHP SAPI:' => 'PHP SAPI:', - 'OS version:' => 'OS Version:', - 'Database version:' => 'Datenbank Version:', - 'Browser:' => 'Browser:', - 'Task view' => 'Aufgaben Ansicht', - 'Edit task' => 'Aufgabe bearbeiten', - 'Edit description' => 'Beschreibung bearbeiten', - 'New internal link' => 'Neue interne Verbindung', - 'Display list of keyboard shortcuts' => 'Liste der Tastaturkürzel anzeigen', - 'Menu' => 'Menü', - 'Set start date' => 'Anfangsdatum setzen', - 'Avatar' => 'Avatar', - 'Upload my avatar image' => 'Mein Avatar Bild hochladen', - 'Remove my image' => 'Mein Bild entfernen', - 'The OAuth2 state parameter is invalid' => 'Der OAuth2 Statusparameter ist ungültig', - 'User not found.' => 'Benutzer nicht gefunden', - 'Search in activity stream' => 'Im Aktivitätenstrom suchen', - 'My activities' => 'Meine Aktivitäten', - 'Activity until yesterday' => 'Aktivitäten bis gestern', - 'Activity until today' => 'Aktivitäten bis heute', - 'Search by creator: ' => 'nach Ersteller suchen:', - 'Search by creation date: ' => 'nach Datum suchen:', - 'Search by task status: ' => 'nach Aufgabenstatus suchen:', - 'Search by task title: ' => 'nach Titel suchen:', - 'Activity stream search' => 'Im Aktivitätenstrom suchen', - 'Projects where "%s" is manager' => 'Projekte in denen "%s" Manager ist', - 'Projects where "%s" is member' => 'Projekte in denen "%s" Mitglied ist', - 'Open tasks assigned to "%s"' => 'Offene Aufgaben, die "%s" zugeteilt sind', - 'Closed tasks assigned to "%s"' => 'Geschlossene Aufgaben, die "%s" zugeteilt sind', - 'Assign automatically a color based on a priority' => 'Eine Farbe basierend auf einer Priorität automatisch zuordnen', - 'Overdue tasks for the project(s) "%s"' => 'Überfällige Aufgaben des/der Projekt/e "%s"', - 'Upload files' => 'Dateien hochladen', - 'Installed Plugins' => 'Installierte Plugins', - 'Plugin Directory' => 'Plugin Verzeichnis', - 'Plugin installed successfully.' => 'Plugin erfolgreich installiert.', - 'Plugin updated successfully.' => 'Plugin erfolgreich aktualisiert.', - 'Plugin removed successfully.' => 'Plugin erfolgreich entfernt.', - 'Subtask converted to task successfully.' => 'Teilaufgabe erfolgreich in Aufgabe umgewandelt.', - 'Unable to convert the subtask.' => 'Teilaufgabe kann nicht umgewandelt werden.', - 'Unable to extract plugin archive.' => 'Plugin Archiv kann nicht entpackt werden.', - 'Plugin not found.' => 'Plugin nicht gefunden.', - 'You don\'t have the permission to remove this plugin.' => 'Sie dürfen dieses Plugin nicht entfernen.', - 'Unable to download plugin archive.' => 'Plugin Archiv kann nicht herunter geladen werden.', - 'Unable to write temporary file for plugin.' => 'Temporäre Dateien für das Plugin können nicht geschrieben werden.', - 'Unable to open plugin archive.' => 'Kann das Plugin Archiv nicht öffenen.', - 'There is no file in the plugin archive.' => 'Es gibt keine Datei im Plugin Archiv.', - 'Create tasks in bulk' => 'Viele Aufgaben auf einmal erstellen', - 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'Ihre Kanboard Installation ist nicht dafür konfiguriert, Plugins mit dem Benutzerinterface zu installieren.', - 'There is no plugin available.' => 'Es gibt kein Plugin.', - 'Install' => 'Installieren', - 'Update' => 'Aktualisieren', - 'Up to date' => 'Aktuell', - 'Not available' => 'Nicht verfügbar', - 'Remove plugin' => 'Plugin entfernen', - 'Do you really want to remove this plugin: "%s"?' => 'Wollen Sie das Plugin "%s" wirklich entfernen?', - 'Uninstall' => 'Deinstallieren', - 'Listing' => 'Auflistung', - 'Metadata' => 'Metadaten', - 'Manage projects' => 'Projekte verwalten', - 'Convert to task' => 'In Aufgabe umwandeln', - 'Convert sub-task to task' => 'Teilaufgabe in Aufgabe umwandeln', - 'Do you really want to convert this sub-task to a task?' => 'Wollen Sie diese Teilaufgabe wirklich in eine Aufgabe umwandeln?', - 'My task title' => 'Mein Aufgabentitel', - 'Enter one task by line.' => 'Geben Sie eine Aufgabe pro Zeile ein.', - 'Number of failed login:' => 'Anzahl fehlgeschlagener Anmeldungen:', - 'Account locked until:' => 'Konto gesperrt bis:', - 'Email settings' => 'E-Mail Einstellungen', - '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.', - 'Tag updated successfully.' => 'Schlagwort erfolgreich aktualisiert.', - 'Unable to update this tag.' => 'Das Schlagwort kann nicht aktualisiert werden.', - 'Tag removed successfully.' => 'Schlagwort erfolgreich entfernt.', - 'Unable to remove this tag.' => 'Das Schlagwort kann nicht entfernt werden.', - 'Global tags management' => 'Globales Schlagwort-Management', - 'Tags' => 'Schlagworte', - 'Tags management' => 'Schlagwort-Management', - 'Add new tag' => 'Neues Schlagwort hinzufügen', - 'Edit a tag' => 'Schlagwort bearbeiten', - 'Project tags' => 'Projektbezogene Schlagwörter', - 'There is no specific tag for this project at the moment.' => 'Es gibt zur Zeit kein spezifisches Schlagwort.', - 'Tag' => 'Schlagwort', - 'Remove a tag' => 'Schlagwort entfernen', - 'Do you really want to remove this tag: "%s"?' => 'Soll dieses Schlagwort wirklich entfernt werden: "%s"?', - 'Global tags' => 'Globale Schlagwörter', - 'There is no global tag at the moment.' => 'Es gibt zur Zeit kein globales Schlagwort', - // 'This field cannot be empty' => '', -); diff --git a/sources/app/Locale/el_GR/translations.php b/sources/app/Locale/el_GR/translations.php deleted file mode 100644 index d4c5504..0000000 --- a/sources/app/Locale/el_GR/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'Τίποτα', - 'edit' => 'Διορθωτής', - 'Edit' => 'Διόρθωση', - 'remove' => 'αφαιρετής', - 'Remove' => 'Αφαίρεση', - 'Yes' => 'Ναι', - 'No' => 'Όχι', - 'cancel' => 'ακύρωση', - 'or' => 'ή', - 'Yellow' => 'Κίτρινο', - 'Blue' => 'Μπλέ', - 'Green' => 'Πράσινο', - 'Purple' => 'Βιολετί', - 'Red' => 'Κόκκινο', - 'Orange' => 'Πορτοκαλί', - 'Grey' => 'Γκρίζο', - 'Brown' => 'Καφέ', - 'Deep Orange' => 'Βαθύ πορτοκαλί', - 'Dark Grey' => 'Βαθύ γκρί', - 'Pink' => 'Ρόζ', - 'Teal' => 'Τυρκουάζ', - 'Cyan' => 'Γαλάζιο', - 'Lime' => 'Λεμονί', - 'Light Green' => 'Ανοιχτό πράσινο', - 'Amber' => 'Κεχριμπαρί', - 'Save' => 'Αποθήκευση', - 'Login' => 'Είσοδος', - 'Official website:' => 'Επίσημο web site:', - 'Unassigned' => 'Μη εκχωρημένο', - 'View this task' => 'Προβολή της εργασίας', - 'Remove user' => 'Αφαίρεση χρήστη', - 'Do you really want to remove this user: "%s"?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό τον χρήστη: « %s » ?', - 'All users' => 'Όλοι οι χρήστες', - 'Username' => 'Όνομα χρήστη', - 'Password' => 'Κωδικός', - 'Administrator' => 'Διαχειριστής', - 'Sign in' => 'Είσοδος', - 'Users' => 'Χρήστες', - 'No user' => 'Δεν υπάρχει χρήστης', - 'Forbidden' => 'Δεν επιτρέπεται η πρόσβαση', - 'Access Forbidden' => 'Δεν επιτρέπεται η πρόσβαση', - 'Edit user' => 'Διόρθωση χρήστη', - 'Logout' => 'Αποσύνδεση', - 'Bad username or password' => 'Λάθος όνομα χρήστη ή κωδικού πρόσβασης', - 'Edit project' => 'Διόρθωση έργου', - 'Name' => 'Όνομα', - 'Projects' => 'Έργα', - 'No project' => 'Δεν υπάρχουν μέλη για το έργο', - 'Project' => 'Έργο', - 'Status' => 'Κατάσταση', - 'Tasks' => 'Εργασίες', - 'Board' => 'Κεντρικός πίνακας έργου', - 'Actions' => 'Ενέργειες', - 'Inactive' => 'Ανενεργός', - 'Active' => 'Ενεργός', - '%d tasks on the board' => '%d εργασίες στον κεντρικό πίνακα έργου', - '%d tasks in total' => '%d εργασιών στο σύνολο', - 'Unable to update this board.' => 'Αδύνατη η ενημέρωση αυτού του πίνακα', - 'Edit board' => 'Ενημέρωση πίνακα', - 'Disable' => 'Απενεργοποίηση', - 'Enable' => 'Ενεργοποίηση', - 'New project' => 'Νέο έργο', - 'Do you really want to remove this project: "%s"?' => 'Αφαίρεση του έργου: « %s » ?', - 'Remove project' => 'Αφαίρεση του έργου', - 'Edit the board for "%s"' => 'Διόρθωση πίνακα από « %s »', - 'All projects' => 'Όλα τα έργα', - 'Add a new column' => 'Πρόσθήκη στήλης', - 'Title' => 'Τίτλος', - 'Assigned to %s' => 'Ανατιθεμένο στον %s', - 'Remove a column' => 'Αφαίρεση στήλης', - 'Remove a column from a board' => 'Αφαίρεση στήλης από τον πίνακα', - 'Unable to remove this column.' => 'Αδύνατη η αφαίρεση της στήλης', - 'Do you really want to remove this column: "%s"?' => 'Θέλετε να αφαιρέσετε τη στήλη: « %s » ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Αυτή η ενέργεια θα ΑΦΑΙΡΕΣΕΙ ΟΛΕΣ ΤΙΣ ΕΡΓΑΣΙΕΣ που είναι σχετικές με τη στήλη!!', - 'Settings' => 'Προτιμήσεις', - 'Application settings' => 'Παραμετροποίηση εφαρμογής', - 'Language' => 'Γλώσσα', - 'Webhook token:' => 'Διακριτικό ασφαλείας (token) webhooks:', - 'API token:' => 'Διακριτικό ασφαλείας (token) API:', - 'Database size:' => 'Μέγεθος βάσης δεδομένων :', - 'Download the database' => 'Κατεβάστε τη βάση δεδομένων', - 'Optimize the database' => 'Βελτιστοποίηση της βάσης δεδομένων', - '(VACUUM command)' => '(VACUUM command)', - '(Gzip compressed Sqlite file)' => '(Gzip compressed Sqlite file)', - 'Close a task' => 'Κλείσιμο εργασίας', - 'Edit a task' => 'Διόρθωση εργασίας', - 'Column' => 'Στήλη', - 'Color' => 'Χρώμα', - 'Assignee' => 'Ανατεθιμένο στον χρήστη', - 'Create another task' => 'Δημιουργία και άλλης εργασίας', - 'New task' => 'Νέα εργασία', - 'Open a task' => 'Άνοιγμα εργασίας', - 'Do you really want to open this task: "%s"?' => 'Άνοιγμα της εργασίας : « %s » ?', - 'Back to the board' => 'Επιστροφή στον κεντρικό πίνακα έργου', - 'There is nobody assigned' => 'Δεν έχει ανατεθεί σε κανένα', - 'Column on the board:' => 'Στήλη στον κεντρικό πίνακα : ', - 'Close this task' => 'Κλείσιμο εργασίας', - 'Open this task' => 'Άνοιγμα εργασίας', - 'There is no description.' => 'Δεν υπάρχει περιγραφή.', - 'Add a new task' => 'Προσθήκη νέας εργασίας', - 'The username is required' => 'Το όνομα χρήστη απαιτείται', - 'The maximum length is %d characters' => 'Ο μέγιστος αριθμός χαρακτήρων είναι %d χαρακτήρες', - 'The minimum length is %d characters' => 'Ο ελάχιστος αριθμός χαρακτήρων είναι %d χαρακτήρες', - 'The password is required' => 'Ο κωδικός απαιτείται', - 'This value must be an integer' => 'Η τιμή πρέπει να είναι ακέραιος', - 'The username must be unique' => 'Το όνομα χρήστη πρέπει να είναι μοναδικό', - 'The user id is required' => 'το αναγνωριστικό χρήστη απαιτείται', - 'Passwords don\'t match' => 'Οι κωδικοί πρόσβασης δεν ταιριάζουν', - 'The confirmation is required' => 'Η επειβεβαίωση απαιτείται', - 'The project is required' => 'Το έργο απαιτείται', - 'The id is required' => 'το αναγνωριστικό απαιτείται', - 'The project id is required' => 'το αναγνωριστικό έργου απαιτείται', - 'The project name is required' => 'Η ονομασία έργου απαιτείται', - 'The title is required' => 'Ο τίτλος απαιτείται', - 'Settings saved successfully.' => 'Οι προτιμήσεις αποθηκεύθηκαν με επιτυχία.', - 'Unable to save your settings.' => 'Αδυναμία αποθήκευσης προτιμήσεων.', - 'Database optimization done.' => 'Η βελτιστοποίηση της βάσης δεδομένων έγινε με επιτυχία.', - 'Your project have been created successfully.' => 'Το έργο δημιουργήθηκε.', - 'Unable to create your project.' => 'Δεν είναι δυνατή η δημιουργία του έργου', - 'Project updated successfully.' => 'Το έργο ενημερώθηκε με επιτυχία.', - 'Unable to update this project.' => 'Δεν είναι δυνατή η ενημέρωση του έργου.', - 'Unable to remove this project.' => 'Δεν είναι δυνατή η διαγραφή του έργου', - 'Project removed successfully.' => 'Το έργο αφαιρέθηκε επιτυχώς.', - 'Project activated successfully.' => 'Το έργο ενεργοποιήθηκε με επιτυχία', - 'Unable to activate this project.' => 'Δεν είναι δυνατή η ενεργοποίηση του έργου', - 'Project disabled successfully.' => 'Το έργο ενεργοποιήθηκε με επιτυχία', - 'Unable to disable this project.' => 'Δεν είναι δυνατή η επενεργοποίηση του έργου.', - 'Unable to open this task.' => 'Δεν είναι δυνατό το άνοιγμα της εργασίας', - 'Task opened successfully.' => 'Η εργασία άνοιξε με επιτυχία', - 'Unable to close this task.' => 'Δεν είναι δυνατό το κλείσιμο της εργασίας', - 'Task closed successfully.' => 'Η εργασία έκλεισε επιτυχώς', - 'Unable to update your task.' => 'Δεν είναι δυνατή η ενημέρωση της εργασίας', - 'Task updated successfully.' => 'Η εργασία ενημερώθηκε επιτυχώς', - 'Unable to create your task.' => 'Δεν είναι δυνατή η δημιουργία της εργασίας', - 'Task created successfully.' => 'Η εργασία δημιουργήθηκε επιτυχώς', - 'User created successfully.' => 'Ο χρήστης δημιουργήθηκε με επιτυχία', - 'Unable to create your user.' => 'Δεν είναι δυνατή η δημιουργία χρήστη', - 'User updated successfully.' => 'Ο χρήστης ενημερωθηκε με επιτυχία', - 'Unable to update your user.' => 'Δεν είναι δυνατή η ενημέρωση του χρήστη', - 'User removed successfully.' => 'Ο χρήστης αφαιρέθηκε με επιτυχία.', - 'Unable to remove this user.' => 'Δεν είναι δυνατή η αφαίρεση χρήστη.', - 'Board updated successfully.' => 'Ο πίνακας ενημερώθηκε με επιτυχία.', - 'Ready' => 'Έτοιμο', - 'Backlog' => 'Πρέπει να', - 'Work in progress' => 'Σε πρόοδο', - 'Done' => 'Ολοκληρωμένα', - 'Application version:' => 'Version εφαρμογής :', - 'Id' => 'Αναγνωριστικό.', - '%d closed tasks' => '%d κλειστές εργασίες', - 'No task for this project' => 'Αριθμός εργασιών για το έργο', - 'Public link' => 'Δημόσιος σύνδεσμος', - 'Timezone' => 'Timezone', - 'Sorry, I didn\'t find this information in my database!' => 'Δυστυχώς δεν βρέθηκε αυτή η πληροφορία στη βάση δεδομένων', - 'Page not found' => 'Η σελίδα δεν βρέθηκε', - 'Complexity' => 'Πολυπλοκότητα', - 'Task limit' => 'Όριο εργασιών.', - 'Task count' => 'Αρίθμηση εργασιών', - 'User' => 'Χρήστης', - 'Comments' => 'Σχόλια', - 'Leave a comment' => 'Αφήστε ένα σχόλιο', - 'Comment is required' => 'Το σχόλιο απαιτείται', - 'Leave a description' => 'Αφήστε μια περιγραφή', - 'Comment added successfully.' => 'Το σχόλιο σας προστέθηκε με επιτυχία.', - 'Unable to create your comment.' => 'Δεν είναι δυνατή η προσθήκη του σχολίου σας.', - 'Due Date' => 'Μέχρι την ημερομηνία', - 'Invalid date' => 'Μη ορθή ημερομηνία', - 'Automatic actions' => 'Αυτόματες ενέργειες', - 'Your automatic action have been created successfully.' => 'Η αυτόματη ενέργεια δημιουργήθηκε με επιτυχία.', - 'Unable to create your automatic action.' => 'Impossible de créer votre action automatisée.', - 'Remove an action' => 'Αφαίρεση ενέργειας', - 'Unable to remove this action.' => 'Δεν είναι δυνατή η αφαίρεση αυτής της ενέργειας', - 'Action removed successfully.' => 'Η ενέργεια αφαιρέθηκε με επιτυχία.', - 'Automatic actions for the project "%s"' => 'Αυτόματες ενέργειες για το έργο « %s »', - 'Add an action' => 'Προσθήκη ενέργειας', - 'Event name' => 'Ονομασία συμβάντος', - 'Action name' => 'Ονομασία ενέργειας', - 'Action parameters' => 'Παράμετροι ενέργειας', - 'Action' => 'Ενέργεια', - 'Event' => 'Συμβάν', - 'When the selected event occurs execute the corresponding action.' => 'Όταν εμφανίζεται το επιλεγμένο συμβάν εκτελέστε την αντίστοιχη ενέργεια.', - 'Next step' => 'Επόμενο βήμα', - 'Define action parameters' => 'Ορισμός παραμέτρων ενέργειας', - 'Do you really want to remove this action: "%s"?' => 'Αφαίρεση της ενέργειας: « %s » ?', - 'Remove an automatic action' => 'Αφαίρεση της αυτόματης ενέργειας', - 'Assign the task to a specific user' => 'Ανάθεση της εργασίας σε συγκεκριμένο χρήστη', - 'Assign the task to the person who does the action' => 'Ανάθεση της εργασίας στο άτομο που κάνει την ενέργεια', - 'Duplicate the task to another project' => 'Αντιγραφή εργασίας σε άλλο έργο', - 'Move a task to another column' => 'Μεταφορά εργασίας σε άλλη στήλη', - 'Task modification' => 'Διόρθωση εργασίας', - 'Task creation' => 'Δημιουργία εργασίας', - 'Closing a task' => 'Κλείσιμο εργασίας', - 'Assign a color to a specific user' => 'Ανάθεση χρώματος σε συγκεκριμένο χρήστη', - 'Column title' => 'Τίτλος στήλης', - 'Position' => 'Θέση', - 'Duplicate to another project' => 'Αντιγραφή σε άλλο έργο', - 'Duplicate' => 'Αντιγραφή', - 'link' => 'σύνδεσμος', - 'Comment updated successfully.' => 'Το σχόλιο ενημερώθηκε με επιτυχία.', - 'Unable to update your comment.' => 'Αδυναμία ενημέρωσης σχολίου.', - 'Remove a comment' => 'Διαγραφή σχολίου', - 'Comment removed successfully.' => 'Το σχόλιο διαγράφτηκε με επιτυχία.', - 'Unable to remove this comment.' => 'Αδυναμία διαγραφής σχολίου.', - 'Do you really want to remove this comment?' => 'Θέλετε να αφαιρέσετε το σχόλιο ?', - 'Current password for the user "%s"' => 'Ο τρέχοντας κωδικός για τον χρήστη « %s »', - 'The current password is required' => 'Ο τρέχοντας κωδικός πρόσβασης απαιτείται', - 'Wrong password' => 'Λάθος κωδικός πρόσβασης', - 'Unknown' => 'Άγνωστο', - 'Last logins' => 'Τελευταίες συνδέσεις', - 'Login date' => 'Ημερομηνία σύνδεσης', - 'Authentication method' => 'Μέθοδος ελέγχου ταυτότητας', - 'IP address' => 'Διεύθυνση IP', - 'User agent' => 'User agent', - 'Persistent connections' => 'Μόνιμες συνδέσεις', - 'No session.' => 'Καμμία συνεδρία', - 'Expiration date' => 'Ημερομηνία λήξης', - 'Remember Me' => 'Να με θυμάσαι', - 'Creation date' => 'Ημερομηνία δημιουργίας', - 'Everybody' => 'Όλα', - 'Open' => 'Ανοικτά', - 'Closed' => 'Κλειστά', - 'Search' => 'Αναζήτηση', - 'Nothing found.' => 'Δεν βρέθηκε.', - 'Due date' => 'Μέχρι την ημερομηνία', - 'Others formats accepted: %s and %s' => 'Άλλες δεκτές μορφοποιήσεις: %s και %s', - 'Description' => 'Περιγραφή', - '%d comments' => '%d σχόλια', - '%d comment' => '%d σχόλιο', - 'Email address invalid' => 'Μη αποδεκτή διεύθυνση email', - 'Your external account is not linked anymore to your profile.' => 'Ο λογαριασμός σας δεν συνδέεται πλέον με το προφίλ σας.', - 'Unable to unlink your external account.' => 'Αδυναμία αποσύνδεσης του εξωτερικού σας λογαριασμού.', - 'External authentication failed' => 'Αποτυχία εξωτερικής σύνδεσης', - 'Your external account is linked to your profile successfully.' => 'Ο λογαριασμός σας συνδέθηκε με το προφίλ σας με επιτυχία.', - 'Email' => 'Email', - 'Task removed successfully.' => 'Η εργασία αφαιρέθηκε με επιτυχία.', - 'Unable to remove this task.' => 'Δεν είναι δυνατή η αφαίρεση της εργασίας.', - 'Remove a task' => 'Αφαίρεση εργασίας', - 'Do you really want to remove this task: "%s"?' => 'Αφαίρεση της εργασίας « %s » ?', - 'Assign automatically a color based on a category' => 'Αυτόματη εκχώρηση ενός χρώματος με βάση την κατηγορία', - 'Assign automatically a category based on a color' => 'Αυτόματη εκχώρηση μιας κατηγορίας με βάση το χρώμα', - 'Task creation or modification' => 'Δημιουργία ή τροποποίηση εργασιών', - 'Category' => 'Κατηγορία', - 'Category:' => 'Κατηγορία:', - 'Categories' => 'Κατηγορίες', - 'Your category have been created successfully.' => 'Η κατηγορία δημιουργήθηκε.', - 'Unable to create your category.' => 'Δεν είναι δυνατή η δημιουργία της κατηγορίας.', - 'Your category have been updated successfully.' => 'Η ενημέρωση της κατηγορίας καταχωρήθηκε με επιτυχία.', - 'Unable to update your category.' => 'Δεν είναι δυνατή η ενημέρωση της κατηγορίας.', - 'Remove a category' => 'Διαγραφή κατηγορίας', - 'Category removed successfully.' => 'Η κατηγορία διεγράφει επιτυχώς.', - 'Unable to remove this category.' => 'Δεν είναι δυνατή η διαγραφή της κατηγορίας.', - 'Category modification for the project "%s"' => 'Τροποποίηση κατηγορίας για το έργο « %s »', - 'Category Name' => 'Ονομασία κατηγορίας', - 'Add a new category' => 'Προσθήκη νέας κατηγορίας', - 'Do you really want to remove this category: "%s"?' => 'Διαγραφή της κατηγορίας « %s » ?', - 'All categories' => 'Όλες οι κατηγορίες', - 'No category' => 'Χωρίς κατηγορία', - 'The name is required' => 'Η ονομασία απαιτείται', - 'Remove a file' => 'Αφαίρεση αρχείου', - 'Unable to remove this file.' => 'Αδυναμία αφαίρεσης αρχείου.', - 'File removed successfully.' => 'Το αρχείο αφαιρέθηκε επιτυχώς.', - 'Attach a document' => 'Προσθήκη Συνημμένου', - 'Do you really want to remove this file: "%s"?' => 'Αφαίρεση του αρχείου: « %s » ?', - 'Attachments' => 'Συνημμένα', - 'Edit the task' => 'Διόρθωση εργασίας', - 'Add a comment' => 'Προσθήκη σχολίου', - 'Edit a comment' => 'Διόρθωση σχολίου', - 'Summary' => 'Περίληψη', - 'Time tracking' => 'Παρακολούθηση χρόνου', - 'Estimate:' => 'Κατ\' εκτίμηση:', - 'Spent:' => 'Ξοδεύτηκε :', - 'Do you really want to remove this sub-task?' => 'Διαγραφή της υπο-εργασίας ?', - 'Remaining:' => 'Απομένει :', - 'hours' => 'ώρες', - 'spent' => 'ξοδεύτηκε', - 'estimated' => 'κατ\' εκτίμηση', - 'Sub-Tasks' => 'Υπο-Εργασίες', - 'Add a sub-task' => 'Προσθήκη υπο-εργασίας', - 'Original estimate' => 'Αρχική πρόβλεψη χρόνου', - 'Create another sub-task' => 'Δημιουργία κι άλλης υπο-εργασίας', - 'Time spent' => 'Χρόνος που ξοδεύτηκε', - 'Edit a sub-task' => 'Διόρθωση υπο-εργασίας', - 'Remove a sub-task' => 'Διαγραφή υπο-εργασίας', - 'The time must be a numeric value' => 'Ο χρόνος πρέπει να είναι αριθμός', - 'Todo' => 'Πρέπει να γίνουν', - 'In progress' => 'Σε πρόοδο', - 'Sub-task removed successfully.' => 'Η υπο-εργασία αφαιρέθηκε με επιτυχία.', - 'Unable to remove this sub-task.' => 'Αδυναμία αφαίρεσης υπο-εργασίας.', - 'Sub-task updated successfully.' => 'Η υπο-εργασία ενημερώθηκε με επιτυχία.', - 'Unable to update your sub-task.' => 'Αδύνατο να ενημερωθεί η υπο-εργασία.', - 'Unable to create your sub-task.' => 'Αδύνατο να δημιουργηθεί η υπο-εργασία.', - 'Sub-task added successfully.' => 'Η υπο-εργασία προστέθηκε με επιτυχία.', - 'Maximum size: ' => 'Μέγιστο μέγεθος : ', - 'Unable to upload the file.' => 'Δεν είναι δυνατή η μεταφόρτωση του αρχείου.', - 'Display another project' => 'Εμφάνιση άλλου έργου', - 'Created by %s' => 'Δημιουργήθηκε από %s', - 'Tasks Export' => 'Εξαγωγή εργασιών', - 'Tasks exportation for "%s"' => 'Εξαγωγή εργασιών για το έργο « %s »', - 'Start Date' => 'Ημερομηνία έναρξης', - 'End Date' => 'ημερομηνία λήξης', - 'Execute' => 'Εκτέλεση', - 'Task Id' => 'Task Id', - 'Creator' => 'Δημιουργός', - 'Modification date' => 'Ημερομηνία τροποποίησης', - 'Completion date' => 'Ημερομηνία ολοκλήρωσης', - 'Clone' => 'Clone', - 'Project cloned successfully.' => 'Το έργο κλωνοποιήθηκε με επιτυχία.', - 'Unable to clone this project.' => 'Αδύνατο να κλωνοποιηθεί το έργο.', - 'Enable email notifications' => 'Ενεργοποίηση ειδοποιήσεων ηλεκτρονικού ταχυδρομείου', - 'Task position:' => 'Θέση έργου:', - 'The task #%d have been opened.' => 'Η εργασία #%d έχει ανοίξει.', - 'The task #%d have been closed.' => 'Η εργασία #%d έχει κλείσει.', - 'Sub-task updated' => 'Η υπο-εργασία ενημερώθηκε', - 'Title:' => 'Τίτλος:', - 'Status:' => 'Κατάσταση:', - 'Assignee:' => 'Εντολοδόχος:', - 'Time tracking:' => 'Παρακολούθηση του χρόνου:', - 'New sub-task' => 'Νέα υπο-εργασία', - 'New attachment added "%s"' => 'Νέα επικόλληση προστέθηκε « %s »', - 'New comment posted by %s' => 'Νέο σχόλιο από τον χρήστη « %s »', - 'New attachment' => 'New attachment', - 'New comment' => 'Νέο σχόλιο', - 'Comment updated' => 'Το σχόλιο ενημερώθηκε', - 'New subtask' => 'Νέα υπο-εργασία', - 'Subtask updated' => 'Η Υπο-Εργασία ενημερώθηκε', - 'Task updated' => 'Η εργασία ενημερώθηκε', - 'Task closed' => 'Η εργασία έκλεισε', - 'Task opened' => 'Η εργασία άνοιξε', - 'I want to receive notifications only for those projects:' => 'Θέλω να ενημερώνομαι αποκλειστικά για:', - 'view the task on Kanboard' => 'Προβολή της εργασίας στο Kanboard', - 'Public access' => 'Ανοιχτή πρόσβαση', - 'Active tasks' => 'Ενεργοποιημένες εργασίες', - 'Disable public access' => 'Απενεργοποίηση δημόσιας πρόσβασης', - 'Enable public access' => 'Ενεργοποίηση δημόσιας πρόσβασης', - 'Public access disabled' => 'Δημόσια πρόσβαση απενεργοποιήθηκε', - 'Do you really want to disable this project: "%s"?' => 'Θέλετε πραγματικά να απενεργοποιήσετε το έργο: « %s » ?', - 'Do you really want to enable this project: "%s"?' => 'Θέλετε πραγματικά να ενεργοποιήσετε το έργο: « %s » ?', - 'Project activation' => 'Ενεργοποίηση έργου', - 'Move the task to another project' => 'Μεταφορά της εργασίας σε άλλο έργο', - 'Move to another project' => 'Μεταφορά σε άλλο έργο', - 'Do you really want to duplicate this task?' => 'Θέλετε πραγματικά να επαναλάβετε αυτή την εργασία;?', - 'Duplicate a task' => 'Επανάληψη εργασίας', - 'External accounts' => 'Εξωτερικοί λογαριασμοί', - 'Account type' => 'Τύπος λογαριασμού', - 'Local' => 'Τοπική', - 'Remote' => 'Απομακρυσμένη', - 'Enabled' => 'Ενεργή', - 'Disabled' => 'Απενεργοποιημένη', - 'Username:' => 'Username:', - 'Name:' => 'Όνομα:', - 'Email:' => 'Email:', - 'Notifications:' => 'Ειδοποιήσεις:', - 'Notifications' => 'Ειδοποιήσεις', - 'Account type:' => 'Τύπος λογαριασμού:', - 'Edit profile' => 'Επεξεργασία προφίλ', - 'Change password' => 'Αλλαγή password', - 'Password modification' => 'Τροποποίηση password ', - 'External authentications' => 'Εξωτερικές πιστοποιήσεις', - 'Never connected.' => 'Ποτέ δεν συνδέθηκε.', - 'No external authentication enabled.' => 'Καμία εξωτερική πιστοποιήση ενεργοποιημένη.', - 'Password modified successfully.' => 'Το password τροποποιήθηκε με επιτυχία.', - 'Unable to change the password.' => 'Αδύνατο να αλλάξει το password.', - 'Change category' => 'Αλλαγή κατηγορίας', - '%s updated the task %s' => '%s ενημέρωσε την εργασία %s', - '%s opened the task %s' => '%s άνοιξε την εργασία %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s άλλαξε την εργασία %s στη θέση n°%d στη στήλη « %s »', - '%s moved the task %s to the column "%s"' => '%s άλλαξε την εργασία %s στη στήλη « %s »', - '%s created the task %s' => '%s δημιούργησε την εργασία %s', - '%s closed the task %s' => '%s έκλεισε την εργασία %s', - '%s created a subtask for the task %s' => '%s δημιούργησε την υπο-εργασία στην εργασία %s', - '%s updated a subtask for the task %s' => '%s ενημέρωση την υπο-εργασία στην εργασία %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Ανατέθηκε στον %s με μια εκτίμηση του %s/%sh', - 'Not assigned, estimate of %sh' => 'Δεν έχει εκχωρηθεί, εκτίμηση %sh', - '%s updated a comment on the task %s' => '%s ενημερώθηκε ένα σχόλιο στην εργασία %s', - '%s commented the task %s' => '%s σχολίασε την εργασία %s', - '%s\'s activity' => 'δραστηριότητα του έργου %s', - 'RSS feed' => 'RSS feed', - '%s updated a comment on the task #%d' => '%s ενημέρωσε ένα σχόλιο στην εργασία n°%d', - '%s commented on the task #%d' => '%s σχολίασε την εργασία n°%d', - '%s updated a subtask for the task #%d' => '%s ενημερώθηκε μια υπο-εργασία στην εργασία n °%d', - '%s created a subtask for the task #%d' => '%s δημιουργήθηκε μια υπο-εργασία στην εργασία n°%d', - '%s updated the task #%d' => '%s ενημέρωσε την εργασία n°%d', - '%s created the task #%d' => '%s δημιούργησε την εργασία n°%d', - '%s closed the task #%d' => '%s έκλεισε την εργασία n°%d', - '%s open the task #%d' => '%s άνοιξε την εργασία n°%d', - '%s moved the task #%d to the column "%s"' => '%s μετακίνησε την εργασία n°%d στη στήλη « %s »', - '%s moved the task #%d to the position %d in the column "%s"' => '%s μετακίνησε την εργασία n°%d στη θέση n°%d της στήλης « %s »', - 'Activity' => 'Δραστηριότητα', - 'Default values are "%s"' => 'Οι προεπιλεγμένες τιμές είναι « %s »', - 'Default columns for new projects (Comma-separated)' => 'Προεπιλεγμένες στήλες για νέα έργα (Comma-separated)', - 'Task assignee change' => 'Αλλαγή εκδοχέα εργασίας', - '%s change the assignee of the task #%d to %s' => '%s άλλαξε τον εκδοχέα της εργασίας n˚%d σε %s', - '%s changed the assignee of the task %s to %s' => '%s ενημέρωσε τον εκδοχέα της εργασίας %s σε %s', - 'New password for the user "%s"' => 'Νέο password του χρήστη « %s »', - 'Choose an event' => 'Επιλογή event', - 'Create a task from an external provider' => 'Δημιουργήστε μια εργασία από ένα εξωτερικό πάροχο', - 'Change the assignee based on an external username' => 'Αλλάξτε τον εκδοχέα βάση ενός εξωτερικού username', - 'Change the category based on an external label' => 'Αλλάξτε τον εκδοχέα βάση ενός εξωτερικού label', - 'Reference' => 'Reference', - 'Label' => 'Label', - 'Database' => 'Database', - 'About' => 'About', - 'Database driver:' => 'Database driver:', - 'Board settings' => 'Board settings', - 'Webhook settings' => 'Webhook settings', - 'Reset token' => 'Reset token', - 'API endpoint:' => 'URL API:', - 'Refresh interval for private board' => 'Ανανέωση interval στο private board', - 'Refresh interval for public board' => 'Ανανέωση interval στο public board', - 'Task highlight period' => 'Περίοδος εργασίας', - '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' => 'Application URL', - 'Token regenerated.' => 'Token regenerated.', - 'Date format' => 'Μορφή ημερομηνίας', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format είναι πάντα αποδεκτό, π.χ.: « %s » και « %s »', - 'New private project' => 'Νέο ιδιωτικό έργο', - 'This project is private' => 'Αυτό το έργο είναι ιδιωτικό', - 'Add' => 'Προσθήκη', - 'Start date' => 'Ημερομηνία έναρξης', - 'Time estimated' => 'Εκτιμώμενος χρόνος', - 'There is nothing assigned to you.' => 'Δεν σας έχει ανατεθεί τίποτα.', - 'My tasks' => 'Οι εργασίες μου', - 'Activity stream' => 'Ροή δραστηριότητας', - 'Dashboard' => 'Κεντρικό ταμπλό', - 'Confirmation' => 'Επιβεβαίωση', - 'Allow everybody to access to this project' => 'Να επιτρέπετε σε όλους να έχουν πρόσβαση σε αυτό το έργο', - 'Everybody have access to this project.' => 'Όλοι έχουν πρόσβαση σε αυτό το έργο.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Δημιουργήστε ένα σχόλιο από έναν εξωτερικό πάροχο', - 'Project management' => 'Διαχείριση έργων', - 'My projects' => 'Τα έργα μου', - 'Columns' => 'Στήλες', - 'Task' => 'Εργασία', - 'Your are not member of any project.' => 'Δεν είστε μέλος κάποιου έργου.', - 'Percentage' => 'Ποσοστό', - 'Number of tasks' => 'Αριθμός εργασιών', - 'Task distribution' => 'Κατανομή εργασιών', - 'Reportings' => 'Αναφορές', - 'Task repartition for "%s"' => 'Επανάληψη εργασιών για « %s »', - 'Analytics' => 'Αναλύσεις', - 'Subtask' => 'Υπο-Εργασία', - 'My subtasks' => 'Οι υπο-εργασίες μου', - 'User repartition' => 'Επαναλήψεις χρηστών', - 'User repartition for "%s"' => 'Επαναλήψεις χρηστών για « %s »', - 'Clone this project' => 'Κλωνοποίηση έργου', - 'Column removed successfully.' => 'Η στήλη αφαιρέθηκε με επιτυχία.', - 'Not enough data to show the graph.' => 'Ελλειπή δεδομένα για να εμφανιστεί το γράφημα.', - 'Previous' => 'Προηγούμενο', - 'The id must be an integer' => 'Το id δεν πρέπει να είναι ακέραιος', - 'The project id must be an integer' => 'Το αναγνωριστικό έργου πρέπει να είναι ακέραιος', - 'The status must be an integer' => 'Το status πρέπει να είναι ακέραιος', - 'The subtask id is required' => 'Το id της υπο-εργασίας είναι υποχρεωτικό', - 'The subtask id must be an integer' => 'Το id της υπο-εργασίας πρέπει να είναι ακέραιος', - 'The task id is required' => 'Το id της εργασίας είναι υποχρεωτικό', - 'The task id must be an integer' => 'Το id της εργασίας πρέπει να είναι ακέραιος', - 'The user id must be an integer' => 'Το user id πρέπει να είναι ακέραιος', - 'This value is required' => 'Η τιμή είναι υποχρεωτική', - 'This value must be numeric' => 'Η τιμή πρέπει να είναι αριθμός', - 'Unable to create this task.' => 'Αδύνατο να δημιουργηθεί αυτή η εργασία.', - 'Cumulative flow diagram' => 'Συγκεντρωτικό διάγραμμα ροής', - 'Cumulative flow diagram for "%s"' => 'Συγκεντρωτικό διάγραμμα ροής για « %s »', - 'Daily project summary' => 'Καθημερινή περίληψη του έργου', - 'Daily project summary export' => 'Εξαγωγή της καθημερινής περίληψης του έργου', - 'Daily project summary export for "%s"' => 'Εξαγωγή της καθημερινής περίληψης του έργου « %s »', - 'Exports' => 'Εξαγωγές', - 'This export contains the number of tasks per column grouped per day.' => 'Αυτή η κατάσταση περιέχει τον αριθμό των εργασιών ανά στήλη ομαδοποιημένα ανά ημέρα.', - 'Active swimlanes' => 'Ενεργές λωρίδες', - 'Add a new swimlane' => 'Προσθήκη λωρίδας', - 'Change default swimlane' => 'Αλλαγή της εξ\' ορισμού λωρίδας', - 'Default swimlane' => 'Εξ\' ορισμού λωρίδα', - 'Do you really want to remove this swimlane: "%s"?' => 'Σίγουρα θέλετε να αφαιρέσετε τη λωρίδα : « %s » ?', - 'Inactive swimlanes' => 'Ανενεργές Λωρίδες', - 'Remove a swimlane' => 'Αφαίρεση λωρίδας', - 'Show default swimlane' => 'Εμφάνιση προεπιλεγμένων λωρίδων', - 'Swimlane modification for the project "%s"' => 'Τροποποίηση λωρίδας για το έργο « %s »', - 'Swimlane removed successfully.' => 'Η λωρίδα αφαιρέθηκε με επιτυχία.', - 'Swimlanes' => 'Λωρίδες', - 'Swimlane updated successfully.' => 'Η λωρίδα ενημερώθηκε με επιτυχία.', - 'The default swimlane have been updated successfully.' => 'Η προεπιλεγμένη λωρίδα ενημερώθηκε με επιτυχία.', - 'Unable to remove this swimlane.' => 'Αδύνατο να αφαιρεθεί η λωρίδα.', - 'Unable to update this swimlane.' => 'Αδύνατο να ενημερωθεί η λωρίδα.', - 'Your swimlane have been created successfully.' => 'Η λωρίδα δημιουργήθηκε με επιτυχία.', - 'Example: "Bug, Feature Request, Improvement"' => 'Παράδειγμα: "Bug, Feature Request, Improvement »', - 'Default categories for new projects (Comma-separated)' => 'Προεπιλεγμένες κατηγορίες για νέα έργα (Διαχωρισμένων με κόμμα)', - 'Integrations' => 'Ενσωματώσεις', - 'Integration with third-party services' => 'Ενοποίηση με υπηρεσίες τρίτων', - 'Subtask Id' => 'Id υπο-εργασίας', - 'Subtasks' => 'Υπο-Εργασίες', - 'Subtasks Export' => 'Εξαγωγή υπο-εργασίων', - 'Subtasks exportation for "%s"' => 'Εξαγωγή υπο-εργασίων για το έργο « %s »', - 'Task Title' => 'Τίτλος εργασίας', - 'Untitled' => 'Χωρίς τίτλο', - 'Application default' => 'Προεπιλογή από την εφαρμογή', - 'Language:' => 'Γλώσσα:', - 'Timezone:' => 'Timezone:', - 'All columns' => 'Όλες οι στήλες', - 'Calendar' => 'Ημερολόγιο', - 'Next' => 'Επόμενο', - '#%d' => 'n˚%d', - 'All swimlanes' => 'Όλες οι λωρίδες', - 'All colors' => 'Όλα τα χρώματα', - 'Moved to column %s' => 'Μεταφορά στη στήλη %s', - '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 »', - 'Subtask timesheet' => 'Πρόγραμμα υπο-εργασίας', - 'There is nothing to show.' => 'Δεν υπάρχει κάτι.', - 'Time Tracking' => 'Παρακολούθηση χρονοδιαγράμματος', - 'You already have one subtask in progress' => 'Έχετε ήδη μια υπο-εργασία σε εξέλιξη', - 'Which parts of the project do you want to duplicate?' => 'Ποιά κομμάτια του έργου θέλετε να αντιγράψετε ?', - 'Disallow login form' => 'Απαγόρευση φόρμας σύνδεσης', - 'Start' => 'Εκκίνηση', - 'End' => 'Τέλος', - 'Task age in days' => 'Χρόνος εργασίας σε μέρες', - 'Days in this column' => 'Μέρες σε αυτή την στήλη', - '%dd' => '%dημ', - 'Add a new link' => 'Προσθήκη ενός νέου link', - 'Do you really want to remove this link: "%s"?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link : « %s » ?', - 'Do you really want to remove this link with task #%d?' => 'Θέλετε σίγουρα να αφαιρέσετε αυτό το link του έργου n°%d ?', - 'Field required' => 'Υποχρεωτικό πεδίο', - 'Link added successfully.' => 'Το link προστέθηκε με επιτυχία.', - 'Link updated successfully.' => 'Το link ενημερώθηκε με επιτυχία.', - 'Link removed successfully.' => 'Το link αφαιρέθηκε με επιτυχία.', - '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 πρέπει να είναι μοναδικό', - 'Unable to create your link.' => 'Αδύνατο να δημιουργήσετε σύνδεσμο.', - 'Unable to update your link.' => 'Αδύνατο να ενημερώσετε τον σύνδεσμο.', - 'Unable to remove this link.' => 'Αδύνατο να αφαιρέσετε τον σύνδεσμο.', - 'relates to' => 'συνδέεται με', - 'blocks' => 'blocks', - 'is blocked by' => 'μπλοκάρεται από', - 'duplicates' => 'διπλότυπα', - 'is duplicated by' => 'αντιγράφεται από', - 'is a child of' => 'είναι ένα παιδί του', - 'is a parent of' => 'είναι ο πατέρας του', - 'targets milestone' => 'στόχοι οροσήμου', - 'is a milestone of' => 'είναι ένα ορόσημο της', - 'fixes' => 'διορθώσεις', - 'is fixed by' => 'διορθώθηκε από', - 'This task' => 'Αυτή η εργασία', - '<1h' => '<1ωρ', - '%dh' => '%dωρ', - 'Expand tasks' => 'Ανάπτυξη εργασιών', - 'Collapse tasks' => 'Σύμπτυξη εργασιών', - 'Expand/collapse tasks' => 'Ανάπτυξη/σύμπτυξη εργασιών', - 'Close dialog box' => 'Κλείστε το παράθυρο διαλόγου', - 'Submit a form' => 'Αποστολή φόρμας', - 'Board view' => 'Προβολή κεντρικού πίνακα', - 'Keyboard shortcuts' => 'Συντομεύσεις πληκτρολογίου', - 'Open board switcher' => 'Άνοιγμα μεταγωγέα κεντρικού πίνακα', - 'Application' => 'Εφαρμογή', - 'Compact view' => 'Συμπυκνωμένη προβολή', - 'Horizontal scrolling' => 'Οριζόντια ολίσθηση', - 'Compact/wide view' => 'Συμπυκνωμένη/Ευρεία Προβολή', - 'No results match:' => 'Δεν ταιριάζει κανένα αποτέλεσμα:', - 'Currency' => 'Νόμισμα', - 'Private project' => 'Ιδιωτικό έργο', - 'AUD - Australian Dollar' => 'AUD - Australian Dollar', - 'CAD - Canadian Dollar' => 'CAD - Canadian Dollar', - 'CHF - Swiss Francs' => 'CHF - Swiss Francs', - 'Custom Stylesheet' => 'Custom Stylesheet', - 'download' => 'download', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - British Pound', - 'INR - Indian Rupee' => 'INR - Indian Rupee', - 'JPY - Japanese Yen' => 'JPY - Japanese Yen', - 'NZD - New Zealand Dollar' => 'NZD - New Zealand Dollar', - 'RSD - Serbian dinar' => 'RSD - Serbian dinar', - 'USD - US Dollar' => 'USD - US Dollar', - 'Destination column' => 'Στήλη προορισμού', - 'Move the task to another column when assigned to a user' => 'Μετακινήστε την εργασία σε άλλη στήλη όταν ανατεθεί σε ένα χρήστη', - 'Move the task to another column when assignee is cleared' => 'Μετακινήστε την εργασία σε άλλη στήλη όταν ο εκδοχέας είναι ελεύθερος', - 'Source column' => 'Πηγή στήλης', - 'Transitions' => 'Μεταβάσεις', - 'Executer' => 'Εκτέλεση', - 'Time spent in the column' => 'Χρόνος που αφιερώθηκε στη στήλη', - 'Task transitions' => 'Μεταβίβαση εργασίας', - 'Task transitions export' => 'Εξαγωγή μεταβιβάσεων εργασιών', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Η έκθεση αυτή περιέχει όλες τις κινήσεις της στήλης για κάθε εργασία με την ημερομηνία, το χρήστη και το χρόνο που δαπανάται για κάθε μετάβαση.', - 'Currency rates' => 'Ισοτιμίες', - 'Rate' => 'Τιμή', - 'Change reference currency' => 'Αλλαγή ισοτιμίας', - 'Add a new currency rate' => 'Προσθήκη ισοτιμίας', - 'Reference currency' => 'Αναφορά ισοτιμίας', - 'The currency rate have been added successfully.' => 'Η ισοτιμία προστέθηκε με επιτυχία.', - 'Unable to add this currency rate.' => 'Αδύνατο να προστεθεί αυτή η ισοτιμία.', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s αφαίρεσε τον εκδοχέα της εργασίας %s', - 'Enable Gravatar images' => 'Ενεργοποίηση εικόνων Gravatar', - 'Information' => 'Πληροφορίες', - 'Check two factor authentication code' => 'Ελέγξτε δύο παράγοντες ελέγχου ταυτότητας κωδικού', - 'The two factor authentication code is not valid.' => 'Ο κωδικός ελέγχου ταυτότητας δύο παραγόντων δεν είναι σωστός.', - 'The two factor authentication code is valid.' => 'Ο κωδικός ελέγχου ταυτότητας δύο παραγόντων είναι σωστός.', - 'Code' => 'Κωδικός', - 'Two factor authentication' => 'Κωδικός ελέγχου ταυτότητας δύο παραγόντων', - 'This QR code contains the key URI: ' => 'Αυτό το QR code περιέχει το url : ', - 'Check my code' => 'Έλεγχος του κωδικού μου', - 'Secret key: ' => 'Μυστικό κλειδί: ', - 'Test your device' => 'Ελέγξτε τη συσκευή σας', - 'Assign a color when the task is moved to a specific column' => 'Αντιστοίχιση χρώματος όταν η εργασία κινείται σε μια συγκεκριμένη στήλη', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Δημιουργία διαγράμματος για « %s »', - 'Burndown chart' => 'Δημιουργία διαγράμματος', - 'This chart show the task complexity over the time (Work Remaining).' => 'Αυτό το γράφημα δείχνει την πολυπλοκότητα του έργου κατά την πάροδο του χρόνου (Εργασία που παραμένει).', - 'Screenshot taken %s' => 'Το screenshot αποθηκεύτηκε από %s', - 'Add a screenshot' => 'Προσθήκη ενός screenshot', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Πάρτε ένα screenshot και πατήστε CTRL+V or ⌘+V για να το επικολλήσετε εδώ.', - 'Screenshot uploaded successfully.' => 'Το screenshot ανέβηκε με επιτυχία.', - 'SEK - Swedish Krona' => 'SEK - Swedish Krona', - 'Identifier' => 'Αναγνωριστικό', - 'Disable two factor authentication' => 'Απενεργοποίηση κωδικού ελέγχου ταυτότητας δύο παραγόντων', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Είστε σίγουροι ότι θέλετε να απενεργοποίησετε τον κωδικό ελέγχου ταυτότητας δύο παραγόντων : « %s » ?', - 'Edit link' => 'Επεξεργασία συνδέσμου', - 'Start to type task title...' => 'Ξεκινήστε να πληκτρολογείτε τον τίτλο της εργασίας...', - 'A task cannot be linked to itself' => 'Μια εργασία δεν μπορεί να συνδεθεί με τον εαυτό της', - 'The exact same link already exists' => 'Ο σύνδεσμος υπάρχει ήδη', - 'Recurrent task is scheduled to be generated' => 'Επαναλαμβανόμενο έργο έχει προγραμματιστεί να δημιουργηθεί', - 'Score' => 'Score', - 'The identifier must be unique' => 'Το αναγνωριστικό πρέπει να είναι μοναδικό', - 'This linked task id doesn\'t exists' => 'Αυτό το συνδεδεμένο id της εργασίας δεν υπάρχει', - 'This value must be alphanumeric' => 'Η τιμή πρέπει να είναι αλφαριθμητική', - 'Edit recurrence' => 'Επεξεργασία επανάληψης', - 'Generate recurrent task' => 'Δημιουργία επαναλαμβανόμενου έργου', - 'Trigger to generate recurrent task' => 'Έναυσμα για τη δημιουργία επαναλαμβανόμενης εργασίας', - 'Factor to calculate new due date' => 'Συντελεστής για τον υπολογισμό νέας ημερομηνίας καθηκόντων', - 'Timeframe to calculate new due date' => 'Χρονικό πλαίσιο για τον υπολογισμό νέας ημερομηνίας καθηκόντων', - 'Base date to calculate new due date' => 'Ημερομηνία βάσης για τον υπολογισμό νέας ημερομηνίας καθηκόντων', - 'Action date' => 'Ημέρα ενέργειας', - 'Base date to calculate new due date: ' => 'Ημερομηνία βάσης για τον υπολογισμό νέας ημερομηνίας καθηκόντων : ', - 'This task has created this child task: ' => 'Το έργο αυτό έχει δημιουργήθει από το έργο παιδί του: ', - 'Day(s)' => 'Μέρα(ες)', - 'Existing due date' => 'Υπάρχουσα ημερομηνία καθηκόντων', - 'Factor to calculate new due date: ' => 'Συντελεστής για τον υπολογισμό νέας ημερομηνίας καθηκόντων: ', - 'Month(s)' => 'Μήνες', - 'Recurrence' => 'Επανάληψη', - 'This task has been created by: ' => 'Αυτό το έργο δημιουργήθηκε από τον χρήστη :', - 'Recurrent task has been generated:' => 'Το επαναλαμβανόμενο έργο έχει παραχθεί :', - 'Timeframe to calculate new due date: ' => 'Χρονοδιάγραμμα υπολογισμού νέας ημερομηνίας καθηκόντων : ', - 'Trigger to generate recurrent task: ' => 'Έναυσμα για τη δημιουργία επαναλαμβανόμενη εργασίας : ', - 'When task is closed' => 'Όταν το έργο έχει τελειώσει', - 'When task is moved from first column' => 'Όταν το έργο έχει μετακινηθεί στην 1η στήλη', - 'When task is moved to last column' => 'Όταν το έργο έχει μετακινηθεί στην τελευταία στήλη', - 'Year(s)' => 'Χρόνος(οι)', - 'Calendar settings' => 'Ρυθμίσεις ημερολογίου', - 'Project calendar view' => 'Προβολή ημερολογίου έργων', - 'Project settings' => 'Ρυθμίσεις έργου', - 'Show subtasks based on the time tracking' => 'Εμφάνιση υπο-εργασίων με βάση την παρακολούθηση του χρόνου', - 'Show tasks based on the creation date' => 'Εμφάνιση έργων με βάση την ημερομηνία δημιουργίας', - 'Show tasks based on the start date' => 'Εμφάνιση έργων με βάση την ημερομηνία δημιουργίας ', - 'Subtasks time tracking' => 'Παρακολούθηση χρόνου υπο-εργασίων', - 'User calendar view' => 'Προβολή του ημερολογίου του χρήστη', - 'Automatically update the start date' => 'Αυτόματη ενημέρωση της ημερομηνίας έναρξης', - 'iCal feed' => 'iCal feed', - 'Preferences' => 'Προτιμήσεις', - 'Security' => 'Ασφάλεια', - 'Two factor authentication disabled' => 'Η πιστοποίηση δύο παραγόντων απενεργοποιήθηκε', - 'Two factor authentication enabled' => 'Η πιστοποίηση δύο παραγόντων ενεργοποιήθηκε', - 'Unable to update this user.' => 'Αδύνατο να ενημερωθεί αυτός ο χρήστης.', - 'There is no user management for private projects.' => 'Δεν υπάρχει διαχείριση χρηστών για ιδιωτικά έργα.', - 'User that will receive the email' => 'Ο χρήστης που θα λάβει το μήνυμα ηλεκτρονικού ταχυδρομείου', - 'Email subject' => 'Θέμα ηλεκτρονικού ταχυδρομείου', - 'Date' => 'Ημέρα', - 'Add a comment log when moving the task between columns' => 'Προσθέστε ένα σχόλιο καταγραφής κατά τη μετακίνηση του έργου μεταξύ των στηλών', - 'Move the task to another column when the category is changed' => 'Μετακινήστε την εργασία σε άλλη στήλη, όταν η κατηγορία έχει αλλάξει', - 'Send a task by email to someone' => 'Στείλτε μια εργασία μέσω ηλεκτρονικού ταχυδρομείου σε κάποιον', - 'Reopen a task' => 'Ξανα-ανοίξτε μια εργασία', - 'Column change' => 'Αλλαγή στήλης', - 'Position change' => 'Αλλαγή θέσης', - 'Swimlane change' => 'Αλλαγή λωρίδας', - 'Assignee change' => 'Αλλαγή εκδοχέα', - '[%s] Overdue tasks' => '[%s] Εκπρόθεσμες εργασίες', - 'Notification' => 'Κοινοποίηση', - '%s moved the task #%d to the first swimlane' => '%s μετέφερε την εργασία n°%d στην 1η λωρίδα', - '%s moved the task #%d to the swimlane "%s"' => '%s μετέφερε την εργασία n°%d στη λωρίδα « %s »', - 'Swimlane' => 'Λωρίδα', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s μετέφερε την εργασία %s στην 1η λωρίδα', - '%s moved the task %s to the swimlane "%s"' => '%s μετέφερε την εργασία %s στη λωρίδα « %s »', - 'This report contains all subtasks information for the given date range.' => 'Η έκθεση αυτή περιέχει όλες τις υπο-εργασίες για το συγκεκριμένο εύρος ημερομηνιών.', - 'This report contains all tasks information for the given date range.' => 'Η έκθεση αυτή περιέχει όλες τις πληροφορίες για το συγκεκριμένο εύρος ημερομηνιών.', - 'Project activities for %s' => 'Ενέργειες για το έργο « %s »', - 'view the board on Kanboard' => 'δείτε τον πίνακα στο Kanboard', - 'The task have been moved to the first swimlane' => 'Η εργασία αυτή έχει μετακινηθεί στην πρώτη λωρίδα', - 'The task have been moved to another swimlane:' => 'Η εργασία αυτή έχει μετακινηθεί σε άλλη λωρίδα:', - 'New title: %s' => 'Νέος τίτλος: %s', - 'The task is not assigned anymore' => 'Η εργασία δεν έχει ανατεθεί πλέον', - 'New assignee: %s' => 'Καινούργια ανάθεση: %s', - 'There is no category now' => 'Δεν υπάρχει κατηγορία τώρα', - 'New category: %s' => 'Νέα κατηγορία: %s', - 'New color: %s' => 'Νέο χρώμα: %s', - 'New complexity: %d' => 'Νέα πολυπλοκότητα: %d', - 'The due date have been removed' => 'Η ημερομηνία καθηκόντων έχει αφαιρεθεί', - 'There is no description anymore' => 'Δεν υπάρχει περιγραφή πλέον', - 'Recurrence settings have been modified' => 'Οι ρυθμίσεις επανάληψης έχουν τροποποιηθεί', - 'Time spent changed: %sh' => 'Ο χρόνος που πέρασε έχει αλλάξει: %sh', - 'Time estimated changed: %sh' => 'Ο εκτιμώμενος χρόνος άλλαξε: %sh', - 'The field "%s" have been updated' => 'Το πεδίο « %s » έχει ενημερωθεί', - 'The description has been modified:' => 'Η περιγραφή έχει ενημερωθεί', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Σίγουρα θέλετε να κλείσετε την εργασία « %s » και την υπο-εργασία ?', - 'I want to receive notifications for:' => 'Επιθυμώ να λαμβάνω ενημερώσεις για :', - 'All tasks' => 'Όλες οι εργασίες', - 'Only for tasks assigned to me' => 'Μόνο σε εργασίες που μου έχουν ανατεθεί', - 'Only for tasks created by me' => 'Μόνο σε εργασίες που έχουν δημιουργηθεί από εμένα', - 'Only for tasks created by me and assigned to me' => 'Μόνο σε εργασίες που έχουν δημιουργηθεί από εμένα και μου έχουν ανατεθεί', - '%%Y-%%m-%%d' => '%%d/%%m/%%Y', - 'Total for all columns' => 'Σύνολο για όλες τις στήλες', - 'You need at least 2 days of data to show the chart.' => 'Έχετε τουλάχιστον 2 ημέρες δεδομένων για να εμφανιστούν στο διάγραμμα.', - '<15m' => '<15m', - '<30m' => '<30m', - 'Stop timer' => 'Διακοπή ρολογιού', - 'Start timer' => 'Έναρξη ρολογιού', - 'Add project member' => 'Προσθήκη νέου μέλους έργου', - 'My activity stream' => 'Η ροή δραστηριοτήτων μου', - 'My calendar' => 'Το ημερολόγιο μου', - 'Search tasks' => 'Αναζήτηση εργασιών', - 'Reset filters' => 'Επαναφορά φίλτρων', - 'My tasks due tomorrow' => 'Οι εργασίες καθηκόντων μου αύριο', - 'Tasks due today' => 'Οι εργασίες καθηκόντων μου αύριο', - 'Tasks due tomorrow' => 'Εργασίες καθηκόντων αύριο', - 'Tasks due yesterday' => 'Εργασίες καθηκόντων χτές', - 'Closed tasks' => 'Κλειστές εργασίες', - 'Open tasks' => 'Ανοιχτές εργασίες', - 'Not assigned' => 'Δεν έχουν εκχωρηθεί', - 'View advanced search syntax' => 'Δείτε τη σύνταξη "αναζήτησης για προχωρημένους"', - 'Overview' => 'Επισκόπηση', - 'Board/Calendar/List view' => 'Πίνακας / Ημερολόγιο / Προβολή λίστας', - 'Switch to the board view' => 'Εναλλαγή στην προβολή του πίνακα', - 'Switch to the calendar view' => 'Εναλλαγή στην προβολή ημερολογίου', - 'Switch to the list view' => 'Εναλλαγή στην προβολή λίστας', - 'Go to the search/filter box' => 'Μετάβαση στο πλαίσιο αναζήτησης / φίλτρο', - 'There is no activity yet.' => 'Δεν υπάρχει καμία δραστηριότητα ακόμα.', - 'No tasks found.' => 'Δεν βρέθηκαν εργασίες.', - 'Keyboard shortcut: "%s"' => 'Συντόμευση πληκτρολογίου: « %s »', - 'List' => 'Λίστα', - 'Filter' => 'Φίλτρο', - 'Advanced search' => 'Προχωρημένη Αναζήτηση', - 'Example of query: ' => 'Παράδειγμα ερωτήματος: ', - 'Search by project: ' => 'Αναζήτηση με βάση το έργο: ', - 'Search by column: ' => 'Αναζήτηση με βάση την στήλη: ', - 'Search by assignee: ' => 'Αναζήτηση με βάση τον δικαιοδόχο: ', - 'Search by color: ' => 'Αναζήτηση βάση χρώματος: ', - 'Search by category: ' => 'Αναζήτηση βάση κατηγορίας: ', - 'Search by description: ' => 'Αναζήτηση βάση περιγραφής: ', - 'Search by due date: ' => 'Αναζήτηση βάση ημέρας λήξης: ', - 'Lead and Cycle time for "%s"' => 'Lead & cycle time για « %s »', - 'Average time spent into each column for "%s"' => 'Μέσος χρόνος παραμονής σε κάθε στήλη για « %s »', - 'Average time spent into each column' => 'Μέσος χρόνος παραμονής σε κάθε στήλη', - 'Average time spent' => 'Μέσος χρόνος που δαπανήθηκε', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Αυτό το γράφημα δείχνει ότι ο μέσος χρόνος που δαπανάται σε κάθε στήλη για τις τελευταίες %d εργασίες', - 'Average Lead and Cycle time' => 'Average Lead & Cycle time', - 'Average lead time: ' => 'Average lead time: ', - 'Average cycle time: ' => 'Average cycle time: ', - 'Cycle Time' => 'Cycle time', - 'Lead Time' => 'Lead time', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Αυτό το γράφημα δείχνει το average lead and cycle time για τις τελευταίες %d εργασίες κατά τη διάρκεια του χρόνου.', - 'Average time into each column' => 'Μέσος χρόνος σε κάθε στήλη', - 'Lead and cycle time' => 'Lead et cycle time', - 'Lead time: ' => 'Lead time : ', - 'Cycle time: ' => 'Cycle time : ', - 'Time spent into each column' => 'Ο χρόνος που δαπανήθηκε σε κάθε στήλη', - 'The lead time is the duration between the task creation and the completion.' => 'Το <lead time> είναι η διάρκεια μεταξύ της δημιουργίας του έργου και της ολοκλήρωσης του.', - 'The cycle time is the duration between the start date and the completion.' => 'Το <cycle time> είναι η διάρκεια μεταξύ της ημερομηνίας εκκίνησης και της ολοκλήρωσης του.', - '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 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.' => 'Δεν υπάρχει διαθέσιμο κανένα έργο προορισμού.', - 'Trigger automatically subtask time tracking' => 'Αυτόματη ενεργοποίηση της παρακολούθησης χρόνου σε υπο-εργασίες', - 'Include closed tasks in the cumulative flow diagram' => 'Να συμπεριλαμβάνονται οι κλειστές εργασίες στο συσσωρευτικό διάγραμμα ροής', - 'Current swimlane: %s' => 'Τρέχουσα λωρίδα: %s', - 'Current column: %s' => 'Τρέχουσα στήλη: %s', - 'Current category: %s' => 'Τρέχουσα κατηγορία: %s', - 'no category' => 'Καμμία κατηγορία', - 'Current assignee: %s' => 'Τρέχον εκδοχέας: %s', - 'not assigned' => 'δεν έχει εκχωρηθεί', - 'Author:' => 'Συγγραφέας:', - 'contributors' => 'συνεισφέροντες', - 'License:' => 'Άδεια:', - 'License' => 'Άδεια', - 'Enter the text below' => 'Πληκτρολογήστε το παρακάτω κείμενο', - 'Gantt chart for %s' => 'Gantt διάγραμμα για %s', - 'Sort by position' => 'Ταξινόμηση κατά Θέση', - 'Sort by date' => 'Ταξινόμηση κατά ημέρα', - 'Add task' => 'Προσθήκη εργασίας', - 'Start date:' => 'Ημερομηνία εκκίνησης :', - 'Due date:' => 'Ημερομηνία λήξης:', - 'There is no start date or due date for this task.' => 'Δεν υπάρχει ημερομηνία έναρξης ή ημερομηνία λήξης καθηκόντων για το έργο αυτό.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Μετακίνηση ή αλλαγή μεγέθους μιας εργασίας θα αλλάξει την ώρα έναρξης και ημερομηνία λήξης της εργασίας.', - 'There is no task in your project.' => 'Δεν υπάρχει καμία εργασία στο έργο σας.', - 'Gantt chart' => 'Διαγράμματα Gantt', - 'People who are project managers' => 'Οι άνθρωποι που είναι οι διευθυντές έργων', - 'People who are project members' => 'Οι άνθρωποι που είναι μέλη των έργων', - 'NOK - Norwegian Krone' => 'NOK - Norwegian Krone', - 'Show this column' => 'Εμφάνιση αυτής της στήλης', - 'Hide this column' => 'Απόκρυψη αυτής τη στήλη', - 'open file' => 'Άνοιγμα αρχείου', - 'End date' => 'Ημερομηνία λήξης', - 'Users overview' => 'Επισκόπηση χρηστών', - 'Members' => 'Μέλη', - 'Shared project' => 'Κοινόχρηστο έργο', - 'Project managers' => 'Διευθυντές έργου', - 'Gantt chart for all projects' => 'Διάγραμμα Gantt για όλα τα έργα', - 'Projects list' => 'Λίστα έργων', - 'Gantt chart for this project' => 'Διάγραμμα Gantt για το έργο', - 'Project board' => 'Κεντρικός πίνακας έργου', - 'End date:' => 'Ημερομηνία λήξης :', - 'There is no start date or end date for this project.' => 'Δεν υπάρχει ημερομηνία έναρξης ή λήξης για το έργο αυτό.', - 'Projects Gantt chart' => 'Διάγραμμα Gantt έργων', - 'Change task color when using a specific task link' => 'Αλλαγή χρώματος εργασίας χρησιμοποιώντας συγκεκριμένο σύνδεσμο εργασίας', - 'Task link creation or modification' => 'Σύνδεσμος δημιουργίας ή τροποποίησης εργασίας', - 'Milestone' => 'Ορόσημο', - 'Documentation: %s' => 'Τεκμηρίωση: %s', - 'Switch to the Gantt chart view' => 'Μεταφορά σε προβολή διαγράμματος Gantt', - 'Reset the search/filter box' => 'Αρχικοποίηση του πεδίου αναζήτησης/φιλτραρίσματος', - 'Documentation' => 'Τεκμηρίωση', - 'Table of contents' => 'Πίνακας περιεχομένων', - 'Gantt' => 'Gantt', - 'Author' => 'Δημιουργός', - 'Version' => 'Έκδοση', - 'Plugins' => 'Πρόσθετα', - 'There is no plugin loaded.' => 'Δεν έχει φορτωθεί plugin', - 'Set maximum column height' => 'Ορισμός μέγιστου ύψους στήλης', - 'Remove maximum column height' => 'Αφαίρεση μέγιστου ύψους στήλης', - 'My notifications' => 'Οι ειδοποιήσεις μου', - 'Custom filters' => 'Φίλτρα ορισμένα από τον χρήστη', - 'Your custom filter have been created successfully.' => 'Το παρεμετροποιημένο από τον χρήστη φίλτρο δημιουργήθηκε με επιτυχία', - 'Unable to create your custom filter.' => 'Δεν είναι δυνατή η δημιουργία του φίλτρου ορισμένου από τον χρήστη.', - 'Custom filter removed successfully.' => 'Το παρεμετροποιημένο από τον χρήστη φίλτρο αφαιρέθηκε με επιτυχία.', - 'Unable to remove this custom filter.' => 'Δεν είναι δυνατή η αφαίρεση του παρεμετροποιημένου από τον χρήστη φίλτρου.', - 'Edit custom filter' => 'Διόρθωση παρεμετροποιημένου από τον χρήστη φίλτρου', - 'Your custom filter have been updated successfully.' => 'Το παρεμετροποιημένο από τον χρήστη φίλτρο, διορθώθηκε με επιτυχία.', - 'Unable to update custom filter.' => 'Δεν είναι δυνατή η ενημέρωση του παρεμετροποιημένου από τον χρήστη φίλτρου.', - 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Νέο συνημμένο για την εργασία n°%d: %s', - 'New comment on task #%d' => 'Νέο σχόλιο για την εργασία n°%d', - 'Comment updated on task #%d' => 'Ενημέρωση σχολίου για την εργασία n°%d', - 'New subtask on task #%d' => 'Νέα υπο-εργασία για την εργασία n°%d', - 'Subtask updated on task #%d' => 'Ενημέρωση υπό-εργασίας για την εργασία n°%d', - 'New task #%d: %s' => 'Νέα εργασία n°%d: %s', - 'Task updated #%d' => 'Η εργασία n°%d ενημερώθηκε με επιτυχία', - 'Task #%d closed' => 'Η εργασία n°%d έκλεισε', - 'Task #%d opened' => 'Η εργασία n°%d άνοιξε', - 'Column changed for task #%d' => 'Η στήλη άλλαξε για την εργασία n°%d', - 'New position for task #%d' => 'Νέα θέση για την εργασία n°%d', - 'Swimlane changed for task #%d' => 'Η λωρίδα άλλαξε για την εργασία n°%d', - 'Assignee changed on task #%d' => 'Η ανάθεση άλλαξε για την εργασία n°%d', - '%d overdue tasks' => '%d εκπρόθεσμες εργασίες', - 'Task #%d is overdue' => 'Η εργασία n°%d είναι εκπρόθεσμη', - 'No new notifications.' => 'Χωρίς νέες ειδοποιήσεις.', - 'Mark all as read' => 'Μαρκάρισμα όλων ως διαβασμένα', - 'Mark as read' => 'Μαρκάρισμα ως διαβασμένο', - 'Total number of tasks in this column across all swimlanes' => 'Συνολικός αριθμός εργασιών σε αυτήν τη στήλη σε όλες τις λωρίδες', - 'Collapse swimlane' => 'Συρίκνωση λωρίδας', - 'Expand swimlane' => 'Ανάπτυξη λωρίδας', - 'Add a new filter' => 'Προσθήκη νέου φίλτρου', - 'Share with all project members' => 'Διαμοίραση με όλους τους χρήστες του έργου', - 'Shared' => 'Διαμοιρασμένα', - 'Owner' => 'Ιδιοκτήτης', - 'Unread notifications' => 'Αδιάβαστες ειδοποιήσεις', - 'Notification methods:' => 'Μέθοδοι ειδοποίησης:', - 'Import tasks from CSV file' => 'Εισαγωγή εργασιών μέσω αρχείου CSV', - 'Unable to read your file' => 'Δεν είναι δυνατή η ανάγνωση του αρχείου', - '%d task(s) have been imported successfully.' => '%d η(οι) εργασία(ες) εισήχθησαν με επιτυχία.', - 'Nothing have been imported!' => 'Τίποτα δεν εισήχθη', - 'Import users from CSV file' => 'Εισαγωγή χρηστών μέσω αρχείου CSV', - '%d user(s) have been imported successfully.' => '%d ο(οι) χρήστης(ες) εισήχθησαν με επιτυχία.', - 'Comma' => 'Κόμμα', - 'Semi-colon' => 'Ερωτηματικό', - 'Tab' => 'Tab', - 'Vertical bar' => 'Κατακόρυφη μπάρα', - 'Double Quote' => 'Διπλά εισαγωγικά', - 'Single Quote' => 'Μονά εισαγωγικά', - '%s attached a file to the task #%d' => '%s συνημμένο αρχείο στην εργασία n°%d', - 'There is no column or swimlane activated in your project!' => 'Δεν υπάρχει στήλη ή λωρίδα ενεργοποιημένη στο έργο !', - 'Append filter (instead of replacement)' => 'Προσθήκη φίλτρου (αντί αντικατάσταση)', - 'Append/Replace' => 'Προσθήκη/Αντικατάσταση', - 'Append' => 'Προσθήκη', - 'Replace' => 'Αντικατάσταση', - 'Import' => 'Εισαγωγή', - 'change sorting' => 'Αλλαγή ταξινόμησης', - 'Tasks Importation' => 'Εισαγωγή εργασιών', - 'Delimiter' => 'Delimiter', - 'Enclosure' => 'Enclosure', - 'CSV File' => 'Αρχείο CSV', - 'Instructions' => 'Οδηγίες', - 'Your file must use the predefined CSV format' => 'Το αρχείο σας πρέπει να χρησιμοποιεί προκαθορισμένη μορφοποίηση CSV', - 'Your file must be encoded in UTF-8' => 'Το αρχείο σας πρέπει να έχει κωδικοποίηση χαρακτήρων UTF-8', - 'The first row must be the header' => 'Η πρώτη γραμμή πρέπει να είναι η κεφαλίδα', - 'Duplicates are not verified for you' => 'Οι Διπλοεγγραφές δεν ελέγχονται', - 'The due date must use the ISO format: YYYY-MM-DD' => 'Η ημερομηνία λήξης πρέπει να χρησιμοποιεί τη μορφοποίηση ISO: EEEE-MM-HH ή στα αγγλικά YYYY-MM-DD', - 'Download CSV template' => 'Κατέβασμα πρότυπου αρχείου CSV', - 'No external integration registered.' => 'No external integration registered.', - 'Duplicates are not imported' => 'Διπλοεγγραφές δεν εισήχθησαν', - 'Usernames must be lowercase and unique' => 'Οι ονομασίες χρηστών πρέπει να είναι σε μικρά γράμματα (lowercase) και μοναδικά', - 'Passwords will be encrypted if present' => 'Οι κωδικοί πρόσβασης κρυπτογραφούνται, αν υπάρχουν', - '%s attached a new file to the task %s' => '%s νέο συνημμένο αρχείο της εργασίας %s', - 'Link type' => 'Τύπος συνδέσμου', - 'Assign automatically a category based on a link' => 'Ανατίθεται αυτόματα κατηγορία, βασισμένη στον σύνδεσμο', - 'BAM - Konvertible Mark' => 'BAM - Konvertible Mark', - 'Assignee Username' => 'Δικαιοδόχο όνομα χρήστη', - 'Assignee Name' => 'Δικαιοδόχο όνομα', - 'Groups' => 'Ομάδες', - 'Members of %s' => 'Μέλη του %s', - 'New group' => 'Νέα ομάδα', - 'Group created successfully.' => 'Η ομάδα δημιουργήθηκε με επιτυχία.', - 'Unable to create your group.' => 'Δεν είναι δυνατή η δημιουργία της ομάδας.', - 'Edit group' => 'Διόρθωση ομάδας', - 'Group updated successfully.' => 'Η ομάδα ενημερώθηκε με επιτυχία.', - 'Unable to update your group.' => 'Δεν είναι δυνατή η ενημέρωση της ομάδας.', - 'Add group member to "%s"' => 'Προσθήκη του μέλους της ομάδας στην « %s »', - 'Group member added successfully.' => 'Το μέλος της ομ΄δας προστέθηκε με επιτυχία.', - 'Unable to add group member.' => 'Δεν είναι δυνατή η προσθήκη μέλους ομάδας.', - 'Remove user from group "%s"' => 'Αφαίρεση μέλους από την ομάδα « %s »', - 'User removed successfully from this group.' => 'Ο χρήστης αφαιρέθηκε με επιτυχία από την ομάδα.', - 'Unable to remove this user from the group.' => 'Δεν είναι δυνατή η αφαίρεση του χρήστη από την ομάδα.', - 'Remove group' => 'Αφαίρεση ομάδας', - 'Group removed successfully.' => 'Η ομάδα αφαιρέθηκε με επιτυχία.', - 'Unable to remove this group.' => 'Δεν είναι δυνατή η αφαίρεση της ομάδας.', - 'Project Permissions' => 'Επιτρέψεις έργου', - 'Manager' => 'Διευθυντής', - 'Project Manager' => 'Διευθυντής έργου', - 'Project Member' => 'Μέλος σε έργο', - 'Project Viewer' => 'Μέλος μόνο για προβολή έργου', - 'Your account is locked for %d minutes' => 'Ο λογαριασμός σας κλειδώθηκε για %d λεπτά', - 'Invalid captcha' => 'Μη αποδεκτό Captcha', - 'The name must be unique' => 'Το όνομα πρέπει να είναι μοναδικό', - 'View all groups' => 'Προβολή όλων των ομάδων', - 'View group members' => 'Προβολή των μελών της ομάδας', - 'There is no user available.' => 'Δεν υπάρχει διαθέσιμος χρήστης', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Αφαίρεση του χρήστη « %s » από την ομάδα « %s » ?', - 'There is no group.' => 'Δεν υπάρχει ομάδα.', - 'External Id' => 'Εξωτερικό αναγνωριστικό', - 'Add group member' => 'Προσθήκη μέλους ομάδας', - 'Do you really want to remove this group: "%s"?' => 'Αφαίρεση της ομάδας: « %s » ?', - 'There is no user in this group.' => 'Δεν υπάρχει χρήστης σε αυτήν την ομάδα', - 'Remove this user' => 'Αφαίρεση χρήστη', - 'Permissions' => 'Επιτρέψεις', - 'Allowed Users' => 'Χρήστες που επιτρέπονται', - 'No user have been allowed specifically.' => 'Δεν υπάρχει χρήστης που να επιτρέπεται συγκεκριμένα.', - 'Role' => 'Ρόλος', - 'Enter user name...' => 'Εισαγωγή ονόματος χρήστη...', - 'Allowed Groups' => 'Ομάδες που επιτρέπονται', - 'No group have been allowed specifically.' => 'Δεν υπάρχει ομάδα που να επιτρέπεται συγκεκριμένα.', - 'Group' => 'Ομάδα', - 'Group Name' => 'Ονομασία ομάδας', - 'Enter group name...' => 'Εισαγωγή ονομασίας ομάδας...', - 'Role:' => 'Ρόλος:', - 'Project members' => 'Μέλη έργου', - 'Compare hours for "%s"' => 'Σύγκριση ωρών για « %s »', - '%s mentioned you in the task #%d' => '%s αναφέρονται σε εσάς, στη εργασία n°%d', - '%s mentioned you in a comment on the task #%d' => '%s αναφέρονται σε εσάς σε σχόλιο, στη εργασίας n°%d', - 'You were mentioned in the task #%d' => 'Αναφέρεστε στην εργασία n°%d', - 'You were mentioned in a comment on the task #%d' => 'Αναφέρεστε σε σχόλιο, στην εργασία n°%d', - 'Mentioned' => 'Αναφέρεται', - 'Compare Estimated Time vs Actual Time' => 'Σύγκριση προβλεπόμενου χρόνου vs πραγματικού χρόνου', - 'Estimated hours: ' => 'Προβλεπόμενες ώρες: ', - 'Actual hours: ' => 'Πραγματικές ώρες: ', - 'Hours Spent' => 'Δαπανόμενες ώρες', - 'Hours Estimated' => 'Προβλεπόμενες ώρες', - 'Estimated Time' => 'Προβλεπόμενος χρόνος', - 'Actual Time' => 'Πραγματικός χρόνος', - 'Estimated vs actual time' => 'Προβλεπόμενος vs πραγματικός χρόνος', - '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' => 'Time-based One-time Password Algorithm', - 'Two-Factor Provider: ' => 'Two-Factor Provider: ', - 'Disable two-factor authentication' => 'Απενεργοποίηση two-factor authentication', - 'Enable two-factor authentication' => 'Ενεργοποίηση two-factor authentication', - 'There is no integration registered at the moment.' => 'There is no integration registered at the moment.', - 'Password Reset for Kanboard' => 'Αρχικοποίηση κωδικών πρόσβασης για την εφαρμογή Kanboard', - 'Forgot password?' => 'Ξεχάσατε τον κωδικό πρόσβασης ?', - 'Enable "Forget Password"' => 'Ενεργοποίηση « Ξέχασα τον κωδικό πρόσβασης »', - 'Password Reset' => 'Αρχικοποίηση κωδικού πρόσβασης', - 'New password' => 'Νέος κωδικός πρόσβασης', - 'Change Password' => 'Αλλαγή κωδικού πρόσβασης', - 'To reset your password click on this link:' => 'Για να αρχικοποιηθεί ο κωδικός πρόσβασης σας πατήστε σε αυτόν τον σύνδεσμο:', - 'Last Password Reset' => 'Αρχικοποίηση τελευταίου κωδικού πρόσβασης', - 'The password has never been reinitialized.' => 'Ο κωδικός πρόσβασης δεν μπορεί να αρχικοποιηθεί για δεύτερη φορά.', - 'Creation' => 'Δημιουργία', - 'Expiration' => 'Λήξη', - 'Password reset history' => 'Ιστορικό αρχικοποίησης κωδικών πρόσβασης', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Όλες οι εργασίας της στήλης « %s » και η λωρίδα « %s » έκλεισαν με επιτυχία.', - 'Do you really want to close all tasks of this column?' => 'Να κλείσουν όλες οι εργασίες αυτής της στήλης ?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d εργασία(ες) στη στήλη « %s » και στη λωρίδα « %s » θα κλείσουν.', - 'Close all tasks of this column' => 'Κλείσιμο όλων των εργασιών αυτής της στήλης', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Κανένα plugin δεν έχει καταχωρηθεί με τη μέθοδο της κοινοποίησης του έργου. Μπορείτε ακόμα να διαμορφώσετε τις μεμονωμένες κοινοποιήσεις στο προφίλ χρήστη σας.', - 'My dashboard' => 'Το κεντρικό ταμπλό μου', - 'My profile' => 'Το προφίλ μου', - 'Project owner: ' => 'Ιδιοκτήτης έργου: ', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Το αναγνωριστικό έργου είναι προαιρετικό και πρέπει να είναι αλφαριθμητικό, για παράδειγμα: MYPROJECT', - 'Project owner' => 'Ιδιοκτήτης έργου', - 'Those dates are useful for the project Gantt chart.' => 'Οι ημερομηνίες αυτές είανι χρήσιμες για το διάγραμμα Gantt του έργου', - 'Private projects do not have users and groups management.' => 'Τα ιδιωτικά έργα δεν έχουν χρήστες και διαχείριση ομάδων', - 'There is no project member.' => 'Δεν υπάρχει μέλος στο έργο', - 'Priority' => 'Προτεραιότητα', - 'Task priority' => 'Προτεραιότητα εργασίας', - 'General' => 'Γενικά', - 'Dates' => 'Ημερομηνίες', - 'Default priority' => 'Εξ ορισμού προτεραιότητα', - 'Lowest priority' => 'η χαμηλότερη προτεραιότητα', - 'Highest priority' => 'η υψηλότερη προτεραιότητα', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Αν βάλετε μηδέν στη χαμηλή και στην υψηλή προτεραιότητα, το χαρακτηριστικό αυτό απενεργοποιείται.', - 'Close a task when there is no activity' => 'Κλείσιμο εργασίας όταν δεν υπάρχει δραστηριότητα', - 'Duration in days' => 'Διάρκεια σε ημέρες', - 'Send email when there is no activity on a task' => 'Αποστολή email όταν δεν υπάρχει δραστηριότητα σε εργασία', - 'Unable to fetch link information.' => 'Δεν είναι δυνατή η ανάλυση της πληροφορίας συνδεσμου', - 'Daily background job for tasks' => 'Ημερήσια παρασκηνιακή δουλειά για τις εργασίες', - 'Auto' => 'Αυτόματο', - 'Related' => 'Σχετίζεται', - 'Attachment' => 'Συνημμένο', - 'Title not found' => 'Ο τίτλος δεν βρέθηκε', - 'Web Link' => 'Σύνδεσμος web', - 'External links' => 'Εξωτερικοί σύνδεσμοι', - 'Add external link' => 'Προσθήκη εξωτερικού συνδέσμου', - 'Type' => 'Τύπος', - 'Dependency' => 'Εξάρτηση', - 'Add internal link' => 'Προσθήκη εσωτερικού συνδέσμου', - 'Add a new external link' => 'Προσθήκη νέου εξωτερικού συνδέσμου', - 'Edit external link' => 'Διόρθωση εξωτερικού συνδέσμου', - 'External link' => 'Εξωτερικός σύνδεσμος', - 'Copy and paste your link here...' => 'Κάντε αντιγραφή και επικόλληση εδώ', - 'URL' => 'URL', - 'Internal links' => 'Εσωτερικοί σύνδεσμοι', - 'Assign to me' => 'Αναττίθεται σε εμένα', - 'Me' => 'Σε μένα', - 'Do not duplicate anything' => 'Να μην γίνει κλωνοποίηση από άλλο έργο', - 'Projects management' => 'Διαχείριση έργων', - 'Users management' => 'Διαχείριση χρηστών', - 'Groups management' => 'Διαχείριση ομάδων', - 'Create from another project' => 'Δημιουργία από άλλο έργο', - 'open' => 'Ανοικτό', - 'closed' => 'Κλειστό', - 'Priority:' => 'Προτεραιότητα:', - 'Reference:' => 'Αναφορά:', - 'Complexity:' => 'Πολυπλοκότητα:', - 'Swimlane:' => 'Λωρίδα:', - 'Column:' => 'Στήλη:', - 'Position:' => 'Θέση:', - 'Creator:' => 'Δημιουργός:', - 'Time estimated:' => 'Προβλεπόμενη ώρα:', - '%s hours' => '%s ώρες', - 'Time spent:' => 'χρόνος που καταναλώθηκε:', - 'Created:' => 'Δημιουργήθηκε:', - 'Modified:' => 'Διορθώθηκε:', - 'Completed:' => 'Ολοκληρώθηκε:', - 'Started:' => 'Ξεκίνησε:', - 'Moved:' => 'Μετακινήθηκε:', - 'Task #%d' => 'Εργασία #%d', - 'Date and time format' => 'Μορφή ημερομηνίας και ώρας', - 'Time format' => 'Μορφή ώρας', - 'Start date: ' => 'Ημερομηνία έναρξης: ', - 'End date: ' => 'Ημερομηνία λήξης: ', - 'New due date: ' => 'Νέα ημερομηνία λήξης: ', - 'Start date changed: ' => 'Αλλαγμένη ημερομηνία έναρξης: ', - 'Disable private projects' => 'Απενεργοποίηση ιδιωτικών έργων', - 'Do you really want to remove this custom filter: "%s"?' => 'Αφαίρεση αυτού του οριζόμενου από το χρήστη φίλτρου %s ?', - 'Remove a custom filter' => 'Αφαίρεση του οριζόμενου από το χρήστη φίλτρου', - 'User activated successfully.' => 'Ο χρήστης ενεργοποιήθηκε με επιτυχία', - 'Unable to enable this user.' => 'Δεν είναι δυνατή η ενεργοποίηση του χρήστη', - 'User disabled successfully.' => 'Η απενεργοποίηση του χρήστη έγινε με επιτυχία', - 'Unable to disable this user.' => 'Δεν είναι δυνατή η απενεργοποίηση του χρήστη', - 'All files have been uploaded successfully.' => 'Όλα τα αρχεία ανέβηκαν με επιτυχία', - 'View uploaded files' => 'Προβολή ανεβασμένων αρχείων', - 'The maximum allowed file size is %sB.' => 'Το μέγιστο μέγεθος αρχείου που επιτρέπεται είναι %sB.', - 'Choose files again' => 'Επιλογή κι άλλων αρχείων', - 'Drag and drop your files here' => 'Σύρετε τα αρχεία σας εδώ', - 'choose files' => 'Επιλογή αρχείων', - 'View profile' => 'Προβολή προφίλ', - 'Two Factor' => 'Δύο παραγόντων', - 'Disable user' => 'Απενεργοποίηση χρήστη', - 'Do you really want to disable this user: "%s"?' => 'Απενεργοποίηση του χρήστη: "%s";', - 'Enable user' => 'Ενεργοποίηση χρήστη', - 'Do you really want to enable this user: "%s"?' => 'Ενεργοποίηση του χρήστη "%s";', - 'Download' => 'Κατέβασμα', - 'Uploaded: %s' => 'Ανέβηκε το αρχείο: %s', - 'Size: %s' => 'Μέγεθος: %s', - 'Uploaded by %s' => 'Ανέβασμα από τον χρήστη: %s', - 'Filename' => 'Όνομα αρχείου', - 'Size' => 'Μέγεθος', - 'Column created successfully.' => 'Η στήλη δημιουργήθηκε με επιτυχία.', - 'Another column with the same name exists in the project' => 'Μια άλλη στήλη με το ίδιο όνομα υπάρχει στο έργο', - 'Default filters' => 'Εξ\' ορισμού φίλτρα', - 'Your board doesn\'t have any 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' => 'Η τιμή πρέπει να είναι μεγαλύτερη από %d', - 'Another swimlane with the same name exists in the project' => 'Μια άλλη λωρίδα, με το ίδιο όνομα υπάρχει στο έργο', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Παράδειγμα: http://example.kanboard.net/ (χρησιμοποιείται για τη δημιουργία απόλυτων URLs)', - // 'Actions duplicated successfully.' => '', - // 'Unable to duplicate actions.' => '', - // 'Add a new action' => '', - // 'Import from another project' => '', - // 'There is no action at the moment.' => '', - // 'Import actions from another project' => '', - // 'There is no available project.' => '', - // 'Local File' => '', - // 'Configuration' => '', - // 'PHP version:' => '', - // 'PHP SAPI:' => '', - // 'OS version:' => '', - // 'Database version:' => '', - // 'Browser:' => '', - // 'Task view' => '', - // 'Edit task' => '', - // 'Edit description' => '', - // 'New internal link' => '', - // 'Display list of keyboard shortcuts' => '', - // 'Menu' => '', - // 'Set start date' => '', - // 'Avatar' => '', - // 'Upload my avatar image' => '', - // 'Remove my image' => '', - // 'The OAuth2 state parameter is invalid' => '', - // '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' => '', -); diff --git a/sources/app/Locale/es_ES/translations.php b/sources/app/Locale/es_ES/translations.php deleted file mode 100644 index 40c9a8c..0000000 --- a/sources/app/Locale/es_ES/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'Ninguno', - 'edit' => 'modificar', - 'Edit' => 'Modificar', - 'remove' => 'eliminar', - 'Remove' => 'Eliminar', - 'Yes' => 'Sí', - 'No' => 'No', - 'cancel' => 'cancelar', - 'or' => 'o', - 'Yellow' => 'Amarillo', - 'Blue' => 'Azul', - 'Green' => 'Verde', - 'Purple' => 'Morado', - 'Red' => 'Rojo', - 'Orange' => 'Naranja', - 'Grey' => 'Gris', - 'Brown' => 'Marrón', - 'Deep Orange' => 'Naranja oscuro', - 'Dark Grey' => 'Gris oscuro', - 'Pink' => 'Rosa', - 'Teal' => 'Verde azulado', - 'Cyan' => 'Cian', - 'Lime' => 'Lima', - 'Light Green' => 'Verde claro', - 'Amber' => 'Ámbar', - 'Save' => 'Guardar', - 'Login' => 'Iniciar sesión (ingresar)', - 'Official website:' => 'Página web oficial:', - 'Unassigned' => 'No asignado', - 'View this task' => 'Ver esta tarea', - 'Remove user' => 'Eliminar un usuario', - 'Do you really want to remove this user: "%s"?' => '¿Realmente desea eliminar este usuario: «%s»?', - 'All users' => 'Todos los usuarios', - 'Username' => 'Nombre de usuario', - 'Password' => 'Contraseña', - 'Administrator' => 'Administrador', - 'Sign in' => 'Iniciar sesión', - 'Users' => 'Usuarios', - 'No user' => 'Ningún usuario', - 'Forbidden' => 'Acceso denegado', - 'Access Forbidden' => 'Acceso denegado', - 'Edit user' => 'Modificar el usuario', - 'Logout' => 'Salir', - 'Bad username or password' => 'Usuario o contraseña incorrecto', - 'Edit project' => 'Modificar el proyecto', - 'Name' => 'Nombre', - 'Projects' => 'Proyectos', - 'No project' => 'Ningún proyecto', - 'Project' => 'Proyecto', - 'Status' => 'Estado', - 'Tasks' => 'Tareas', - 'Board' => 'Tablero', - 'Actions' => 'Acciones', - 'Inactive' => 'Inactivo', - 'Active' => 'Activo', - '%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', - 'Do you really want to remove this project: "%s"?' => '¿Realmente desea eliminar este proyecto: «%s»?', - 'Remove project' => 'Eliminar el proyecto', - 'Edit the board for "%s"' => 'Modificar el tablero para «%s»', - 'All projects' => 'Todos los proyectos', - 'Add a new column' => 'Añadir una nueva columna', - '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!', - 'Settings' => 'Preferencias', - 'Application settings' => 'Preferencias de la aplicación', - 'Language' => 'Idioma', - 'Webhook token:' => 'Token de los disparadores web (webhooks):', - 'API token:' => 'Token de la API:', - 'Database size:' => 'Tamaño de la base de datos:', - 'Download the database' => 'Descargar la base de datos', - 'Optimize the database' => 'Optimizar la base de datos', - '(VACUUM command)' => '(comando VACUUM)', - '(Gzip compressed Sqlite file)' => '(archivo Sqlite comprimido en Gzip)', - 'Close a task' => 'Cerrar una tarea', - 'Edit a task' => 'Modificar una tarea', - 'Column' => 'Columna', - 'Color' => 'Color', - 'Assignee' => 'Responsable', - 'Create another task' => 'Crear otra tarea', - 'New task' => 'Nueva tarea', - 'Open a task' => 'Abrir una tarea', - 'Do you really want to open this task: "%s"?' => '¿Realmente desea abrir esta tarea: «%s»?', - 'Back to the board' => 'Volver al tablero', - 'There is nobody assigned' => 'No hay nadie asignado a esta tarea', - 'Column on the board:' => 'Columna en el tablero:', - 'Close this task' => 'Cerrar esta tarea', - 'Open this task' => 'Abrir esta tarea', - 'There is no description.' => 'No hay descripción.', - 'Add a new task' => 'Añadir una nueva tarea', - 'The username is required' => 'El nombre del usuario es obligatorio', - 'The maximum length is %d characters' => 'La longitud máxima es de %d caracteres', - 'The minimum length is %d characters' => 'La longitud mínima es de %d caracteres', - 'The password is required' => 'La contraseña es obligatoria', - 'This value must be an integer' => 'Este valor debe ser un entero', - 'The username must be unique' => 'El nombre del usuario debe ser único', - 'The user id is required' => 'El identificador del usuario es obligatorio', - 'Passwords don\'t match' => 'Las contraseñas no coinciden', - 'The confirmation is required' => 'La confirmación es obligatoria', - 'The project is required' => 'El proyecto es obligatorio', - 'The id is required' => 'El identificador es obligatorio', - 'The project id is required' => 'El identificador del proyecto es obligatorio', - 'The project name is required' => 'El nombre del proyecto es obligatorio', - 'The title is required' => 'El título es obligatorio', - 'Settings saved successfully.' => 'Preferencias guardadas correctamente.', - 'Unable to save your settings.' => 'No se pueden guardar sus preferencias.', - 'Database optimization done.' => 'Optimización de la base de datos terminada.', - 'Your project have been created successfully.' => 'El proyecto ha sido creado correctamente.', - 'Unable to create your project.' => 'No se puede crear el proyecto.', - 'Project updated successfully.' => 'El proyecto ha sido actualizado correctamente.', - 'Unable to update this project.' => 'No se puede actualizar el proyecto.', - 'Unable to remove this project.' => 'No se puede eliminar este proyecto.', - 'Project removed successfully.' => 'El proyecto ha sido eliminado correctamente.', - 'Project activated successfully.' => 'El proyecto ha sido activado correctamente.', - 'Unable to activate this project.' => 'No se puede activar el proyecto.', - 'Project disabled successfully.' => 'El proyecto ha sido desactivado correctamente.', - 'Unable to disable this project.' => 'No se puede desactivar el proyecto.', - 'Unable to open this task.' => 'No se puede abrir esta tarea.', - 'Task opened successfully.' => 'La tarea ha sido abierta correctamente.', - 'Unable to close this task.' => 'No se puede cerrar esta tarea.', - 'Task closed successfully.' => 'La tarea ha sido cerrada correctamente.', - 'Unable to update your task.' => 'No se puede actualizar esta tarea.', - 'Task updated successfully.' => 'La tarea ha sido actualizada correctamente.', - 'Unable to create your task.' => 'No se puede crear esta tarea.', - 'Task created successfully.' => 'La tarea ha sido creada correctamente.', - 'User created successfully.' => 'El usuario ha sido creado correctamente.', - 'Unable to create your user.' => 'No se puede crear este usuario.', - 'User updated successfully.' => 'El usuario ha sido actualizado correctamente.', - 'Unable to update your user.' => 'No se puede actualizar este usuario.', - 'User removed successfully.' => 'El usuario ha sido creado correctamente.', - 'Unable to remove this user.' => 'No se puede crear este usuario.', - 'Board updated successfully.' => 'El tablero ha sido actualizado correctamente.', - 'Ready' => 'Preparado', - 'Backlog' => 'En espera', - 'Work in progress' => 'En curso', - 'Done' => 'Hecho', - 'Application version:' => 'Versión de la aplicación:', - 'Id' => 'Identificador', - '%d closed tasks' => '%d tareas completadas', - 'No task for this project' => 'Ninguna tarea para este proyecto', - 'Public link' => 'Enlace público', - 'Timezone' => 'Zona horaria', - 'Sorry, I didn\'t find this information in my database!' => '¡Lo siento, no he encontrado esta información en mi base de datos!', - 'Page not found' => 'Página no encontrada', - 'Complexity' => 'Complejidad', - 'Task limit' => 'Número máximo de tareas', - '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', - 'Invalid date' => 'Fecha no válida', - 'Automatic actions' => 'Acciones automatizadas', - 'Your automatic action have been created successfully.' => 'La acción automatizada ha sido creada correctamente.', - 'Unable to create your automatic action.' => 'No se puede crear esta acción automatizada.', - 'Remove an action' => 'Eliminar una acción', - 'Unable to remove this action.' => 'No se puede eliminar esta acción.', - 'Action removed successfully.' => 'La acción ha sido eliminada correctamente.', - 'Automatic actions for the project "%s"' => 'Acciones automatizadas para el proyecto «%s»', - 'Add an action' => 'Añadir una acción', - 'Event name' => 'Nombre del evento', - 'Action name' => 'Nombre de la acción', - 'Action parameters' => 'Parámetros de la acción', - 'Action' => 'Acción', - 'Event' => 'Evento', - 'When the selected event occurs execute the corresponding action.' => 'Cuando tiene lugar el evento seleccionado, ejecutar la acción correspondiente.', - 'Next step' => 'Etapa siguiente', - 'Define action parameters' => 'Define los parámetros de la acción', - 'Do you really want to remove this action: "%s"?' => '¿Realmente desea eliminar esta acción «%s»?', - 'Remove an automatic action' => 'Eliminar una acción automatizada', - 'Assign the task to a specific user' => 'Asignar una tarea a un usuario especifico', - 'Assign the task to the person who does the action' => 'Asignar la tarea al usuario que hace la acción', - 'Duplicate the task to another project' => 'Duplicar la tarea a otro proyecto', - 'Move a task to another column' => 'Mover una tarea a otra columna', - 'Task modification' => 'Modificación de una tarea', - 'Task creation' => 'Creación de una tarea', - 'Closing a task' => 'Cerrar una tarea', - 'Assign a color to a specific user' => 'Asignar un color a un usuario específico', - 'Column title' => 'Título de la columna', - 'Position' => 'Posición', - 'Duplicate to another project' => 'Duplicar a otro proyecto', - 'Duplicate' => 'Duplicar', - 'link' => 'enlace', - 'Comment updated successfully.' => 'El comentario ha sido actualizado correctamente.', - 'Unable to update your comment.' => 'No se puede actualizar este comentario.', - 'Remove a comment' => 'Eliminar un comentario', - 'Comment removed successfully.' => 'El comentario ha sido eliminado correctamente.', - 'Unable to remove this comment.' => 'No se puede eliminar este comentario.', - 'Do you really want to remove this comment?' => '¿Realmente desea eliminar este comentario?', - 'Current password for the user "%s"' => 'Contraseña actual para el usuario: «%s»', - 'The current password is required' => 'La contraseña es obligatoria', - 'Wrong password' => 'Contraseña incorrecta', - 'Unknown' => 'Desconocido', - 'Last logins' => 'Últimos ingresos', - 'Login date' => 'Fecha de ingreso', - 'Authentication method' => 'Método de autenticación', - 'IP address' => 'Dirección IP', - 'User agent' => 'Agente de usuario (User agent)', - 'Persistent connections' => 'Conexión persistente', - 'No session.' => 'No existe sesión.', - 'Expiration date' => 'Fecha de expiración', - 'Remember Me' => 'Recuérdame', - 'Creation date' => 'Fecha de creación', - 'Everybody' => 'Todo el mundo', - 'Open' => 'Abierto', - 'Closed' => 'Cerrado', - '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', - 'Email address invalid' => 'Dirección de correo inválida', - 'Your external account is not linked anymore to your profile.' => 'Su cuenta externa se ha desvinculado de su perfil.', - 'Unable to unlink your external account.' => 'No se puede desvincular su cuenta externa.', - 'External authentication failed' => 'Falló la autenticación externa', - 'Your external account is linked to your profile successfully.' => 'Su cuenta externa se ha vinculado correctamente con su perfil.', - 'Email' => 'Correo electrónico', - 'Task removed successfully.' => 'Tarea eliminada correctamente.', - 'Unable to remove this task.' => 'No se puede eliminar esta tarea.', - 'Remove a task' => 'Eliminar una tarea', - 'Do you really want to remove this task: "%s"?' => '¿Realmente desea eliminar esta tarea: «%s»?', - 'Assign automatically a color based on a category' => 'Asignar un color de forma automática basándose en la categoría', - 'Assign automatically a category based on a color' => 'Asignar una categoría de forma automática basándose en el color', - 'Task creation or modification' => 'Creación o Edición de Tarea', - 'Category' => 'Categoría', - 'Category:' => 'Categoría:', - 'Categories' => 'Categorías', - 'Your category have been created successfully.' => 'Se ha creado su categoría correctamente.', - 'Unable to create your category.' => 'No se puede crear su categoría.', - 'Your category have been updated successfully.' => 'Se ha actualizado su categoría correctamente.', - 'Unable to update your category.' => 'No se puede actualizar su categoría.', - 'Remove a category' => 'Eliminar una categoría', - 'Category removed successfully.' => 'Categoría eliminada correctamente.', - 'Unable to remove this category.' => 'No se puede eliminar esta categoría.', - 'Category modification for the project "%s"' => 'Modificación de la categoría para el proyecto «%s»', - 'Category Name' => 'Nombre de la categoría', - 'Add a new category' => 'Añadir una nueva categoría', - 'Do you really want to remove this category: "%s"?' => '¿Realmente desea eliminar esta categoría: «%s»?', - 'All categories' => 'Todas las categorías', - 'No category' => 'Sin categoría', - 'The name is required' => 'El nombre es obligatorio', - 'Remove a file' => 'Eliminar un fichero', - 'Unable to remove this file.' => 'No se puede eliminar este fichero.', - 'File removed successfully.' => 'Fichero eliminado correctamente.', - 'Attach a document' => 'Adjuntar un documento', - 'Do you really want to remove this file: "%s"?' => '¿Realmente desea eliminar este fichero: «%s»?', - 'Attachments' => 'Adjuntos', - 'Edit the task' => 'Modificar la tarea', - 'Add a comment' => 'Añadir un comentario', - 'Edit a comment' => 'Modificar un comentario', - 'Summary' => 'Resumen', - 'Time tracking' => 'Seguimiento temporal', - 'Estimate:' => 'Estimado:', - 'Spent:' => 'Transcurrido:', - 'Do you really want to remove this sub-task?' => '¿Realmente desea eliminar esta subtarea?', - 'Remaining:' => 'Restante:', - 'hours' => 'horas', - 'spent' => 'transcurrido', - 'estimated' => 'estimado', - 'Sub-Tasks' => 'Subtareas', - 'Add a sub-task' => 'Añadir una subtarea', - 'Original estimate' => 'Estimación original', - 'Create another sub-task' => 'Crear otra subtarea', - 'Time spent' => 'Tiempo transcurrido', - 'Edit a sub-task' => 'Modificar una subtarea', - 'Remove a sub-task' => 'Eliminar una subtarea', - 'The time must be a numeric value' => 'El tiempo debe de ser un valor numérico', - 'Todo' => 'Por hacer', - 'In progress' => 'En progreso', - 'Sub-task removed successfully.' => 'Subtarea eliminada correctamente.', - 'Unable to remove this sub-task.' => 'No se puede eliminar esta subtarea.', - 'Sub-task updated successfully.' => 'Subtarea actualizada correctamente.', - 'Unable to update your sub-task.' => 'No se puede actualizar esta subtarea.', - 'Unable to create your sub-task.' => 'No se puede crear la subtarea.', - 'Sub-task added successfully.' => 'Subtarea añadida correctamente.', - 'Maximum size: ' => 'Tamaño máximo: ', - 'Unable to upload the file.' => 'No se puede cargar el fichero.', - 'Display another project' => 'Mostrar otro proyecto', - 'Created by %s' => 'Creado por %s', - 'Tasks Export' => 'Exportar tareas', - 'Tasks exportation for "%s"' => 'Exportación de tareas para «%s»', - 'Start Date' => 'Fecha de inicio', - 'End Date' => 'Fecha final', - 'Execute' => 'Ejecutar', - 'Task Id' => 'Identificador de tarea', - 'Creator' => 'Creador', - 'Modification date' => 'Fecha de modificación', - 'Completion date' => 'Fecha de finalización', - 'Clone' => 'Clonar', - 'Project cloned successfully.' => 'Proyecto clonado correctamente.', - 'Unable to clone this project.' => 'No se puede clonar este proyecto.', - 'Enable email notifications' => 'Habilitar notificaciones por correo electrónico', - 'Task position:' => 'Posición de la tarea:', - 'The task #%d have been opened.' => 'La tarea #%d ha sido abierta.', - 'The task #%d have been closed.' => 'La tarea #%d ha sido cerrada.', - 'Sub-task updated' => 'Subtarea actualizada', - 'Title:' => 'Título:', - 'Status:' => 'Estado:', - 'Assignee:' => 'Responsable:', - 'Time tracking:' => 'Control de tiempo:', - 'New sub-task' => 'Nueva subtarea', - 'New attachment added "%s"' => 'Nuevo adjunto añadido «%s»', - 'New comment posted by %s' => 'Nuevo comentario añadido por %s', - 'New attachment' => 'Nuevo adjunto', - 'New comment' => 'Nuevo comentario', - 'Comment updated' => 'Comentario actualizado', - 'New subtask' => 'Nueva subtarea', - 'Subtask updated' => 'Subtarea actualizada', - 'Task updated' => 'Tarea actualizada', - 'Task closed' => 'Tarea cerrada', - 'Task opened' => 'Tarea abierta', - 'I want to receive notifications only for those projects:' => 'Quiero recibir notificaciones sólo de estos proyectos:', - 'view the task on Kanboard' => 'ver la tarea en Kanboard', - 'Public access' => 'Acceso público', - 'Active tasks' => 'Tareas activas', - 'Disable public access' => 'Desactivar acceso público', - 'Enable public access' => 'Activar acceso público', - 'Public access disabled' => 'Acceso público desactivado', - 'Do you really want to disable this project: "%s"?' => '¿Realmente desea desactivar este proyecto: «%s»?', - 'Do you really want to enable this project: "%s"?' => '¿Realmente desea activar este proyecto: «%s»?', - 'Project activation' => 'Activación de proyecto', - 'Move the task to another project' => 'Mover la tarea a otro proyecto', - 'Move to another project' => 'Mover a otro proyecto', - 'Do you really want to duplicate this task?' => '¿Realmente desea duplicar esta tarea?', - 'Duplicate a task' => 'Duplicar una tarea', - 'External accounts' => 'Cuentas externas', - 'Account type' => 'Tipo de cuenta', - 'Local' => 'Local', - 'Remote' => 'Remota', - 'Enabled' => 'Activada', - 'Disabled' => 'Desactivada', - 'Username:' => 'Nombre de usuario:', - 'Name:' => 'Nombre:', - 'Email:' => 'Correo electrónico:', - 'Notifications:' => 'Notificaciones:', - 'Notifications' => 'Notificaciones', - 'Account type:' => 'Tipo de cuenta:', - 'Edit profile' => 'Modificar perfil', - 'Change password' => 'Cambiar contraseña', - 'Password modification' => 'Modificación de contraseña', - 'External authentications' => 'Autenticación externa', - 'Never connected.' => 'Nunca se ha conectado.', - 'No external authentication enabled.' => 'Sin autenticación externa activa.', - 'Password modified successfully.' => 'Contraseña cambiada correctamente.', - 'Unable to change the password.' => 'No se puede cambiar la contraseña.', - 'Change category' => 'Cambiar categoría', - '%s updated the task %s' => '%s actualizó la tarea %s', - '%s opened the task %s' => '%s abrió la tarea %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s movió la tarea %s a la posición #%d de la columna «%s»', - '%s moved the task %s to the column "%s"' => '%s movió la tarea %s a la columna «%s»', - '%s created the task %s' => '%s creó la tarea %s', - '%s closed the task %s' => '%s cerró la tarea %s', - '%s created a subtask for the task %s' => '%s creó una subtarea para la tarea %s', - '%s updated a subtask for the task %s' => '%s actualizó una subtarea para la tarea %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Asignada a %s con una estimación de %s/%sh', - 'Not assigned, estimate of %sh' => 'No asignada, se estima en %sh', - '%s updated a comment on the task %s' => '%s actualizó un comentario de la tarea %s', - '%s commented the task %s' => '%s comentó la tarea %s', - '%s\'s activity' => 'Actividad de %s', - 'RSS feed' => 'Fuentes RSS', - '%s updated a comment on the task #%d' => '%s actualizó un comentario de la tarea #%d', - '%s commented on the task #%d' => '%s comentó la tarea #%d', - '%s updated a subtask for the task #%d' => '%s actualizó una subtarea de la tarea #%d', - '%s created a subtask for the task #%d' => '%s creó una subtarea de la tarea #%d', - '%s updated the task #%d' => '%s actualizó la tarea #%d', - '%s created the task #%d' => '%s creó la tarea #%d', - '%s closed the task #%d' => '%s cerró la tarea #%d', - '%s open the task #%d' => '%s abrió la tarea #%d', - '%s moved the task #%d to the column "%s"' => '%s movió la tarea #%d a la columna «%s»', - '%s moved the task #%d to the position %d in the column "%s"' => '%s movió la tarea #%d a la posición %d de la columna «%s»', - 'Activity' => 'Actividad', - 'Default values are "%s"' => 'Los valores por defecto son «%s»', - 'Default columns for new projects (Comma-separated)' => 'Columnas por defecto para los nuevos proyectos (separadas mediante comas)', - 'Task assignee change' => 'Cambiar responsable de la tarea', - '%s change the assignee of the task #%d to %s' => '%s cambió el responsable de la tarea #%d por %s', - '%s changed the assignee of the task %s to %s' => '%s cambió el responsable de la tarea %s por %s', - 'New password for the user "%s"' => 'Nueva contraseña para el usuario «%s»', - 'Choose an event' => 'Seleccione un evento', - 'Create a task from an external provider' => 'Crear una tarea a partir de un proveedor externo', - 'Change the assignee based on an external username' => 'Cambiar el responsable basado en un nombre de usuario externo', - 'Change the category based on an external label' => 'Cambiar la categoría basado en una etiqueta externa', - 'Reference' => 'Referencia', - 'Label' => 'Etiqueta', - 'Database' => 'Base de datos', - 'About' => 'Acerca de', - 'Database driver:' => 'Controlador de la base de datos (driver):', - 'Board settings' => 'Preferencias del tablero', - 'Webhook settings' => 'Preferencias del disparador web (webhook)', - 'Reset token' => 'Limpiar token', - 'API endpoint:' => 'Endpoint del API:', - 'Refresh interval for private board' => 'Intervalo de refresco del tablero privado', - 'Refresh interval for public board' => 'Intervalo de refresco del tablero público', - 'Task highlight period' => 'Periodo de realce de la tarea', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Periodo (en segundos) para considerar que una tarea fue modificada recientemente (0 para deshabilitar, 2 días por defecto)', - 'Frequency in second (60 seconds by default)' => 'Frecuencia en segundos (60 segundos por defecto)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frecuencia en segundos (0 para deshabilitar esta característica, 10 segundos por defecto)', - 'Application URL' => 'URL de la aplicación', - 'Token regenerated.' => 'Token regenerado.', - 'Date format' => 'Formato de la fecha', - 'ISO format is always accepted, example: "%s" and "%s"' => 'El formato ISO siempre es aceptado, ejemplo: «%s» y «%s»', - 'New private project' => 'Nuevo proyecto privado', - 'This project is private' => 'Este proyecto es privado', - 'Add' => 'Añadir', - 'Start date' => 'Fecha de inicio', - 'Time estimated' => 'Tiempo estimado', - 'There is nothing assigned to you.' => 'No tiene nada asignado.', - 'My tasks' => 'Mis tareas', - 'Activity stream' => 'Flujo de actividad', - 'Dashboard' => 'Tablero', - 'Confirmation' => 'Confirmación', - 'Allow everybody to access to this project' => 'Permitir a cualquiera acceder a este proyecto', - 'Everybody have access to this project.' => 'Cualquiera tiene acceso a este proyecto.', - 'Webhooks' => 'Disparadores web (webhooks)', - 'API' => 'API', - 'Create a comment from an external provider' => 'Crear un comentario a partir de un proveedor externo', - 'Project management' => 'Administración del proyecto', - 'My projects' => 'Mis proyectos', - 'Columns' => 'Columnas', - 'Task' => 'Tarea', - 'Your are not member of any project.' => 'No eres miembro de ningún proyecto.', - 'Percentage' => 'Porcentaje', - 'Number of tasks' => 'Número de tareas', - 'Task distribution' => 'Distribución de tareas', - 'Reportings' => 'Informes', - 'Task repartition for "%s"' => 'Repartición de tareas para «%s»', - 'Analytics' => 'Analítica', - 'Subtask' => 'Subtarea', - 'My subtasks' => 'Mis subtareas', - 'User repartition' => 'Repartición de usuarios', - 'User repartition for "%s"' => 'Repartición de usuarios para «%s»', - 'Clone this project' => 'Clonar este proyecto', - 'Column removed successfully.' => 'Columna eliminada correctamente.', - 'Not enough data to show the graph.' => 'No hay suficiente información para mostrar el gráfico.', - 'Previous' => 'Anterior', - 'The id must be an integer' => 'El id debe ser un entero', - 'The project id must be an integer' => 'El id del proyecto debe ser un entero', - 'The status must be an integer' => 'El estado debe ser un entero', - 'The subtask id is required' => 'El id de la subtarea es obligatorio', - 'The subtask id must be an integer' => 'El id de la subtarea debe ser un entero', - 'The task id is required' => 'El id de la tarea es obligatorio', - 'The task id must be an integer' => 'El id de la tarea debe ser un entero', - 'The user id must be an integer' => 'El id del usuario debe ser un entero', - 'This value is required' => 'Este valor es obligatorio', - 'This value must be numeric' => 'Este valor debe ser numérico', - 'Unable to create this task.' => 'No se puede crear esta tarea.', - 'Cumulative flow diagram' => 'Diagrama de flujo acumulativo', - 'Cumulative flow diagram for "%s"' => 'Diagrama de flujo acumulativo para «%s»', - 'Daily project summary' => 'Resumen diario del proyecto', - 'Daily project summary export' => 'Exportar resumen diario del proyecto', - 'Daily project summary export for "%s"' => 'Exportar resumen diario del proyecto para «%s»', - 'Exports' => 'Exportaciones', - 'This export contains the number of tasks per column grouped per day.' => 'Esta exportación contiene el número de tareas por columna agrupadas por día.', - 'Active swimlanes' => 'Calles activas', - 'Add a new swimlane' => 'Añadir nueva calle', - 'Change default swimlane' => 'Cambiar la calle por defecto', - 'Default swimlane' => 'Calle por defecto', - 'Do you really want to remove this swimlane: "%s"?' => '¿Realmente desea eliminar esta calle: «%s»?', - 'Inactive swimlanes' => 'Calles inactivas', - 'Remove a swimlane' => 'Eliminar una calle', - 'Show default swimlane' => 'Mostrar calle por defecto', - 'Swimlane modification for the project "%s"' => 'Modificación de la calle para el proyecto «%s»', - 'Swimlane removed successfully.' => 'Calle eliminada correctamente.', - 'Swimlanes' => 'Calles', - 'Swimlane updated successfully.' => 'Calle actualizada correctamente.', - 'The default swimlane have been updated successfully.' => 'La calle por defecto ha sido actualizada correctamente.', - 'Unable to remove this swimlane.' => 'No es posible eliminar esta calle.', - 'Unable to update this swimlane.' => 'No es posible actualizar esta calle.', - 'Your swimlane have been created successfully.' => 'Su calle ha sido creada correctamente.', - 'Example: "Bug, Feature Request, Improvement"' => 'Ejemplo: "Error, Solicitud de característica, Mejora', - 'Default categories for new projects (Comma-separated)' => 'Categorías por defecto para nuevos proyectos (separadas por comas)', - 'Integrations' => 'Integraciones', - 'Integration with third-party services' => 'Integración con servicios de terceros', - 'Subtask Id' => 'Identificador de subtarea', - 'Subtasks' => 'Subtareas', - 'Subtasks Export' => 'Exportación de subtareas', - 'Subtasks exportation for "%s"' => 'Exportación de subtareas para «%s»', - 'Task Title' => 'Título de la tarea', - 'Untitled' => 'Sin título', - 'Application default' => 'Predefinido por la aplicación', - 'Language:' => 'Idioma:', - 'Timezone:' => 'Zona horaria:', - 'All columns' => 'Todas las columnas', - 'Calendar' => 'Calendario', - 'Next' => 'Siguiente', - '#%d' => '#%d', - 'All swimlanes' => 'Todas las calles', - 'All colors' => 'Todos los colores', - 'Moved to column %s' => 'Movida a la columna %s', - 'User dashboard' => 'Tablero de usuario', - 'Allow only one subtask in progress at the same time for a user' => 'Permitir sólo una subtarea en progreso a la vez para cada usuario', - 'Edit column "%s"' => 'Modificar la columna %s', - 'Select the new status of the subtask: "%s"' => 'Seleccionar el nuevo estado de la subtarea: «%s»', - 'Subtask timesheet' => 'Hoja temporal de la subtarea', - 'There is nothing to show.' => 'No hay nada que mostrar.', - 'Time Tracking' => 'Seguimiento temporal', - 'You already have one subtask in progress' => 'Ya tiene una subtarea en progreso', - 'Which parts of the project do you want to duplicate?' => '¿Qué partes del proyecto desea duplicar?', - 'Disallow login form' => 'Deshabilitar formulario de ingreso', - 'Start' => 'Inicio', - 'End' => 'Fin', - 'Task age in days' => 'Edad de la tarea en días', - 'Days in this column' => 'Días en esta columna', - '%dd' => '%dd', - 'Add a new link' => 'Añadir nuevo enlace', - 'Do you really want to remove this link: "%s"?' => '¿Realmente desea eliminar este enlace: «%s»?', - 'Do you really want to remove this link with task #%d?' => '¿Realmente desea eliminar este enlace con la tarea #%d?', - 'Field required' => 'Campo requerido', - 'Link added successfully.' => 'Enlace añadido correctamente.', - 'Link updated successfully.' => 'Enlace actualizado correctamente.', - 'Link removed successfully.' => 'Enlace eliminado correctamente.', - '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', - 'Unable to create your link.' => 'No se puede crear el enlace.', - 'Unable to update your link.' => 'No se puede actualizar el enlace.', - 'Unable to remove this link.' => 'No se puede eliminar este enlace.', - 'relates to' => 'se refiere a', - 'blocks' => 'bloquea', - 'is blocked by' => 'está bloqueada por', - 'duplicates' => 'duplica', - 'is duplicated by' => 'está duplicada por', - 'is a child of' => 'es un hijo de', - 'is a parent of' => 'es un padre de', - 'targets milestone' => 'hito de objetivos', - 'is a milestone of' => 'es un hito de', - 'fixes' => 'arregla', - 'is fixed by' => 'es arreglada por', - 'This task' => 'Esta tarea', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Expandir tareas', - 'Collapse tasks' => 'Colapsar tareas', - 'Expand/collapse tasks' => 'Expande/colapsa tareas', - 'Close dialog box' => 'Cerrar caja de diálogo', - 'Submit a form' => 'Enviar formulario', - 'Board view' => 'Vista de tablero', - 'Keyboard shortcuts' => 'Atajos de teclado', - 'Open board switcher' => 'Abrir conmutador de tablero', - 'Application' => 'Aplicación', - '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', - 'CAD - Canadian Dollar' => 'CAD - Dólar canadiense', - 'CHF - Swiss Francs' => 'CHF - Francos suizos', - 'Custom Stylesheet' => 'Hoja de estilo Personalizada', - 'download' => 'descargar', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Libra británica', - 'INR - Indian Rupee' => 'INR - Rupia india', - 'JPY - Japanese Yen' => 'JPY - Yen japonés', - 'NZD - New Zealand Dollar' => 'NZD - Dóloar neocelandés', - 'RSD - Serbian dinar' => 'RSD - Dinar serbio', - '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', - 'Move the task to another column when assignee is cleared' => 'Mover la tarea a otra columna al quitar el responsable', - 'Source column' => 'Columna fuente', - 'Transitions' => 'Transiciones', - 'Executer' => 'Ejecutor', - 'Time spent in the column' => 'Tiempo transcurrido en la columna', - 'Task transitions' => 'Transiciones de tarea', - 'Task transitions export' => 'Exportar transiciones de tarea', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Este informe contiene todos los movimientos de columna para cada tarea con la fecha, el usuario y el tiempo transcurrido en cada transición.', - '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.', - 'Webhook URL' => 'URL del disparador web (webhook)', - '%s remove the assignee of the task %s' => '%s quita el responsable de la tarea %s', - 'Enable Gravatar images' => 'Activar imágenes Gravatar', - 'Information' => 'Información', - 'Check two factor authentication code' => 'Revisar código de autenticación en dos pasos', - 'The two factor authentication code is not valid.' => 'El código de autenticación en dos pasos no es válido.', - 'The two factor authentication code is valid.' => 'El código de autenticación en dos pasos es válido.', - 'Code' => 'Código', - 'Two factor authentication' => 'Autenticación en dos pasos', - 'This QR code contains the key URI: ' => 'Este código QR contiene la clave URI: ', - 'Check my code' => 'Revisar mi código', - 'Secret key: ' => 'Clave secreta: ', - 'Test your device' => 'Probar su dispositivo', - 'Assign a color when the task is moved to a specific column' => 'Asignar un color al mover la tarea a una columna específica', - '%s via Kanboard' => '%s vía Kanboard', - 'Burndown chart for "%s"' => 'Trabajo pendiente para «%s»', - 'Burndown chart' => 'Trabajo pendiente', - 'This chart show the task complexity over the time (Work Remaining).' => 'Este diagrama muestra la complejidad de la tarea a lo largo del tiempo (trabajo restante).', - 'Screenshot taken %s' => 'Pantallazo tomado el %s', - 'Add a screenshot' => 'Añadir un pantallazo', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Capture un patallazo y pulse CTRL+V o ⌘+V para pegar aquí.', - 'Screenshot uploaded successfully.' => 'Pantallazo cargado correctamente.', - 'SEK - Swedish Krona' => 'SEK - Corona sueca', - 'Identifier' => 'Identificador', - 'Disable two factor authentication' => 'Desactivar la autenticación en dos pasos', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => '¿Realmente desea desactivar la autenticación en dos pasos para este usuario: «%s»?', - 'Edit link' => 'Modificar enlace', - 'Start to type task title...' => 'Empiece a escribir el título de la tarea...', - 'A task cannot be linked to itself' => 'Una tarea no se puede enlazar con sigo misma', - 'The exact same link already exists' => 'El mismo enlace ya existe', - 'Recurrent task is scheduled to be generated' => 'Tarea recurrente programada para ser generada', - 'Score' => 'Puntuación', - 'The identifier must be unique' => 'El identificador debe ser único', - 'This linked task id doesn\'t exists' => 'El identificador de tarea no existe', - 'This value must be alphanumeric' => 'Este valor debe ser alfanumérico', - 'Edit recurrence' => 'Modificar repetición', - 'Generate recurrent task' => 'Generar una tarea recurrente', - 'Trigger to generate recurrent task' => 'Disparador para generar una tarea recurrente', - 'Factor to calculate new due date' => 'Factor para calcular la nueva fecha de entrega', - 'Timeframe to calculate new due date' => 'Calendario para calcular la nueva fecha de entrega', - 'Base date to calculate new due date' => 'Fecha base para calcular la nueva fecha de entrega', - 'Action date' => 'Fecha de la acción', - 'Base date to calculate new due date: ' => 'Fecha base para calcular la nueva fecha de entrega: ', - 'This task has created this child task: ' => 'Esta tarea ha creado esta tarea hija: ', - 'Day(s)' => 'Día(s)', - 'Existing due date' => 'Fecha de entrega existente', - 'Factor to calculate new due date: ' => 'Factor para calcular la nueva fecha de entrega: ', - 'Month(s)' => 'Mes(es)', - 'Recurrence' => 'Repetición', - 'This task has been created by: ' => 'Esta tarea ha sido creada por: ', - 'Recurrent task has been generated:' => 'Tarea recurrente generada:', - 'Timeframe to calculate new due date: ' => 'Calendario para calcular la nueva fecha de entrega: ', - 'Trigger to generate recurrent task: ' => 'Disparador para generar una tarea recurrente: ', - 'When task is closed' => 'Cuando la tarea es cerrada', - 'When task is moved from first column' => 'Cuando la tarea es movida desde la primera columna', - 'When task is moved to last column' => 'Cuando la tarea es movida a la última columna', - 'Year(s)' => 'Año(s)', - 'Calendar settings' => 'Preferencias del calendario', - 'Project calendar view' => 'Vista de calendario del proyecto', - 'Project settings' => 'Preferencias del proyecto', - 'Show subtasks based on the time tracking' => 'Mostrar subtareas en base al seguimiento temporal', - 'Show tasks based on the creation date' => 'Mostrar tareas en base a la fecha de creación', - 'Show tasks based on the start date' => 'Mostrar tareas en base a la fecha de inicio', - 'Subtasks time tracking' => 'Seguimiento de tiempo en subtareas', - 'User calendar view' => 'Vista de calendario del usuario', - 'Automatically update the start date' => 'Actualizar automáticamente la fecha de inicio', - 'iCal feed' => 'Fuente iCal', - 'Preferences' => 'Preferencias', - 'Security' => 'Seguridad', - 'Two factor authentication disabled' => 'Autenticación en dos pasos deshabilitada', - 'Two factor authentication enabled' => 'Autenticación en dos pasos habilitada', - 'Unable to update this user.' => 'No se puede actualizar este usuario.', - 'There is no user management for private projects.' => 'No hay gestión de usuarios para proyectos privados.', - 'User that will receive the email' => 'Usuario que recibirá el correo', - 'Email subject' => 'Asunto del correo', - 'Date' => 'Fecha', - 'Add a comment log when moving the task between columns' => 'Añadir un comentario al mover la tarea entre columnas', - 'Move the task to another column when the category is changed' => 'Mover la tarea a otra columna cuando cambie la categoría', - 'Send a task by email to someone' => 'Enviar una tarea a alguien por correo', - 'Reopen a task' => 'Reabrir tarea', - 'Column change' => 'Cambio de columna', - 'Position change' => 'Cambio de posición', - 'Swimlane change' => 'Cambio de calle', - 'Assignee change' => 'Cambio de responsable', - '[%s] Overdue tasks' => '[%s] Tareas vencidas', - 'Notification' => 'Notificación', - '%s moved the task #%d to the first swimlane' => '%s movió la tarea #%d a la primera calle', - '%s moved the task #%d to the swimlane "%s"' => '%s movió la tarea #%d a la calle «%s»', - 'Swimlane' => 'Calle', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s movió la tarea %s a la primera calle', - '%s moved the task %s to the swimlane "%s"' => '%s movió la tarea %s a la calle «%s»', - 'This report contains all subtasks information for the given date range.' => 'Este informe contiene toda la información de las subtareas para el rango de fechas proporcionado.', - 'This report contains all tasks information for the given date range.' => 'Este informe contiene toda la información de las tareas para el rango de fechas proporcionado.', - 'Project activities for %s' => 'Actividades del proyecto para %s', - 'view the board on Kanboard' => 'ver el tablero en Kanboard', - 'The task have been moved to the first swimlane' => 'Se ha movido la tarea a la primera calle', - 'The task have been moved to another swimlane:' => 'Se ha movido la tarea a otra calle:', - 'New title: %s' => 'Nuevo título: %s', - 'The task is not assigned anymore' => 'La tarea ya no está asignada', - 'New assignee: %s' => 'Nuevo responsable: %s', - 'There is no category now' => 'En este momento no hay categorías', - 'New category: %s' => 'Nueva categoría: %s', - 'New color: %s' => 'Nuevo color: %s', - 'New complexity: %d' => 'Nueva complejidad: %d', - 'The due date have been removed' => 'Se ha quitado la fecha de entrega', - 'There is no description anymore' => 'Ya no hay descripción', - 'Recurrence settings have been modified' => 'Se han modificado los valores recurrentes', - 'Time spent changed: %sh' => 'Se ha cambiado el tiempo empleado: %sh', - 'Time estimated changed: %sh' => 'Se ha cambiado el tiempo estimado: %sh', - 'The field "%s" have been updated' => 'Se ha actualizado el campo «%s»', - 'The description has been modified:' => 'Se ha modificado la descripción:', - 'Do you really want to close the task "%s" as well as all subtasks?' => '¿Realmente desea cerrar la tarea «%s» así como todas las subtareas?', - 'I want to receive notifications for:' => 'Deseo recibir notificaciones para:', - 'All tasks' => 'Todas las tareas', - 'Only for tasks assigned to me' => 'Sólo para las tareas que me han sido asignadas', - 'Only for tasks created by me' => 'Sólo para las tareas creadas por mí', - 'Only for tasks created by me and assigned to me' => 'Sólo para las tareas creadas por mí y que me han sido asignadas', - '%%Y-%%m-%%d' => '%%d/%%M/%%Y', - 'Total for all columns' => 'Total para todas las columnas', - 'You need at least 2 days of data to show the chart.' => 'Necesitas al menos 2 días de datos para mostrar el gráfico.', - '<15m' => '<15m', - '<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', - 'Reset filters' => 'Limpiar filtros', - 'My tasks due tomorrow' => 'Mis tareas a entregar mañana', - 'Tasks due today' => 'Tareas a entregar hoy', - 'Tasks due tomorrow' => 'Tareas a entregar mañana', - 'Tasks due yesterday' => 'Tareas a entregar ayer', - 'Closed tasks' => 'Tareas cerradas', - 'Open tasks' => 'Tareas abiertas', - 'Not assigned' => 'No asignada', - 'View advanced search syntax' => 'Ver sintaxis de búsqueda avanzada', - 'Overview' => 'Resumen', - 'Board/Calendar/List view' => 'Vista de tablero/calendario/lista', - 'Switch to the board view' => 'Cambiar a vista de tablero', - 'Switch to the calendar view' => 'Cambiar a vista de calendario', - 'Switch to the list view' => 'Cambiar a vista de lista', - 'Go to the search/filter box' => 'Ir a caja de buscar/filtrar', - 'There is no activity yet.' => 'Aún no hay actividades.', - 'No tasks found.' => 'No se ha encontrado ninguna tarea.', - 'Keyboard shortcut: "%s"' => 'Atajo de teclado: %s', - 'List' => 'Lista', - 'Filter' => 'Filtro', - 'Advanced search' => 'Búsqueda avanzada', - 'Example of query: ' => 'Ejemplo de consulta: ', - 'Search by project: ' => 'Buscar por proyecto: ', - 'Search by column: ' => 'Buscar por columna: ', - 'Search by assignee: ' => 'Buscar por responsable: ', - 'Search by color: ' => 'Buscar por color: ', - 'Search by category: ' => 'Buscar por categoría: ', - 'Search by description: ' => 'Buscar por descripción: ', - 'Search by due date: ' => 'Buscar por fecha de entrega: ', - 'Lead and Cycle time for "%s"' => 'Plazo de entrega y ciclo para «%s»', - 'Average time spent into each column for "%s"' => 'Tiempo medio empleado en cada columna para «%s»', - 'Average time spent into each column' => 'Tiempo medio empleado en cada columna', - 'Average time spent' => 'Tiempo medio empleado', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Esta gráfica muestra el tiempo medio empleado en cada columna para las últimas %d tareas.', - 'Average Lead and Cycle time' => 'Plazo medio de entrega y de ciclo', - 'Average lead time: ' => 'Plazo medio de entrega: ', - 'Average cycle time: ' => 'Tiempo medio de ciclo: ', - 'Cycle Time' => 'Tiempo de ciclo', - 'Lead Time' => 'Plazo de entrega', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Esta gráfica muestra el plazo medio de entrega y de ciclo para las %d últimas tareas.', - 'Average time into each column' => 'Tiempo medio en cada columna', - 'Lead and cycle time' => 'Plazo de entrega y de ciclo', - 'Lead time: ' => 'Plazo de entrega: ', - 'Cycle time: ' => 'Tiempo de ciclo: ', - 'Time spent into each column' => 'Tiempo empleado en cada columna', - 'The lead time is the duration between the task creation and the completion.' => 'El plazo de entrega es la duración entre la creación de la tarea su finalización.', - 'The cycle time is the duration between the start date and the completion.' => 'El tiempo de ciclo es la duración entre la fecha de inicio y su finalización.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Si la tarea no se cierra, se usa la fecha actual en lugar de la de finalización.', - 'Set automatically the start date' => 'Poner la fecha de inicio de forma automática', - 'Edit Authentication' => 'Modificar autenticación', - '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.', - 'Trigger automatically subtask time tracking' => 'Disparar de forma automática el seguimiento temporal de subtarea', - 'Include closed tasks in the cumulative flow diagram' => 'Incluir tareas cerradas en el diagrama de flujo acumulado', - 'Current swimlane: %s' => 'Calle en curso: %s', - 'Current column: %s' => 'Columna en curso: %s', - 'Current category: %s' => 'Categoría en curso: %s', - 'no category' => 'no hay categoría', - 'Current assignee: %s' => 'Responsable en curso: %s', - 'not assigned' => 'sin asignar', - 'Author:' => 'Autor:', - 'contributors' => 'contribuyentes', - 'License:' => 'Licencia:', - 'License' => 'Licencia', - 'Enter the text below' => 'Introduzca el texto a continuación', - 'Gantt chart for %s' => 'Diagrama de Gantt para %s', - 'Sort by position' => 'Ordenar por posición', - 'Sort by date' => 'Ordenar por fecha', - 'Add task' => 'Añadir tarea', - 'Start date:' => 'Fecha de inicio:', - 'Due date:' => 'Fecha de entrega:', - 'There is no start date or due date for this task.' => 'No hay fecha de inicio o de entrega para esta tarea.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Mover o redimensionar una tarea cambiará la fecha inicio y de entrega de la misma.', - 'There is no task in your project.' => 'No hay tareas en su proyecto.', - 'Gantt chart' => 'Diagrama de Gantt', - 'People who are project managers' => 'Usuarios que son administradores del proyecto', - 'People who are project members' => 'Usuarios que son miembros del proyecto', - 'NOK - Norwegian Krone' => 'NOK - Corona Noruega', - 'Show this column' => 'Mostrar esta columna', - 'Hide this column' => 'Ocultar esta columna', - 'open file' => 'abrir fichero', - 'End date' => 'Fecha de fin', - 'Users overview' => 'Resumen de usuarios', - 'Members' => 'Miembros', - 'Shared project' => 'Proyecto compartido', - 'Project managers' => 'Administradores del proyecto', - 'Gantt chart for all projects' => 'Diagrama de Gantt para todos los proyectos', - 'Projects list' => 'Lista de proyectos', - 'Gantt chart for this project' => 'Diagrama de Gantt para este proyecto', - 'Project board' => 'Tablero del proyecto', - 'End date:' => 'Fecha de fin:', - 'There is no start date or end date for this project.' => 'No existe fecha de inicio o de fin para este proyecto.', - 'Projects Gantt chart' => 'Diagrama de Gantt de los proyectos', - 'Change task color when using a specific task link' => 'Cambiar el color de la tarea al usar un enlace específico a tarea', - 'Task link creation or modification' => 'Creación o modificación del enlace a tarea', - 'Milestone' => 'Hito', - 'Documentation: %s' => 'Documentación: %s', - 'Switch to the Gantt chart view' => 'Cambiar a vista de diagrama de Gantt', - 'Reset the search/filter box' => 'Limpiar el filtro de búsqueda', - 'Documentation' => 'Documentación', - 'Table of contents' => 'Tabla de contenido', - 'Gantt' => 'Gantt', - 'Author' => 'Autor', - 'Version' => 'Versión', - 'Plugins' => 'Plugins', - 'There is no plugin loaded.' => 'No hay ningún plugin cargado.', - 'Set maximum column height' => 'Establecer altura máxima de la columna', - 'Remove maximum column height' => 'Eliminar altura máxima de la columna', - 'My notifications' => 'Mis notificaciones', - 'Custom filters' => 'Filtros personalizados', - 'Your custom filter have been created successfully.' => 'Tus filtros personalizados han sido creados correctamente.', - 'Unable to create your custom filter.' => 'No se ha podido crear tu filtro personalizado.', - 'Custom filter removed successfully.' => 'El filtro personalizado ha sido eliminado correctamente.', - 'Unable to remove this custom filter.' => 'No se ha podido eliminar tu filtro personalizado.', - 'Edit custom filter' => 'Modificar filtro personalizado', - 'Your custom filter have been updated successfully.' => 'Tu filtro personalizado ha sido actualizado correctamente.', - 'Unable to update custom filter.' => 'No se ha podido actualizar tu filtro personalizado.', - 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Nuevo adjunto en la tarea #%d: %s', - 'New comment on task #%d' => 'Nuevo comentario en la tarea #%d', - 'Comment updated on task #%d' => 'Comentario actualizado en la tarea #%d', - 'New subtask on task #%d' => 'Nueva subtarea en la tarea #%d', - 'Subtask updated on task #%d' => 'Subtarea actualizada en la tarea #%d', - 'New task #%d: %s' => 'Nueva tarea #%d: %s', - 'Task updated #%d' => 'Tarea actualizada #%d', - 'Task #%d closed' => 'Tarea #%d cerrada', - 'Task #%d opened' => 'Tarea #%d abierta', - 'Column changed for task #%d' => 'Columna cambiada para la tarea #%d', - 'New position for task #%d' => 'Nueva posición para tarea #%d', - 'Swimlane changed for task #%d' => 'Se cambió la calle de la tarea #%d', - 'Assignee changed on task #%d' => 'Se cambió el responsable de la tarea #%d', - '%d overdue tasks' => '%d tareas atrasadas', - 'Task #%d is overdue' => 'La tarea #%d está atrasada', - 'No new notifications.' => 'No hay nuevas notificaciones.', - 'Mark all as read' => 'Marcar todo como leído', - 'Mark as read' => 'Marcar como leído', - 'Total number of tasks in this column across all swimlanes' => 'Número total de tareas en esta columna a través de todas las calles', - 'Collapse swimlane' => 'Contraer calle', - 'Expand swimlane' => 'Ampliar calle', - 'Add a new filter' => 'Añadir nuevo filtro', - 'Share with all project members' => 'Compartir con todos los miembros del proyecto', - 'Shared' => 'Compartido', - '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!', - 'Import users from CSV file' => 'Importar usuarios desde archivo CSV', - '%d user(s) have been imported successfully.' => '%d usuario(s) se han importado correctamente.', - 'Comma' => 'Coma', - 'Semi-colon' => 'Punto y coma', - 'Tab' => 'Tabulación', - 'Vertical bar' => 'Barra vertical', - 'Double Quote' => 'Comilla doble', - 'Single Quote' => 'Comilla simple', - '%s attached a file to the task #%d' => '%s adjuntó un archivo en la tarea #%d', - 'There is no column or swimlane activated in your project!' => '¡No hay ninguna columna o calle activada en su proyecto!', - 'Append filter (instead of replacement)' => 'Añadir filtro (en vez de reemplazar)', - 'Append/Replace' => 'Añadir/Reemplazar', - 'Append' => 'Añadir', - 'Replace' => 'Reemplazar', - 'Import' => 'Importar', - 'change sorting' => 'Cambiar orden', - 'Tasks Importation' => 'Importación de tareas', - 'Delimiter' => 'Delimitador', - 'Enclosure' => 'Recinto', - 'CSV File' => 'Archivo CSV', - 'Instructions' => 'Indicaciones', - 'Your file must use the predefined CSV format' => 'Su archivo debe utilizar el formato CSV predeterminado', - 'Your file must be encoded in UTF-8' => 'Su archivo debe estar codificado en UTF-8', - 'The first row must be the header' => 'La primera fila debe ser el encabezado', - 'Duplicates are not verified for you' => 'Los duplicados no serán verificados', - 'The due date must use the ISO format: YYYY-MM-DD' => 'La fecha de entrega debe utilizar el formato ISO: AAAA-MM-DD', - 'Download CSV template' => 'Descargar plantilla CSV', - 'No external integration registered.' => 'No se ha registrado integración externa.', - 'Duplicates are not imported' => 'Los duplicados no son importados', - 'Usernames must be lowercase and unique' => 'Los nombres de usuario deben ser únicos y en minúsculas', - 'Passwords will be encrypted if present' => 'Las contraseñas serán cifradas si es que existen', - '%s attached a new file to the task %s' => '%s adjuntó un nuevo archivo en la tarea %s', - 'Link type' => 'Tipo de enlace', - 'Assign automatically a category based on a link' => 'Asignar una categoría automáticamente basado en un enlace', - 'BAM - Konvertible Mark' => 'BAM - Marco convertible', - 'Assignee Username' => 'Nombre de usuario del responsable', - 'Assignee Name' => 'Nombre del responsable', - 'Groups' => 'Grupos', - 'Members of %s' => 'Miembros de %s', - 'New group' => 'Nuevo grupo', - 'Group created successfully.' => 'Grupo creado correctamente.', - 'Unable to create your group.' => 'No es posible crear el grupo.', - 'Edit group' => 'Modificar grupo', - 'Group updated successfully.' => 'Grupo actualizado correctamente.', - 'Unable to update your group.' => 'No es posible actualizar el grupo.', - 'Add group member to "%s"' => 'Añadir un miembro del grupo a «%s»', - 'Group member added successfully.' => 'Miembro del grupo añadido correctamente.', - 'Unable to add group member.' => 'No es posible añadir el miembro del grupo.', - 'Remove user from group "%s"' => 'Eliminar usuario del grupo «%s»', - 'User removed successfully from this group.' => 'Usuario eliminado correctamente del grupo.', - 'Unable to remove this user from the group.' => 'No es posible eliminar este usuario del grupo.', - 'Remove group' => 'Eliminar grupo', - 'Group removed successfully.' => 'Grupo eliminado correctamente.', - 'Unable to remove this group.' => 'No es posible eliminar este grupo.', - 'Project Permissions' => 'Permisos del proyecto', - 'Manager' => 'Administrador', - 'Project Manager' => 'Administrador del proyecto', - 'Project Member' => 'Miembro del proyecto', - 'Project Viewer' => 'Observador del proyecto', - 'Your account is locked for %d minutes' => 'Tu cuenta ha sido bloqueada durante %d minutos', - 'Invalid captcha' => 'CAPTCHA inválido', - 'The name must be unique' => 'El nombre debe ser único', - 'View all groups' => 'Ver todos los grupos', - 'View group members' => 'Ver miembros del grupo', - 'There is no user available.' => 'No hay usuario disponible.', - 'Do you really want to remove the user "%s" from the group "%s"?' => '¿Realmente desea eliminar el usuario «%s» del grupo «%s»?', - 'There is no group.' => 'No hay grupo.', - 'External Id' => 'Identificador externo', - 'Add group member' => 'Añadir un miembro al grupo', - 'Do you really want to remove this group: "%s"?' => '¿Realmente desea eliminar este grupo: «%s»?', - 'There is no user in this group.' => 'No hay usuario en este grupo.', - 'Remove this user' => 'Eliminar este usuario', - 'Permissions' => 'Permisos', - 'Allowed Users' => 'Usuarios permitidos', - 'No user have been allowed specifically.' => 'Ningún usuario ha sido explícitamente permitido.', - 'Role' => 'Rol', - 'Enter user name...' => 'Ingresa nombre de usuario...', - 'Allowed Groups' => 'Grupos permitidos', - 'No group have been allowed specifically.' => 'Ningún grupo ha sido explícitamente permitido.', - 'Group' => 'Grupo', - 'Group Name' => 'Nombre del grupo', - 'Enter group name...' => 'Ingresa el nombre del grupo...', - 'Role:' => 'Rol:', - 'Project members' => 'Miembros del proyecto', - 'Compare hours for "%s"' => 'Compara horas con «%s»', - '%s mentioned you in the task #%d' => '%s te mencionó en la tarea #%d', - '%s mentioned you in a comment on the task #%d' => '%s te mencionó en un comentario en la tarea #%d', - 'You were mentioned in the task #%d' => 'Fuiste mencionado en la tarea #%d', - 'You were mentioned in a comment on the task #%d' => 'Fuiste mencionado en un comentario de la tarea #%d', - 'Mentioned' => 'Mencionado', - 'Compare Estimated Time vs Actual Time' => 'Comparar tiempo estimado vs tiempo actual', - 'Estimated hours: ' => 'Horas estimadas: ', - 'Actual hours: ' => 'Horas actuales: ', - 'Hours Spent' => 'Horas gastadas', - 'Hours Estimated' => 'Horas estimadas', - 'Estimated Time' => 'Tiempo estimado', - 'Actual Time' => 'Tiempo actual', - 'Estimated vs actual time' => 'Tiempo estimado vs real', - 'RUB - Russian Ruble' => 'RUB - Rublo ruso', - 'Assign the task to the person who does the action when the column is changed' => 'Asignar la tarea a la persona que hace la acción al cambiar de columna', - 'Close a task in a specific column' => 'Cerrar tarea en una columna especifica', - 'Time-based One-time Password Algorithm' => 'Algoritmo basado en tiempo de un solo uso', - 'Two-Factor Provider: ' => 'Proveedor de autenticación en dos pasos: ', - 'Disable two-factor authentication' => 'Deshabilitar autenticación en dos pasos', - 'Enable two-factor authentication' => 'Habilitar autenticación en dos pasos', - 'There is no integration registered at the moment.' => 'No hay ninguna integración registrada por el momento.', - 'Password Reset for Kanboard' => 'Restablecimiento de contraseña para Kanboard', - 'Forgot password?' => '¿Olvidó la contraseña?', - 'Enable "Forget Password"' => 'Habilitar "olvidar contraseña"', - 'Password Reset' => 'Restablecer contraseña', - 'New password' => 'Nueva contraseña', - 'Change Password' => 'Cambiar contraseña', - 'To reset your password click on this link:' => 'Para cambiar tu contraseña haz clic en el siguiente enlace:', - 'Last Password Reset' => 'Último cambio de contraseña', - 'The password has never been reinitialized.' => 'La contraseña nunca se ha reinicializado.', - 'Creation' => 'Creación', - 'Expiration' => 'Vencimiento', - 'Password reset history' => 'Historial de restablecimiento de contraseña', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Todas las tareas de la columna "%s" y la calle «%s» se han cerrado correctamente.', - 'Do you really want to close all tasks of this column?' => '¿Realmente desea cerrar todas las tareas de esta columna?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d tarea(s) en la columna "%s" y en la calle «%s» será(n) cerrada(s).', - 'Close all tasks of this column' => 'Cerrar todas las tareas de esta columna', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Ningún plugin ha registrado un método de notificación para el proyecto. Aún puedes configurar notificaciones individuales en tu perfil de usuario.', - 'My dashboard' => 'Mi tablero', - 'My profile' => 'Mi perfil', - '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', - 'Task priority' => 'Prioridad de la tarea', - 'General' => 'General', - 'Dates' => 'Fechas', - 'Default priority' => 'Prioridad predeterminada', - 'Lowest priority' => 'Prioridad más baja', - 'Highest priority' => 'Prioridad más alta', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Si estableces la prioridad más baja y más alta a cero esta función será deshabilitada.', - 'Close a task when there is no activity' => 'Cerrar tarea cuando no haya actividad', - 'Duration in days' => 'Duración en días', - 'Send email when there is no activity on a task' => 'Enviar correo cuando no haya actividad en una tarea', - 'Unable to fetch link information.' => 'No es posible obtener información del enlace.', - 'Daily background job for tasks' => 'Trabajo en segundo plano diario para las tareas', - 'Auto' => 'Automático', - 'Related' => 'Relacionado', - 'Attachment' => 'Adjunto', - 'Title not found' => 'No se ha encontrado el título', - 'Web Link' => 'Enlace web', - 'External links' => 'Enlaces externos', - 'Add external link' => 'Añadir enlace externo', - 'Type' => 'Tipo', - 'Dependency' => 'Dependencia', - 'Add internal link' => 'Añadir enlace interno', - 'Add a new external link' => 'Añadir un nuevo enlace externo', - 'Edit external link' => 'Modificar enlace externo', - 'External link' => 'Enlace externo', - 'Copy and paste your link here...' => 'Copia y pega tu enlace aquí...', - 'URL' => 'URL', - 'Internal links' => 'Enlaces internos', - 'Assign to me' => 'Asignarme a mí', - 'Me' => 'Yo', - 'Do not duplicate anything' => 'No duplicar nada', - 'Projects management' => 'Administración de proyectos', - 'Users management' => 'Administración de usuarios', - 'Groups management' => 'Administración de grupos', - 'Create from another project' => 'Crear a partir de otro proyecto', - 'open' => 'abierto', - 'closed' => 'cerrado', - 'Priority:' => 'Prioridad:', - 'Reference:' => 'Referencia:', - 'Complexity:' => 'Complejidad:', - 'Swimlane:' => 'Calle:', - 'Column:' => 'Columna:', - 'Position:' => 'Posición:', - 'Creator:' => 'Creador:', - 'Time estimated:' => 'Tiempo estimado:', - '%s hours' => '%s horas', - 'Time spent:' => 'Tiempo gastado:', - 'Created:' => 'Creado:', - 'Modified:' => 'Modificado:', - 'Completed:' => 'Finalizado:', - '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: ', - 'New due date: ' => 'Nueva fecha de entrega: ', - 'Start date changed: ' => 'Fecha de inicio cambiada: ', - 'Disable private projects' => 'Deshabilitar proyectos privados', - 'Do you really want to remove this custom filter: "%s"?' => '¿Realmente desea eliminar este filtro personalizado: «%s»?', - 'Remove a custom filter' => 'Eliminar el filtro personalizado', - 'User activated successfully.' => 'Usuario activado correctamente.', - 'Unable to enable this user.' => 'No es posible habilitar este usuario.', - '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', - 'Two Factor' => 'Dos factores', - 'Disable user' => 'Deshabilitar usuario', - 'Do you really want to disable this user: "%s"?' => '¿Realmente desea deshabilitar este usuario: «%s»?', - 'Enable user' => 'Habilitar usuario', - 'Do you really want to enable this user: "%s"?' => '¿Realmente desea habilitar este usuario: «%s»?', - 'Download' => 'Descargar', - 'Uploaded: %s' => 'Subido: %s', - 'Size: %s' => 'Tamaño: %s', - 'Uploaded by %s' => 'Subido por %s', - 'Filename' => 'Nombre de archivo', - 'Size' => 'Tamaño', - 'Column created successfully.' => 'Columna creada correctamente.', - 'Another column with the same name exists in the project' => 'Ya existe una columna con el mismo nombre en el proyecto', - 'Default filters' => 'Filtros predeterminados', - 'Your board doesn\'t have any columns!' => '¡Tu tablero no tiene ninguna columna!', - 'Change column position' => 'Cambiar posición de la columna', - 'Switch to the project overview' => 'Cambiar a vista general del proyecto', - 'User filters' => 'Usar filtros', - 'Category filters' => 'Filtros de categoría', - 'Upload a file' => 'Cargar archivo', - 'View file' => 'Ver archivo', - 'Last activity' => 'Última actividad', - 'Change subtask position' => 'Cambiar posición de la subtarea', - 'This value must be greater than %d' => 'Este valor debe ser mayor que %d', - 'Another swimlane with the same name exists in the project' => 'Ya existe otra calle con el mismo nombre en el proyecto', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Ejemplo: http://ejemplo.kanboard.net/ (usado para generar URLs absolutas)', - 'Actions duplicated successfully.' => 'Acciones duplicadas con éxito.', - 'Unable to duplicate actions.' => 'No se han podido duplicar las acciones.', - 'Add a new action' => 'Añadir una nueva acción', - 'Import from another project' => 'Importar de otro proyecto', - 'There is no action at the moment.' => 'No hay ninguna acción en este momento.', - 'Import actions from another project' => 'Importar acciones de otro proyecto', - 'There is no available project.' => 'No hay proyectos disponibles.', - 'Local File' => 'Archivo local', - 'Configuration' => 'Configuración', - 'PHP version:' => 'Versión de PHP:', - 'PHP SAPI:' => 'PHP SAPI:', - 'OS version:' => 'Sistema operativo:', - 'Database version:' => 'Versión de la base de datos:', - 'Browser:' => 'Navegador web:', - 'Task view' => 'Ver tarea', - 'Edit task' => 'Modificar tarea', - 'Edit description' => 'Modificar descripción', - 'New internal link' => 'Nuevo enlace interno', - 'Display list of keyboard shortcuts' => 'Mostrar la lista de atajos de teclado', - 'Menu' => 'Menú', - 'Set start date' => 'Establecer fecha de inicio', - 'Avatar' => 'Avatar', - 'Upload my avatar image' => 'Cargar imagen de avatar', - 'Remove my image' => 'Eliminar imagen', - 'The OAuth2 state parameter is invalid' => 'El parámetro estado de OAuth2 es inválido', - 'User not found.' => 'Usuario no encontrado.', - 'Search in activity stream' => 'Buscar en el río de actividad', - 'My activities' => 'Mis actividades', - 'Activity until yesterday' => 'Actividad hasta ayer', - 'Activity until today' => 'Actividad hasta hoy', - 'Search by creator: ' => 'Buscar por creador: ', - 'Search by creation date: ' => 'Buscar por fecha de creación: ', - 'Search by task status: ' => 'Buscar por estado de la tarea: ', - 'Search by task title: ' => 'Buscar por título de la tarea: ', - 'Activity stream search' => 'Búsqueda en el río de actividad', - 'Projects where "%s" is manager' => 'Proyectos donde «%s» es administrador', - 'Projects where "%s" is member' => 'Proyectos donde «%s» es miembro', - 'Open tasks assigned to "%s"' => 'Tareas abiertas asignadas a «%s»', - 'Closed tasks assigned to "%s"' => 'Tareas cerradas asignadas a «%s»', - 'Assign automatically a color based on a priority' => 'Asignar automáticamente un color basado en la prioridad', - 'Overdue tasks for the project(s) "%s"' => 'Tareas atrasadas para el proyecto(s) «%s»', - 'Upload files' => 'Cargar archivos', - 'Installed Plugins' => 'Plugins instalados', - 'Plugin Directory' => 'Directorio de plugins', - 'Plugin installed successfully.' => 'Plugin instalado correctamente.', - 'Plugin updated successfully.' => 'Plugin actualizado correctamente.', - 'Plugin removed successfully.' => 'Plugin eliminado correctamente.', - 'Subtask converted to task successfully.' => 'Subtarea convertida en tarea correctamente.', - 'Unable to convert the subtask.' => 'No se puede convertir la subtarea.', - 'Unable to extract plugin archive.' => 'No se puede extraer el plugin.', - 'Plugin not found.' => 'Plugin no encontrado.', - 'You don\'t have the permission to remove this plugin.' => 'No tiene permiso para eliminar este plugin.', - 'Unable to download plugin archive.' => 'No se puede descargar el plugin.', - 'Unable to write temporary file for plugin.' => 'No se puede escribir el fichero temporal del plugin.', - 'Unable to open plugin archive.' => 'No se puede abrir el plugin.', - 'There is no file in the plugin archive.' => 'No hay ficheros dentro del plugin.', - 'Create tasks in bulk' => 'Crear tareas en bloque', - 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'Kanboard no está configurado para instalar plugins desde la interfaz de usuario.', - 'There is no plugin available.' => 'No hay plugins disponibles.', - 'Install' => 'Instalar', - 'Update' => 'Actualizar', - 'Up to date' => 'Actualizado', - 'Not available' => 'No disponible', - 'Remove plugin' => 'Eliminar plugin', - 'Do you really want to remove this plugin: "%s"?' => '¿Realmente desea eliminar este plugin: «%s»?', - 'Uninstall' => 'Desinstalar', - 'Listing' => 'Listado', - 'Metadata' => 'Metadatos', - 'Manage projects' => 'Administrar proyectos', - 'Convert to task' => 'Convertir en tarea', - 'Convert sub-task to task' => 'Convertir subtarea en tarea', - 'Do you really want to convert this sub-task to a task?' => '¿Realmente desea convertir esta subtarea en tarea?', - 'My task title' => 'Título de la tarea', - 'Enter one task by line.' => 'Introduce una tarea por línea.', - 'Number of failed login:' => 'Número de ingresos fallidos:', - 'Account locked until:' => 'Cuenta bloqueada hasta:', - 'Email settings' => 'Preferencias de correo electrónico', - '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.' => '', - // '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' => '', -); diff --git a/sources/app/Locale/fi_FI/translations.php b/sources/app/Locale/fi_FI/translations.php deleted file mode 100644 index 58360ab..0000000 --- a/sources/app/Locale/fi_FI/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => 'Ei mikään', - 'edit' => 'muokkaa', - 'Edit' => 'Muokkaa', - 'remove' => 'poista', - 'Remove' => 'Poista', - 'Yes' => 'Kyllä', - 'No' => 'Ei', - 'cancel' => 'peruuta', - 'or' => 'tai', - 'Yellow' => 'Keltainen', - 'Blue' => 'Sininen', - 'Green' => 'Vihreä', - 'Purple' => 'Violetti', - 'Red' => 'Punainen', - 'Orange' => 'Oranssi', - 'Grey' => 'Harmaa', - // 'Brown' => '', - // 'Deep Orange' => '', - // 'Dark Grey' => '', - // 'Pink' => '', - // 'Teal' => '', - // 'Cyan' => '', - // 'Lime' => '', - // 'Light Green' => '', - // 'Amber' => '', - 'Save' => 'Tallenna', - 'Login' => 'Sisäänkirjautuminen', - 'Official website:' => 'Virallinen verkkosivu:', - 'Unassigned' => 'Ei suorittajaa', - 'View this task' => 'Näytä tämä tehtävä', - 'Remove user' => 'Poista käyttäjä', - 'Do you really want to remove this user: "%s"?' => 'Oletko varma että haluat poistaa käyttäjän "%s"?', - 'All users' => 'Kaikki käyttäjät', - 'Username' => 'Käyttäjänimi', - 'Password' => 'Salasana', - 'Administrator' => 'Ylläpitäjä', - 'Sign in' => 'Kirjaudu sisään', - 'Users' => 'Käyttäjät', - 'No user' => 'Ei käyttäjää', - 'Forbidden' => 'Estetty', - 'Access Forbidden' => 'Pääsy estetty', - 'Edit user' => 'Muokkaa käyttäjää', - 'Logout' => 'Kirjaudu ulos', - 'Bad username or password' => 'Väärä käyttäjätunnus tai salasana', - 'Edit project' => 'Muokkaa projektia', - 'Name' => 'Nimi', - 'Projects' => 'Projektit', - 'No project' => 'Ei projektia', - 'Project' => 'Projekti', - 'Status' => 'Status', - 'Tasks' => 'Tehtävät', - 'Board' => 'Taulu', - 'Actions' => 'Toiminnot', - 'Inactive' => 'Ei aktiivinen', - 'Active' => 'Aktiivinen', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Haluatko varmasti poistaa projektin: "%s"?', - 'Remove project' => 'Poista projekti', - 'Edit the board for "%s"' => 'Muokkaa taulua projektille "%s"', - 'All projects' => 'Kaikki projektit', - 'Add a new column' => 'Lisää uusi sarake', - '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!', - 'Settings' => 'Asetukset', - 'Application settings' => 'Ohjelman asetukset', - 'Language' => 'Kieli', - 'Webhook token:' => 'Webhooks avain:', - // 'API token:' => '', - 'Database size:' => 'Tietokannan koko:', - 'Download the database' => 'Lataa tietokanta', - 'Optimize the database' => 'Optimoi tietokanta', - '(VACUUM command)' => '(VACUUM-komento)', - '(Gzip compressed Sqlite file)' => '(Gzip-pakattu Sqlite-tiedosto)', - 'Close a task' => 'Sulje tehtävä', - 'Edit a task' => 'Muokkaa tehtävää', - 'Column' => 'Sarake', - 'Color' => 'Väri', - 'Assignee' => 'Suorittaja', - 'Create another task' => 'Luo toinen tehtävä', - 'New task' => 'Uusi tehtävä', - 'Open a task' => 'Avaa tehtävä', - 'Do you really want to open this task: "%s"?' => 'Haluatko varmasti avata tehtävän: "%s"?', - 'Back to the board' => 'Takaisin tauluun', - 'There is nobody assigned' => 'Ei suorittajaa', - 'Column on the board:' => 'Sarake taululla: ', - 'Close this task' => 'Sulje tämä tehtävä', - 'Open this task' => 'Avaa tämä tehtävä', - 'There is no description.' => 'Ei kuvausta.', - 'Add a new task' => 'Lisää uusi tehtävä', - 'The username is required' => 'Käyttäjätunnut vaaditaan', - 'The maximum length is %d characters' => 'Maksimipituus on %d merkkiä', - 'The minimum length is %d characters' => 'Vähimmäispituus on %d merkkiä', - 'The password is required' => 'Salasana vaaditaan', - 'This value must be an integer' => 'Tämän arvon täytyy olla numero', - 'The username must be unique' => 'Käyttäjänimi täytyy olla uniikki', - 'The user id is required' => 'Käyttäjän id on pakollinen', - // 'Passwords don\'t match' => '', - 'The confirmation is required' => 'Varmistus vaaditaan', - 'The project is required' => 'Projekti on pakollinen', - 'The id is required' => 'ID vaaditaan', - 'The project id is required' => 'Projektin ID on pakollinen', - 'The project name is required' => 'Projektin nimi on pakollinen', - 'The title is required' => 'Otsikko vaaditaan', - 'Settings saved successfully.' => 'Asetukset tallennettu onnistuneesti.', - 'Unable to save your settings.' => 'Asetusten tallentaminen epäonnistui.', - 'Database optimization done.' => 'Tietokannan optimointi suoritettu.', - 'Your project have been created successfully.' => 'Projekti luotiin onnistuneesti.', - 'Unable to create your project.' => 'Projektin luominen epäonnistui.', - 'Project updated successfully.' => 'Projekti päivitettiin onnistuneesti.', - 'Unable to update this project.' => 'Projektin muuttaminen epäonnistui.', - 'Unable to remove this project.' => 'Projektin poistaminen epäonnistui.', - 'Project removed successfully.' => 'Projekti poistettiin onnistuneesti.', - 'Project activated successfully.' => 'Projekti aktivoitiin onnistuneesti.', - 'Unable to activate this project.' => 'Projektin aktivoiminen epäonnistui.', - 'Project disabled successfully.' => 'Projektin disabloiminen onnistui.', - 'Unable to disable this project.' => 'Projektin disabloiminen epäonnistui.', - 'Unable to open this task.' => 'Tehtävän avaus epäonnistui.', - 'Task opened successfully.' => 'Tehtävä avattiin onnistuneesti.', - 'Unable to close this task.' => 'Tehtävän sulkeminen epäonnistui.', - 'Task closed successfully.' => 'Tehtävä suljettiin onnistuneesti.', - 'Unable to update your task.' => 'Tehtävän muokkaaminen epäonnistui.', - 'Task updated successfully.' => 'Tehtävä päivitettiin onnistuneesti.', - 'Unable to create your task.' => 'Tehtävän luominen epäonnistui.', - 'Task created successfully.' => 'Tehtävä luotiin onnistuneesti.', - 'User created successfully.' => 'Käyttäjä lisättiin onnistuneesti.', - 'Unable to create your user.' => 'Käyttäjän lisäys epäonnistui.', - 'User updated successfully.' => 'Käyttäjätietojen päivitys onnistui.', - 'Unable to update your user.' => 'Käyttäjätietojen päivitys epäonnistui.', - 'User removed successfully.' => 'Käyttäjä poistettiin onnistuneesti.', - 'Unable to remove this user.' => 'Käyttäjän poistaminen epäonnistui.', - 'Board updated successfully.' => 'Taulu päivitettiin onnistuneesti.', - 'Ready' => 'Valmis', - 'Backlog' => 'Tehtäväjono', - 'Work in progress' => 'Työnalla', - 'Done' => 'Tehty', - 'Application version:' => 'Ohjelman versio:', - 'Id' => 'Id', - '%d closed tasks' => '%d suljettua tehtävää', - 'No task for this project' => 'Ei tehtävää tälle projektille', - 'Public link' => 'Julkinen linkki', - 'Timezone' => 'Aikavyöhyke', - 'Sorry, I didn\'t find this information in my database!' => 'Anteeksi, en löytänyt tätä tietoa tietokannastani', - 'Page not found' => 'Sivua ei löydy', - 'Complexity' => 'Monimutkaisuus', - 'Task limit' => 'Tehtävien maksimimäärä', - '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', - 'Invalid date' => 'Virheellinen päiväys', - 'Automatic actions' => 'Automaattiset toiminnot', - 'Your automatic action have been created successfully.' => 'Toiminto suoritettiin onnistuneesti.', - 'Unable to create your automatic action.' => 'Automaattisen toiminnon luominen epäonnistui.', - 'Remove an action' => 'Poista toiminto', - 'Unable to remove this action.' => 'Toiminnon poistaminen epäonnistui.', - 'Action removed successfully.' => 'Toiminto poistettiin onnistuneesti.', - 'Automatic actions for the project "%s"' => 'Automaattiset toiminnot projektille "%s"', - // 'Add an action' => '', - 'Event name' => 'Tapahtuman nimi', - 'Action name' => 'Toiminnon nimi', - 'Action parameters' => 'Toiminnon parametrit', - 'Action' => 'Toiminto', - 'Event' => 'Tapahtuma', - 'When the selected event occurs execute the corresponding action.' => 'Kun valittu tapahtuma tapahtuu, suorita vastaava toiminto.', - 'Next step' => 'Seuraava vaihe', - 'Define action parameters' => 'Määrittele toiminnon parametrit', - 'Do you really want to remove this action: "%s"?' => 'Oletko varma että haluat poistaa toiminnon "%s"?', - 'Remove an automatic action' => 'Poista automaattintn toiminto', - 'Assign the task to a specific user' => 'Osoita tehtävä käyttäjälle', - 'Assign the task to the person who does the action' => 'Määritä suorittaja tehtävälle', - 'Duplicate the task to another project' => 'Monista tehtävä toiselle projektille', - 'Move a task to another column' => 'Siirrä tehtävä toiseen sarakkeeseen', - 'Task modification' => 'Tehtävän muokkaus', - 'Task creation' => 'Tehtävän luominen', - 'Closing a task' => 'Tehtävää suljetaan', - 'Assign a color to a specific user' => 'Valitse väri käyttäjälle', - 'Column title' => 'Sarakkeen nimi', - 'Position' => 'Positio', - 'Duplicate to another project' => 'Kopioi toiseen projektiin', - 'Duplicate' => 'Monista', - 'link' => 'linkki', - 'Comment updated successfully.' => 'Kommentti päivitettiin onnistuneesti.', - 'Unable to update your comment.' => 'Kommentin päivitys epäonnistui.', - 'Remove a comment' => 'Poista kommentti', - 'Comment removed successfully.' => 'Kommentti poistettiin onnistuneesti.', - 'Unable to remove this comment.' => 'Kommentin poistaminen epäonnistui.', - 'Do you really want to remove this comment?' => 'Haluatko varmasti poistaa tämän kommentin?', - 'Current password for the user "%s"' => 'Käyttäjän "%s" salasana', - 'The current password is required' => 'Salasana vaaditaan', - 'Wrong password' => 'Väärä salasana', - 'Unknown' => 'Tuntematon', - 'Last logins' => 'Viimeisimmät kirjautumiset', - 'Login date' => 'Kirjautumispäivä', - 'Authentication method' => 'Autentikointimenetelmä', - 'IP address' => 'IP-Osoite', - 'User agent' => 'Selain', - 'Persistent connections' => 'Voimassa olevat yhteydet', - 'No session.' => 'Ei sessioita.', - 'Expiration date' => 'Vanhentumispäivä', - 'Remember Me' => 'Muista minut', - 'Creation date' => 'Luomispäivä', - 'Everybody' => 'Kaikki', - 'Open' => 'Avoin', - 'Closed' => 'Suljettu', - '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', - 'Email address invalid' => 'Email ei kelpaa', - // 'Your external account is not linked anymore to your profile.' => '', - // 'Unable to unlink your external account.' => '', - // 'External authentication failed' => '', - // 'Your external account is linked to your profile successfully.' => '', - 'Email' => 'Sähköposti', - 'Task removed successfully.' => 'Tehtävä poistettiin onnistuneesti.', - 'Unable to remove this task.' => 'Tehtävän poistaminen epäonnistui.', - 'Remove a task' => 'Poista tehtävä', - 'Do you really want to remove this task: "%s"?' => 'Haluatko varmasti poistaa tehtävän: "%s"?', - 'Assign automatically a color based on a category' => 'Aseta väri automaattisesti kategorian mukaan', - 'Assign automatically a category based on a color' => 'Aseta kategoria automaattisesti värin mukaan', - 'Task creation or modification' => 'Tehtävän luonti tai muuttaminen', - 'Category' => 'Kategoria', - 'Category:' => 'Kategoria:', - 'Categories' => 'Kategoriat', - 'Your category have been created successfully.' => 'Kategoria luotiin onnistuneesti.', - 'Unable to create your category.' => 'Kategorian luonti epäonnistui.', - 'Your category have been updated successfully.' => 'Kategoriaa muokattiin onnistuneesti.', - 'Unable to update your category.' => 'Kategorian muokkaaminen epäonnistui.', - 'Remove a category' => 'Poista kategoria', - 'Category removed successfully.' => 'Kategoria poistettu onnistuneesti.', - 'Unable to remove this category.' => 'Kategorian poisto epäonnistui.', - 'Category modification for the project "%s"' => 'Kategorian muutos projektissa "%s"', - 'Category Name' => 'Kategorian nimi', - 'Add a new category' => 'Lisää uusi kategoria', - 'Do you really want to remove this category: "%s"?' => 'Haluatko varmasti poistaa kategorian: "%s"?', - 'All categories' => 'Kaikki kategoriat', - 'No category' => 'Kategoriaa ei löydy', - 'The name is required' => 'Nimi vaaditaan', - 'Remove a file' => 'Poista tiedosto', - 'Unable to remove this file.' => 'Tiedoston poistaminen epäonnistui.', - 'File removed successfully.' => 'Tiedosto poistettiin onnistuneesti.', - 'Attach a document' => 'Liitä dokumentti', - 'Do you really want to remove this file: "%s"?' => 'Haluatko varmasti poistaa tiedoston: "%s"?', - 'Attachments' => 'Liitteet', - 'Edit the task' => 'Muokkaa tehtävää', - 'Add a comment' => 'Lisää kommentti', - 'Edit a comment' => 'Muokkaa kommenttia', - 'Summary' => 'Yhteenveto', - 'Time tracking' => 'Ajan seuranta', - 'Estimate:' => 'Arvio:', - 'Spent:' => 'Käytetty:', - 'Do you really want to remove this sub-task?' => 'Haluatko varmasti poistaa tämän alitehtävän?', - 'Remaining:' => 'Jäljellä', - 'hours' => 'tuntia', - 'spent' => 'käytetty', - 'estimated' => 'estimoitu', - 'Sub-Tasks' => 'Alitehtävät', - 'Add a sub-task' => 'Lisää alitehtävä', - 'Original estimate' => 'Alkuperäinen estimaatti', - 'Create another sub-task' => 'Lisää toinen alitehtävä', - 'Time spent' => 'Käytetty aika', - 'Edit a sub-task' => 'Muokkaa alitehtävää', - 'Remove a sub-task' => 'Poista alitehtävä', - 'The time must be a numeric value' => 'Ajan pitää olla numero', - 'Todo' => 'Todo', - 'In progress' => 'Työnalla', - 'Sub-task removed successfully.' => 'Alitehtävä poistettu onnistuneesti.', - 'Unable to remove this sub-task.' => 'Alitehtävän poistaminen epäonnistui.', - 'Sub-task updated successfully.' => 'Alitehtävä päivitettiin onnistuneesti.', - 'Unable to update your sub-task.' => 'Alitehtävän päivitys epäonnistui.', - 'Unable to create your sub-task.' => 'Alitehtävän luonti epäonnistui.', - 'Sub-task added successfully.' => 'Alitehtävä luotiin onnistuneesti.', - 'Maximum size: ' => 'Maksimikoko: ', - 'Unable to upload the file.' => 'Tiedoston lataus epäonnistui.', - 'Display another project' => 'Näytä toinen projekti', - 'Created by %s' => 'Luonut: %s', - 'Tasks Export' => 'Tehtävien vienti', - 'Tasks exportation for "%s"' => 'Tehtävien vienti projektilta "%s"', - 'Start Date' => 'Aloituspäivä', - 'End Date' => 'Lopetuspäivä', - 'Execute' => 'Suorita', - 'Task Id' => 'Tehtävän ID', - 'Creator' => 'Luonut', - 'Modification date' => 'Muokkauspäivä', - 'Completion date' => 'Valmistumispäivä', - 'Clone' => 'Kahdenna', - 'Project cloned successfully.' => 'Projekti kahdennettu onnistuneesti', - 'Unable to clone this project.' => 'Projektin kahdennus epäonnistui', - 'Enable email notifications' => 'Ota käyttöön sähköposti-ilmoitukset', - 'Task position:' => 'Tehtävän sijainti', - 'The task #%d have been opened.' => 'Tehtävä #%d on avattu', - 'The task #%d have been closed.' => 'Tehtävä #%d on suljettu', - 'Sub-task updated' => 'Alitehtävä päivitetty', - 'Title:' => 'Otsikko:', - 'Status:' => 'Tila:', - 'Assignee:' => 'Vastaanottaja:', - 'Time tracking:' => 'Ajan seuranta:', - 'New sub-task' => 'Uusi alitehtävä', - 'New attachment added "%s"' => 'Uusi liite lisätty "%s"', - 'New comment posted by %s' => '%s lisäsi uuden kommentin', - // 'New attachment' => '', - // 'New comment' => '', - 'Comment updated' => 'Kommentti päivitetty', - // 'New subtask' => '', - // 'Subtask updated' => '', - // 'Task updated' => '', - // 'Task closed' => '', - // 'Task opened' => '', - 'I want to receive notifications only for those projects:' => 'Haluan vastaanottaa ilmoituksia ainoastaan näistä projekteista:', - 'view the task on Kanboard' => 'katso tehtävää Kanboardissa', - 'Public access' => 'Julkinen käyttöoikeus', - 'Active tasks' => 'Aktiiviset tehtävät', - 'Disable public access' => 'Poista käytöstä julkinen käyttöoikeus', - 'Enable public access' => 'Ota käyttöön ', - 'Public access disabled' => 'Julkinen käyttöoikeus ei ole käytössä', - 'Do you really want to disable this project: "%s"?' => 'Haluatko varmasti tehdä projektista "%s" passiivisen?', - 'Do you really want to enable this project: "%s"?' => 'Haluatko varmasti aktivoida projektinen "%s"', - 'Project activation' => 'Projektin aktivointi', - 'Move the task to another project' => 'Siirrä tehtävä toiseen projektiin', - 'Move to another project' => 'Siirrä toiseen projektiin', - 'Do you really want to duplicate this task?' => 'Haluatko varmasti kahdentaa tämän tehtävän?', - 'Duplicate a task' => 'Kahdenna tehtävä', - 'External accounts' => 'Muut tilit', - 'Account type' => 'Tilin tyyppi', - 'Local' => 'Paikallinen', - 'Remote' => 'Etä', - 'Enabled' => 'Käytössä', - 'Disabled' => 'Pois käytöstä', - 'Username:' => 'Käyttäjänimi:', - 'Name:' => 'Nimi:', - 'Email:' => 'Sähköpostiosoite:', - 'Notifications:' => 'Ilmoitukset:', - 'Notifications' => 'Ilmoitukset', - 'Account type:' => 'Tilin tyyppi:', - 'Edit profile' => 'Muokkaa profiilia', - 'Change password' => 'Vaihda salasana', - 'Password modification' => 'Salasanan vaihto', - 'External authentications' => 'Muut tunnistautumistavat', - 'Never connected.' => 'Ei koskaan liitetty.', - 'No external authentication enabled.' => 'Muita tunnistautumistapoja ei ole otettu käyttöön.', - 'Password modified successfully.' => 'Salasana vaihdettu onnistuneesti.', - 'Unable to change the password.' => 'Salasanan vaihto epäonnistui.', - 'Change category' => 'Vaihda kategoria', - '%s updated the task %s' => '%s päivitti tehtävän %s', - '%s opened the task %s' => '%s avasi tehtävän %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s siirsi tehtävän %s %d. sarakkeessa "%s"', - '%s moved the task %s to the column "%s"' => '%s siirsi tehtävän %s sarakkeeseen "%s"', - '%s created the task %s' => '%s loi tehtävän %s', - '%s closed the task %s' => '%s sulki tehtävän %s', - '%s created a subtask for the task %s' => '%s loi alitehtävän tehtävälle %s', - '%s updated a subtask for the task %s' => '%s päivitti tehtävän %s alitehtävää', - 'Assigned to %s with an estimate of %s/%sh' => 'Annettu henkilölle %s arviolla %s/%sh', - 'Not assigned, estimate of %sh' => 'Ei annettu kenellekään, arvio %sh', - '%s updated a comment on the task %s' => '%s päivitti kommentia tehtävässä %s', - '%s commented the task %s' => '%s kommentoi tehtävää %s', - '%s\'s activity' => 'Henkilön %s toiminta', - 'RSS feed' => 'RSS-syöte', - '%s updated a comment on the task #%d' => '%s päivitti kommenttia tehtävässä #%d', - '%s commented on the task #%d' => '%s kommentoi tehtävää #%d', - '%s updated a subtask for the task #%d' => '%s päivitti tehtävän #%d alitehtävää', - '%s created a subtask for the task #%d' => '%s loi alitehtävän tehtävälle #%d', - '%s updated the task #%d' => '%s päivitti tehtävää #%d', - '%s created the task #%d' => '%s loi tehtävän #%d', - '%s closed the task #%d' => '%s sulki tehtävän #%d', - '%s open the task #%d' => '%s avasi tehtävän #%d', - '%s moved the task #%d to the column "%s"' => '%s siirsi tehtävän #%d sarakkeeseen "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s siirsi tehtävän #%d %d. sarakkeessa %s', - 'Activity' => 'Toiminta', - 'Default values are "%s"' => 'Oletusarvot ovat "%s"', - 'Default columns for new projects (Comma-separated)' => 'Oletussarakkeet uusille projekteille', - 'Task assignee change' => 'Tehtävän saajan vaihto', - '%s change the assignee of the task #%d to %s' => '%s vaihtoi tehtävän #%d saajaksi %s', - '%s changed the assignee of the task %s to %s' => '%s vaihtoi tehtävän %s saajaksi %s', - 'New password for the user "%s"' => 'Uusi salasana käyttäjälle "%s"', - 'Choose an event' => 'Valitse toiminta', - 'Create a task from an external provider' => 'Luo tehtävä ulkoiselta tarjoajalta', - 'Change the assignee based on an external username' => 'Vaihda tehtävän saajaa perustuen ulkoiseen käyttäjänimeen', - 'Change the category based on an external label' => 'Vaihda kategoriaa perustuen ulkoiseen labeliin', - 'Reference' => 'Viite', - 'Label' => 'Label', - 'Database' => 'Tietokanta', - 'About' => 'Tietoja', - 'Database driver:' => 'Tietokantaohjelmisto:', - 'Board settings' => 'Taulun asetukset', - 'Webhook settings' => 'Webhookin asetukset', - 'Reset token' => 'Vaihda token', - 'API endpoint:' => 'API päätepiste:', - 'Refresh interval for private board' => 'Päivitystiheys yksityisille tauluille', - 'Refresh interval for public board' => 'Päivitystiheys julkisille tauluille', - 'Task highlight period' => 'Tehtävän korostusaika', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Aika (sekunteina) kuinka kauan tehtävä voidaan katsoa äskettäin muokatuksi (0 poistaa toiminnon käytöstä, oletuksena 2 päivää)', - 'Frequency in second (60 seconds by default)' => 'Päivitystiheys sekunteina (60 sekuntia oletuksena)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Päivitystiheys sekunteina (0 poistaa toiminnon käytöstä, oletuksena 10 sekuntia)', - 'Application URL' => 'Sovelluksen URL', - 'Token regenerated.' => 'Token uudelleenluotu.', - 'Date format' => 'Päiväyksen muoto', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO-muoto on aina hyväksytty, esimerkiksi %s ja %s', - 'New private project' => 'Uusi yksityinen projekti', - 'This project is private' => 'Tämä projekti on yksityinen', - 'Add' => 'Lisää', - 'Start date' => 'Aloituspäivä', - 'Time estimated' => 'Arvioitu aika', - 'There is nothing assigned to you.' => 'Ei tehtäviä, joihin sinut olisi merkitty tekijäksi.', - 'My tasks' => 'Minun tehtävät', - 'Activity stream' => 'Toiminta', - 'Dashboard' => 'Työpöytä', - 'Confirmation' => 'Vahvistus', - 'Allow everybody to access to this project' => 'Anna kaikille käyttöoikeus tähän projektiin', - 'Everybody have access to this project.' => 'Kaikilla on käyttöoikeus projektiin.', - // 'Webhooks' => '', - // 'API' => '', - // 'Create a comment from an external provider' => '', - 'Project management' => 'Projektin hallinta', - 'My projects' => 'Minun projektini', - 'Columns' => 'Sarakkeet', - 'Task' => 'Tehtävät', - 'Your are not member of any project.' => 'Et ole minkään projektin jäsen.', - 'Percentage' => 'Prosentti', - 'Number of tasks' => 'Tehtävien määrä', - 'Task distribution' => 'Tehtävien jakauma', - 'Reportings' => 'Raportoinnit', - // 'Task repartition for "%s"' => '', - 'Analytics' => 'Analytiikka', - 'Subtask' => 'Alitehtävä', - 'My subtasks' => 'Minun alitehtäväni', - // 'User repartition' => '', - // 'User repartition for "%s"' => '', - 'Clone this project' => 'Kahdenna projekti', - 'Column removed successfully.' => 'Sarake poistettu onnstuneesti.', - 'Not enough data to show the graph.' => 'Ei riittävästi dataa graafin näyttämiseksi.', - 'Previous' => 'Edellinen', - 'The id must be an integer' => 'ID:n on oltava kokonaisluku', - 'The project id must be an integer' => 'Projektin ID:n on oltava kokonaisluku', - 'The status must be an integer' => 'Tilan on oltava kokonaisluku', - 'The subtask id is required' => 'Alitehtävän ID vaaditaan', - 'The subtask id must be an integer' => 'Alitehtävän ID:ntulee olla kokonaisluku', - 'The task id is required' => 'Tehtävän ID vaaditaan', - 'The task id must be an integer' => 'Tehtävän ID on oltava kokonaisluku', - 'The user id must be an integer' => 'Käyttäjän ID on oltava kokonaisluku', - 'This value is required' => 'Tämä arvo on pakollinen', - 'This value must be numeric' => 'Tämän arvon tulee olla numeerinen', - 'Unable to create this task.' => 'Tehtävän luonti epäonnistui', - 'Cumulative flow diagram' => 'Kumulatiivinen vuokaavio', - 'Cumulative flow diagram for "%s"' => 'Kumulatiivinen vuokaavio kohteelle "%s"', - 'Daily project summary' => 'Päivittäinen yhteenveto', - 'Daily project summary export' => 'Päivittäisen yhteenvedon vienti', - 'Daily project summary export for "%s"' => 'Päivittäisen yhteenvedon vienti kohteeseen "%s"', - 'Exports' => 'Viennit', - 'This export contains the number of tasks per column grouped per day.' => 'Tämä tiedosto sisältää tehtäviä sarakkeisiin päiväkohtaisesti ryhmilteltyinä', - 'Active swimlanes' => 'Aktiiviset kaistat', - 'Add a new swimlane' => 'Lisää uusi kaista', - 'Change default swimlane' => 'Vaihda oletuskaistaa', - 'Default swimlane' => 'Oletuskaista', - 'Do you really want to remove this swimlane: "%s"?' => 'Haluatko varmasti poistaa tämän kaistan: "%s"?', - 'Inactive swimlanes' => 'Passiiviset kaistat', - 'Remove a swimlane' => 'Poista kaista', - 'Show default swimlane' => 'Näytä oletuskaista', - 'Swimlane modification for the project "%s"' => 'Kaistamuutos projektille "%s"', - 'Swimlane removed successfully.' => 'Kaista poistettu onnistuneesti.', - 'Swimlanes' => 'Kaistat', - 'Swimlane updated successfully.' => 'Kaista päivitetty onnistuneesti.', - 'The default swimlane have been updated successfully.' => 'Oletuskaista päivitetty onnistuneesti.', - 'Unable to remove this swimlane.' => 'Kaistan poisto epäonnistui.', - 'Unable to update this swimlane.' => 'Kaistan päivittäminen epäonnistui.', - 'Your swimlane have been created successfully.' => 'Kaista luotu onnistuneesti.', - 'Example: "Bug, Feature Request, Improvement"' => 'Esimerkiksi: "Bugit, Ominaisuuspyynnöt, Parannukset"', - 'Default categories for new projects (Comma-separated)' => 'Oletuskategoriat uusille projekteille (pilkuin eroteltu)', - // 'Integrations' => '', - // 'Integration with third-party services' => '', - // 'Subtask Id' => '', - // 'Subtasks' => '', - // 'Subtasks Export' => '', - // 'Subtasks exportation for "%s"' => '', - // 'Task Title' => '', - // 'Untitled' => '', - // 'Application default' => '', - // 'Language:' => '', - // 'Timezone:' => '', - // 'All columns' => '', - // 'Calendar' => '', - // 'Next' => '', - // '#%d' => '', - // 'All swimlanes' => '', - // 'All colors' => '', - // 'Moved to column %s' => '', - // 'User dashboard' => '', - // 'Allow only one subtask in progress at the same time for a user' => '', - // 'Edit column "%s"' => '', - // 'Select the new status of the subtask: "%s"' => '', - // 'Subtask timesheet' => '', - // 'There is nothing to show.' => '', - // 'Time Tracking' => '', - // 'You already have one subtask in progress' => '', - // 'Which parts of the project do you want to duplicate?' => '', - // 'Disallow login form' => '', - // 'Start' => '', - // 'End' => '', - // 'Task age in days' => '', - // 'Days in this column' => '', - // '%dd' => '', - // 'Add a new link' => '', - // 'Do you really want to remove this link: "%s"?' => '', - // 'Do you really want to remove this link with task #%d?' => '', - // 'Field required' => '', - // 'Link added successfully.' => '', - // 'Link updated successfully.' => '', - // 'Link removed successfully.' => '', - // 'Link labels' => '', - // 'Link modification' => '', - // 'Links' => '', - // 'Link settings' => '', - // 'Opposite label' => '', - // 'Remove a link' => '', - // 'Task\'s links' => '', - // 'The labels must be different' => '', - // 'There is no link.' => '', - // 'This label must be unique' => '', - // 'Unable to create your link.' => '', - // 'Unable to update your link.' => '', - // 'Unable to remove this link.' => '', - // 'relates to' => '', - // 'blocks' => '', - // 'is blocked by' => '', - // 'duplicates' => '', - // 'is duplicated by' => '', - // 'is a child of' => '', - // 'is a parent of' => '', - // 'targets milestone' => '', - // 'is a milestone of' => '', - // 'fixes' => '', - // 'is fixed by' => '', - // 'This task' => '', - // '<1h' => '', - // '%dh' => '', - // 'Expand tasks' => '', - // 'Collapse tasks' => '', - // 'Expand/collapse tasks' => '', - // 'Close dialog box' => '', - // 'Submit a form' => '', - // 'Board view' => '', - // 'Keyboard shortcuts' => '', - // 'Open board switcher' => '', - // 'Application' => '', - // 'Compact view' => '', - // 'Horizontal scrolling' => '', - // 'Compact/wide view' => '', - // 'No results match:' => '', - // 'Currency' => '', - // 'Private project' => '', - // 'AUD - Australian Dollar' => '', - // 'CAD - Canadian Dollar' => '', - // 'CHF - Swiss Francs' => '', - // 'Custom Stylesheet' => '', - // 'download' => '', - // 'EUR - Euro' => '', - // 'GBP - British Pound' => '', - // 'INR - Indian Rupee' => '', - // 'JPY - Japanese Yen' => '', - // 'NZD - New Zealand Dollar' => '', - // 'RSD - Serbian dinar' => '', - // 'USD - US Dollar' => '', - // 'Destination column' => '', - // 'Move the task to another column when assigned to a user' => '', - // 'Move the task to another column when assignee is cleared' => '', - // 'Source column' => '', - // 'Transitions' => '', - // 'Executer' => '', - // 'Time spent in the column' => '', - // 'Task transitions' => '', - // 'Task transitions export' => '', - // 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '', - // 'Currency rates' => '', - // 'Rate' => '', - // 'Change reference currency' => '', - // 'Add a new currency rate' => '', - // 'Reference currency' => '', - // 'The currency rate have been added successfully.' => '', - // 'Unable to add this currency rate.' => '', - // 'Webhook URL' => '', - // '%s remove the assignee of the task %s' => '', - // 'Enable Gravatar images' => '', - // 'Information' => '', - // 'Check two factor authentication code' => '', - // 'The two factor authentication code is not valid.' => '', - // 'The two factor authentication code is valid.' => '', - // 'Code' => '', - // 'Two factor authentication' => '', - // 'This QR code contains the key URI: ' => '', - // 'Check my code' => '', - // 'Secret key: ' => '', - // 'Test your device' => '', - // 'Assign a color when the task is moved to a specific column' => '', - // '%s via Kanboard' => '', - // 'Burndown chart for "%s"' => '', - // 'Burndown chart' => '', - // 'This chart show the task complexity over the time (Work Remaining).' => '', - // 'Screenshot taken %s' => '', - // 'Add a screenshot' => '', - // 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '', - // 'Screenshot uploaded successfully.' => '', - // 'SEK - Swedish Krona' => '', - // 'Identifier' => '', - // 'Disable two factor authentication' => '', - // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', - // 'Edit link' => '', - // 'Start to type task title...' => '', - // 'A task cannot be linked to itself' => '', - // 'The exact same link already exists' => '', - // 'Recurrent task is scheduled to be generated' => '', - // 'Score' => '', - // 'The identifier must be unique' => '', - // 'This linked task id doesn\'t exists' => '', - // 'This value must be alphanumeric' => '', - // 'Edit recurrence' => '', - // 'Generate recurrent task' => '', - // 'Trigger to generate recurrent task' => '', - // 'Factor to calculate new due date' => '', - // 'Timeframe to calculate new due date' => '', - // 'Base date to calculate new due date' => '', - // 'Action date' => '', - // 'Base date to calculate new due date: ' => '', - // 'This task has created this child task: ' => '', - // 'Day(s)' => '', - // 'Existing due date' => '', - // 'Factor to calculate new due date: ' => '', - // 'Month(s)' => '', - // 'Recurrence' => '', - // 'This task has been created by: ' => '', - // 'Recurrent task has been generated:' => '', - // 'Timeframe to calculate new due date: ' => '', - // 'Trigger to generate recurrent task: ' => '', - // 'When task is closed' => '', - // 'When task is moved from first column' => '', - // 'When task is moved to last column' => '', - // 'Year(s)' => '', - // 'Calendar settings' => '', - // 'Project calendar view' => '', - // 'Project settings' => '', - // 'Show subtasks based on the time tracking' => '', - // 'Show tasks based on the creation date' => '', - // 'Show tasks based on the start date' => '', - // 'Subtasks time tracking' => '', - // 'User calendar view' => '', - // 'Automatically update the start date' => '', - // 'iCal feed' => '', - // 'Preferences' => '', - // 'Security' => '', - // 'Two factor authentication disabled' => '', - // 'Two factor authentication enabled' => '', - // 'Unable to update this user.' => '', - // 'There is no user management for private projects.' => '', - // 'User that will receive the email' => '', - // 'Email subject' => '', - // 'Date' => '', - // 'Add a comment log when moving the task between columns' => '', - // 'Move the task to another column when the category is changed' => '', - // 'Send a task by email to someone' => '', - // 'Reopen a task' => '', - // 'Column change' => '', - // 'Position change' => '', - // 'Swimlane change' => '', - // 'Assignee change' => '', - // '[%s] Overdue tasks' => '', - // 'Notification' => '', - // '%s moved the task #%d to the first swimlane' => '', - // '%s moved the task #%d to the swimlane "%s"' => '', - // 'Swimlane' => '', - // 'Gravatar' => '', - // '%s moved the task %s to the first swimlane' => '', - // '%s moved the task %s to the swimlane "%s"' => '', - // 'This report contains all subtasks information for the given date range.' => '', - // 'This report contains all tasks information for the given date range.' => '', - // 'Project activities for %s' => '', - // 'view the board on Kanboard' => '', - // 'The task have been moved to the first swimlane' => '', - // 'The task have been moved to another swimlane:' => '', - // 'New title: %s' => '', - // 'The task is not assigned anymore' => '', - // 'New assignee: %s' => '', - // 'There is no category now' => '', - // 'New category: %s' => '', - // 'New color: %s' => '', - // 'New complexity: %d' => '', - // 'The due date have been removed' => '', - // 'There is no description anymore' => '', - // 'Recurrence settings have been modified' => '', - // 'Time spent changed: %sh' => '', - // 'Time estimated changed: %sh' => '', - // 'The field "%s" have been updated' => '', - // 'The description has been modified:' => '', - // 'Do you really want to close the task "%s" as well as all subtasks?' => '', - // 'I want to receive notifications for:' => '', - // 'All tasks' => '', - // 'Only for tasks assigned to me' => '', - // 'Only for tasks created by me' => '', - // 'Only for tasks created by me and assigned to me' => '', - // '%%Y-%%m-%%d' => '', - // 'Total for all columns' => '', - // 'You need at least 2 days of data to show the chart.' => '', - // '<15m' => '', - // '<30m' => '', - // 'Stop timer' => '', - // 'Start timer' => '', - // 'Add project member' => '', - // 'My activity stream' => '', - // 'My calendar' => '', - // 'Search tasks' => '', - // 'Reset filters' => '', - // 'My tasks due tomorrow' => '', - // 'Tasks due today' => '', - // 'Tasks due tomorrow' => '', - // 'Tasks due yesterday' => '', - // 'Closed tasks' => '', - // 'Open tasks' => '', - // 'Not assigned' => '', - // 'View advanced search syntax' => '', - // 'Overview' => '', - // 'Board/Calendar/List view' => '', - // 'Switch to the board view' => '', - // 'Switch to the calendar view' => '', - // 'Switch to the list view' => '', - // 'Go to the search/filter box' => '', - // 'There is no activity yet.' => '', - // 'No tasks found.' => '', - // 'Keyboard shortcut: "%s"' => '', - // 'List' => '', - // 'Filter' => '', - // 'Advanced search' => '', - // 'Example of query: ' => '', - // 'Search by project: ' => '', - // 'Search by column: ' => '', - // 'Search by assignee: ' => '', - // 'Search by color: ' => '', - // 'Search by category: ' => '', - // 'Search by description: ' => '', - // 'Search by due date: ' => '', - // 'Lead and Cycle time for "%s"' => '', - // 'Average time spent into each column for "%s"' => '', - // 'Average time spent into each column' => '', - // 'Average time spent' => '', - // 'This chart show the average time spent into each column for the last %d tasks.' => '', - // 'Average Lead and Cycle time' => '', - // 'Average lead time: ' => '', - // 'Average cycle time: ' => '', - // 'Cycle Time' => '', - // 'Lead Time' => '', - // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', - // 'Average time into each column' => '', - // 'Lead and cycle time' => '', - // 'Lead time: ' => '', - // 'Cycle time: ' => '', - // 'Time spent into each column' => '', - // 'The lead time is the duration between the task creation and the completion.' => '', - // 'The cycle time is the duration between the start date and the completion.' => '', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - // 'Set automatically the start date' => '', - // 'Edit Authentication' => '', - // 'Remote user' => '', - // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', - // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - // 'New remote user' => '', - // 'New local user' => '', - // 'Default task color' => '', - // 'This feature does not work with all browsers.' => '', - // 'There is no destination project available.' => '', - // 'Trigger automatically subtask time tracking' => '', - // 'Include closed tasks in the cumulative flow diagram' => '', - // 'Current swimlane: %s' => '', - // 'Current column: %s' => '', - // 'Current category: %s' => '', - // 'no category' => '', - // 'Current assignee: %s' => '', - // 'not assigned' => '', - // 'Author:' => '', - // 'contributors' => '', - // 'License:' => '', - // 'License' => '', - // 'Enter the text below' => '', - // 'Gantt chart for %s' => '', - // 'Sort by position' => '', - // 'Sort by date' => '', - // 'Add task' => '', - // 'Start date:' => '', - // 'Due date:' => '', - // 'There is no start date or due date for this task.' => '', - // 'Moving or resizing a task will change the start and due date of the task.' => '', - // 'There is no task in your project.' => '', - // 'Gantt chart' => '', - // 'People who are project managers' => '', - // 'People who are project members' => '', - // 'NOK - Norwegian Krone' => '', - // 'Show this column' => '', - // 'Hide this column' => '', - // 'open file' => '', - // 'End date' => '', - // 'Users overview' => '', - // 'Members' => '', - // 'Shared project' => '', - // 'Project managers' => '', - // 'Gantt chart for all projects' => '', - // 'Projects list' => '', - // 'Gantt chart for this project' => '', - // 'Project board' => '', - // 'End date:' => '', - // 'There is no start date or end date for this project.' => '', - // 'Projects Gantt chart' => '', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - // 'Milestone' => '', - // 'Documentation: %s' => '', - // 'Switch to the Gantt chart view' => '', - // 'Reset the search/filter box' => '', - // 'Documentation' => '', - // 'Table of contents' => '', - // 'Gantt' => '', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - // 'Link type' => '', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - // 'Project members' => '', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/fr_FR/translations.php b/sources/app/Locale/fr_FR/translations.php deleted file mode 100644 index 8684d1e..0000000 --- a/sources/app/Locale/fr_FR/translations.php +++ /dev/null @@ -1,1220 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => ' ', - 'None' => 'Aucun', - 'edit' => 'modifier', - 'Edit' => 'Modifier', - 'remove' => 'supprimer', - 'Remove' => 'Supprimer', - 'Yes' => 'Oui', - 'No' => 'Non', - 'cancel' => 'annuler', - 'or' => 'ou', - 'Yellow' => 'Jaune', - 'Blue' => 'Bleu', - 'Green' => 'Vert', - 'Purple' => 'Violet', - 'Red' => 'Rouge', - 'Orange' => 'Orange', - 'Grey' => 'Gris', - 'Brown' => 'Marron', - 'Deep Orange' => 'Orange foncé', - 'Dark Grey' => 'Gris foncé', - 'Pink' => 'Rose', - 'Teal' => 'Turquoise', - 'Cyan'=> 'Bleu intense', - 'Lime' => 'Vert citron', - 'Light Green' => 'Vert clair', - 'Amber' => 'Ambre', - 'Save' => 'Enregistrer', - 'Login' => 'Connexion', - 'Official website:' => 'Site web officiel :', - 'Unassigned' => 'Non assigné', - 'View this task' => 'Voir cette tâche', - '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', - 'Password' => 'Mot de passe', - 'Administrator' => 'Administrateur', - 'Sign in' => 'Connexion', - 'Users' => 'Utilisateurs', - 'No user' => 'Aucun utilisateur', - 'Forbidden' => 'Accès interdit', - 'Access Forbidden' => 'Accès interdit', - 'Edit user' => 'Modifier un utilisateur', - 'Logout' => 'Déconnexion', - 'Bad username or password' => 'Identifiant ou mot de passe incorrect', - 'Edit project' => 'Modifier le projet', - 'Name' => 'Nom', - 'Projects' => 'Projets', - 'No project' => 'Aucun projet', - 'Project' => 'Projet', - 'Status' => 'État', - 'Tasks' => 'Tâches', - 'Board' => 'Tableau', - 'Actions' => 'Actions', - 'Inactive' => 'Inactif', - 'Active' => 'Actif', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Voulez-vous vraiment supprimer ce projet : « %s » ?', - 'Remove project' => 'Supprimer le projet', - 'Edit the board for "%s"' => 'Modifier le tableau pour « %s »', - 'All projects' => 'Tous les projets', - 'Add a new column' => 'Ajouter une nouvelle colonne', - '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 !', - 'Settings' => 'Préférences', - 'Application settings' => 'Paramètres de l\'application', - 'Language' => 'Langue', - 'Webhook token:' => 'Jeton de securité pour les webhooks :', - 'API token:' => 'Jeton de securité pour l\'API :', - 'Database size:' => 'Taille de la base de données :', - 'Download the database' => 'Télécharger la base de données', - 'Optimize the database' => 'Optimiser la base de données', - '(VACUUM command)' => '(Commande VACUUM)', - '(Gzip compressed Sqlite file)' => '(Fichier Sqlite compressé en Gzip)', - 'Close a task' => 'Fermer une tâche', - 'Edit a task' => 'Modifier une tâche', - 'Column' => 'Colonne', - 'Color' => 'Couleur', - 'Assignee' => 'Personne assignée', - 'Create another task' => 'Créer une autre tâche', - 'New task' => 'Nouvelle tâche', - 'Open a task' => 'Ouvrir une tâche', - 'Do you really want to open this task: "%s"?' => 'Voulez-vous vraiment ouvrir cette tâche : « %s » ?', - 'Back to the board' => 'Retour au tableau', - 'There is nobody assigned' => 'Il n\'y a personne d\'assigné à cette tâche', - 'Column on the board:' => 'Colonne sur le tableau : ', - 'Close this task' => 'Fermer cette tâche', - 'Open this task' => 'Ouvrir cette tâche', - 'There is no description.' => 'Il n\'y a pas de description.', - 'Add a new task' => 'Ajouter une nouvelle tâche', - 'The username is required' => 'Le nom d\'utilisateur est obligatoire', - 'The maximum length is %d characters' => 'La longueur maximale est de %d caractères', - 'The minimum length is %d characters' => 'La longueur minimale est de %d caractères', - 'The password is required' => 'Le mot de passe est obligatoire', - 'This value must be an integer' => 'Cette valeur doit être un entier', - 'The username must be unique' => 'Le nom d\'utilisateur doit être unique', - 'The user id is required' => 'L\'id de l\'utilisateur est obligatoire', - 'Passwords don\'t match' => 'Les mots de passe ne correspondent pas', - 'The confirmation is required' => 'Le confirmation est requise', - 'The project is required' => 'Le projet est obligatoire', - 'The id is required' => 'L\'identifiant est obligatoire', - 'The project id is required' => 'L\'identifiant du projet est obligatoire', - 'The project name is required' => 'Le nom du projet est obligatoire', - 'The title is required' => 'Le titre est obligatoire', - 'Settings saved successfully.' => 'Paramètres sauvegardés avec succès.', - 'Unable to save your settings.' => 'Impossible de sauvegarder vos réglages.', - 'Database optimization done.' => 'Optmisation de la base de données terminée.', - 'Your project have been created successfully.' => 'Votre projet a été créé avec succès.', - 'Unable to create your project.' => 'Impossible de créer un projet.', - 'Project updated successfully.' => 'Votre projet a été mis à jour avec succès.', - 'Unable to update this project.' => 'Impossible de mettre à jour ce projet.', - 'Unable to remove this project.' => 'Impossible de supprimer ce projet.', - 'Project removed successfully.' => 'Votre projet a été supprimé avec succès.', - 'Project activated successfully.' => 'Votre projet a été activé avec succès.', - 'Unable to activate this project.' => 'Impossible d\'activer ce projet.', - 'Project disabled successfully.' => 'Votre projet a été désactivé avec succès.', - 'Unable to disable this project.' => 'Impossible de désactiver ce projet.', - 'Unable to open this task.' => 'Impossible d\'ouvrir cette tâche.', - 'Task opened successfully.' => 'Tâche ouverte avec succès.', - 'Unable to close this task.' => 'Impossible de fermer cette tâche.', - 'Task closed successfully.' => 'Tâche fermée avec succès.', - 'Unable to update your task.' => 'Impossible de modifier cette tâche.', - 'Task updated successfully.' => 'Tâche mise à jour avec succès.', - 'Unable to create your task.' => 'Impossible de créer cette tâche.', - 'Task created successfully.' => 'Tâche créée avec succès.', - 'User created successfully.' => 'Utilisateur créé avec succès.', - 'Unable to create your user.' => 'Impossible de créer cet utilisateur.', - 'User updated successfully.' => 'Utilisateur mis à jour avec succès.', - 'Unable to update your user.' => 'Impossible de mettre à jour cet utilisateur.', - 'User removed successfully.' => 'Utilisateur supprimé avec succès.', - 'Unable to remove this user.' => 'Impossible de supprimer cet utilisateur.', - 'Board updated successfully.' => 'Tableau mis à jour avec succès.', - 'Ready' => 'Prêt', - 'Backlog' => 'En attente', - 'Work in progress' => 'En cours', - 'Done' => 'Terminé', - 'Application version:' => 'Version de l\'application :', - 'Id' => 'Id.', - '%d closed tasks' => '%d tâches terminées', - 'No task for this project' => 'Aucune tâche pour ce projet', - 'Public link' => 'Lien public', - 'Timezone' => 'Fuseau horaire', - 'Sorry, I didn\'t find this information in my database!' => 'Désolé, je n\'ai pas trouvé cette information dans ma base de données !', - 'Page not found' => 'Page introuvable', - 'Complexity' => 'Complexité', - 'Task limit' => 'Tâches Max.', - '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', - 'Invalid date' => 'Date invalide', - 'Automatic actions' => 'Actions automatisées', - 'Your automatic action have been created successfully.' => 'Votre action automatisée a été ajoutée avec succès.', - 'Unable to create your automatic action.' => 'Impossible de créer votre action automatisée.', - 'Remove an action' => 'Supprimer une action', - 'Unable to remove this action.' => 'Impossible de supprimer cette action', - 'Action removed successfully.' => 'Action supprimée avec succès.', - 'Automatic actions for the project "%s"' => 'Actions automatisées pour le projet « %s »', - 'Add an action' => 'Ajouter une action', - 'Event name' => 'Nom de l\'événement', - 'Action name' => 'Nom de l\'action', - 'Action parameters' => 'Paramètres de l\'action', - 'Action' => 'Action', - 'Event' => 'Événement', - 'When the selected event occurs execute the corresponding action.' => 'Lorsque l\'événement sélectionné se déclenche, exécuter l\'action correspondante.', - 'Next step' => 'Étape suivante', - 'Define action parameters' => 'Définition des paramètres de l\'action', - 'Do you really want to remove this action: "%s"?' => 'Voulez-vous vraiment supprimer cette action « %s » ?', - 'Remove an automatic action' => 'Supprimer une action automatisée', - 'Assign the task to a specific user' => 'Assigner la tâche à un utilisateur spécifique', - 'Assign the task to the person who does the action' => 'Assigner la tâche à la personne qui fait l\'action', - 'Duplicate the task to another project' => 'Dupliquer la tâche vers un autre projet', - 'Move a task to another column' => 'Déplacement d\'une tâche vers une autre colonne', - 'Task modification' => 'Modification d\'une tâche', - 'Task creation' => 'Création d\'une tâche', - 'Closing a task' => 'Fermeture d\'une tâche', - 'Assign a color to a specific user' => 'Assigner une couleur à un utilisateur', - 'Column title' => 'Titre de la colonne', - 'Position' => 'Position', - 'Duplicate to another project' => 'Dupliquer dans un autre projet', - 'Duplicate' => 'Dupliquer', - 'link' => 'lien', - 'Comment updated successfully.' => 'Commentaire mis à jour avec succès.', - 'Unable to update your comment.' => 'Impossible de supprimer votre commentaire.', - 'Remove a comment' => 'Supprimer un commentaire', - 'Comment removed successfully.' => 'Commentaire supprimé avec succès.', - 'Unable to remove this comment.' => 'Impossible de supprimer ce commentaire.', - 'Do you really want to remove this comment?' => 'Voulez-vous vraiment supprimer ce commentaire ?', - 'Current password for the user "%s"' => 'Mot de passe actuel pour l\'utilisateur « %s »', - 'The current password is required' => 'Le mot de passe actuel est obligatoire', - 'Wrong password' => 'Mot de passe invalide', - 'Unknown' => 'Inconnu', - 'Last logins' => 'Dernières connexions', - 'Login date' => 'Date de connexion', - 'Authentication method' => 'Méthode d\'authentification', - 'IP address' => 'Adresse IP', - 'User agent' => 'Agent utilisateur', - 'Persistent connections' => 'Connexions persistantes', - 'No session.' => 'Aucune session.', - 'Expiration date' => 'Date d\'expiration', - 'Remember Me' => 'Connexion automatique', - 'Creation date' => 'Date de création', - 'Everybody' => 'Tout le monde', - 'Open' => 'Ouvert', - 'Closed' => 'Fermé', - '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', - 'Email address invalid' => 'Adresse email invalide', - 'Your external account is not linked anymore to your profile.' => 'Votre compte externe n\'est plus relié à votre profil.', - 'Unable to unlink your external account.' => 'Impossible de supprimer votre compte externe.', - 'External authentication failed' => 'L’authentification externe a échoué', - 'Your external account is linked to your profile successfully.' => 'Votre compte externe est désormais lié à votre profil.', - 'Email' => 'Email', - 'Task removed successfully.' => 'Tâche supprimée avec succès.', - 'Unable to remove this task.' => 'Impossible de supprimer cette tâche.', - 'Remove a task' => 'Supprimer une tâche', - 'Do you really want to remove this task: "%s"?' => 'Voulez-vous vraiment supprimer cette tâche « %s » ?', - 'Assign automatically a color based on a category' => 'Assigner automatiquement une couleur par rapport à une catégorie définie', - 'Assign automatically a category based on a color' => 'Assigner automatiquement une catégorie par rapport à une couleur définie', - 'Task creation or modification' => 'Création ou modification d\'une tâche', - 'Category' => 'Catégorie', - 'Category:' => 'Catégorie :', - 'Categories' => 'Catégories', - 'Your category have been created successfully.' => 'Votre catégorie a été créée avec succès.', - 'Unable to create your category.' => 'Impossible de créer votre catégorie.', - 'Your category have been updated successfully.' => 'Votre catégorie a été mise à jour avec succès.', - 'Unable to update your category.' => 'Impossible de mettre à jour votre catégorie.', - 'Remove a category' => 'Supprimer une catégorie', - 'Category removed successfully.' => 'Catégorie supprimée avec succès.', - 'Unable to remove this category.' => 'Impossible de supprimer cette catégorie.', - 'Category modification for the project "%s"' => 'Modification d\'une catégorie pour le projet « %s »', - 'Category Name' => 'Nom de la catégorie', - 'Add a new category' => 'Ajouter une nouvelle catégorie', - 'Do you really want to remove this category: "%s"?' => 'Voulez-vous vraiment supprimer cette catégorie « %s » ?', - 'All categories' => 'Toutes les catégories', - 'No category' => 'Aucune catégorie', - 'The name is required' => 'Le nom est requis', - 'Remove a file' => 'Supprimer un fichier', - 'Unable to remove this file.' => 'Impossible de supprimer ce fichier.', - 'File removed successfully.' => 'Fichier supprimé avec succès.', - 'Attach a document' => 'Joindre un document', - 'Do you really want to remove this file: "%s"?' => 'Voulez-vous vraiment supprimer ce fichier « %s » ?', - 'Attachments' => 'Pièces-jointes', - 'Edit the task' => 'Modifier la tâche', - 'Add a comment' => 'Ajouter un commentaire', - 'Edit a comment' => 'Modifier un commentaire', - 'Summary' => 'Résumé', - 'Time tracking' => 'Suivi du temps', - 'Estimate:' => 'Estimation :', - 'Spent:' => 'Passé :', - 'Do you really want to remove this sub-task?' => 'Voulez-vous vraiment supprimer cette sous-tâche ?', - 'Remaining:' => 'Restant :', - 'hours' => 'heures', - 'spent' => 'passé', - 'estimated' => 'estimé', - 'Sub-Tasks' => 'Sous-tâches', - 'Add a sub-task' => 'Ajouter une sous-tâche', - 'Original estimate' => 'Estimation originale', - 'Create another sub-task' => 'Créer une autre sous-tâche', - 'Time spent' => 'Temps passé', - 'Edit a sub-task' => 'Modifier une sous-tâche', - 'Remove a sub-task' => 'Supprimer une sous-tâche', - 'The time must be a numeric value' => 'Le temps doit-être une valeur numérique', - 'Todo' => 'À faire', - 'In progress' => 'En cours', - 'Sub-task removed successfully.' => 'Sous-tâche supprimée avec succès.', - 'Unable to remove this sub-task.' => 'Impossible de supprimer cette sous-tâche.', - 'Sub-task updated successfully.' => 'Sous-tâche mise à jour avec succès.', - 'Unable to update your sub-task.' => 'Impossible de mettre à jour votre sous-tâche.', - 'Unable to create your sub-task.' => 'Impossible de créer votre sous-tâche.', - 'Sub-task added successfully.' => 'Sous-tâche ajoutée avec succès.', - 'Maximum size: ' => 'Taille maximum : ', - 'Unable to upload the file.' => 'Impossible de transférer le fichier.', - 'Display another project' => 'Afficher un autre projet', - 'Created by %s' => 'Créé par %s', - 'Tasks Export' => 'Exportation des tâches', - 'Tasks exportation for "%s"' => 'Exportation des tâches pour « %s »', - 'Start Date' => 'Date de début', - 'End Date' => 'Date de fin', - 'Execute' => 'Exécuter', - 'Task Id' => 'Identifiant de la tâche', - 'Creator' => 'Créateur', - 'Modification date' => 'Date de modification', - 'Completion date' => 'Date de complétion', - 'Clone' => 'Clone', - 'Project cloned successfully.' => 'Projet cloné avec succès.', - 'Unable to clone this project.' => 'Impossible de cloner ce projet.', - 'Enable email notifications' => 'Activer les notifications par emails', - 'Task position:' => 'Position de la tâche :', - 'The task #%d have been opened.' => 'La tâche #%d a été ouverte.', - 'The task #%d have been closed.' => 'La tâche #%d a été fermée.', - 'Sub-task updated' => 'Sous-tâche mise à jour', - 'Title:' => 'Titre :', - 'Status:' => 'État :', - 'Assignee:' => 'Assigné :', - 'Time tracking:' => 'Gestion du temps :', - 'New sub-task' => 'Nouvelle sous-tâche', - 'New attachment added "%s"' => 'Nouvelle pièce-jointe ajoutée « %s »', - 'New comment posted by %s' => 'Nouveau commentaire ajouté par « %s »', - 'New attachment' => 'Nouveau document', - 'New comment' => 'Nouveau commentaire', - 'Comment updated' => 'Commentaire mis à jour', - 'New subtask' => 'Nouvelle sous-tâche', - 'Subtask updated' => 'Sous-tâche mise à jour', - 'Task updated' => 'Tâche mise à jour', - 'Task closed' => 'Tâche fermée', - 'Task opened' => 'Tâche ouverte', - 'I want to receive notifications only for those projects:' => 'Je souhaite reçevoir les notifications uniquement pour les projets sélectionnés :', - 'view the task on Kanboard' => 'voir la tâche sur Kanboard', - 'Public access' => 'Accès public', - 'Active tasks' => 'Tâches actives', - 'Disable public access' => 'Désactiver l\'accès public', - 'Enable public access' => 'Activer l\'accès public', - 'Public access disabled' => 'Accès public désactivé', - 'Do you really want to disable this project: "%s"?' => 'Voulez-vous vraiment désactiver ce projet : « %s » ?', - 'Do you really want to enable this project: "%s"?' => 'Voulez-vous vraiment activer ce projet : « %s » ?', - 'Project activation' => 'Activation du projet', - 'Move the task to another project' => 'Déplacer la tâche vers un autre projet', - 'Move to another project' => 'Déplacer vers un autre projet', - 'Do you really want to duplicate this task?' => 'Voulez-vous vraiment dupliquer cette tâche ?', - 'Duplicate a task' => 'Dupliquer une tâche', - 'External accounts' => 'Comptes externes', - 'Account type' => 'Type de compte', - 'Local' => 'Local', - 'Remote' => 'Distant', - 'Enabled' => 'Activé', - 'Disabled' => 'Désactivé', - 'Username:' => 'Nom d\'utilisateur :', - 'Name:' => 'Nom :', - 'Email:' => 'Email :', - 'Notifications:' => 'Notifications :', - 'Notifications' => 'Notifications', - 'Account type:' => 'Type de compte :', - 'Edit profile' => 'Modifier le profil', - 'Change password' => 'Changer le mot de passe', - 'Password modification' => 'Changement de mot de passe', - 'External authentications' => 'Authentifications externes', - 'Never connected.' => 'Jamais connecté.', - 'No external authentication enabled.' => 'Aucune authentification externe activée.', - 'Password modified successfully.' => 'Mot de passe changé avec succès.', - 'Unable to change the password.' => 'Impossible de changer le mot de passe.', - 'Change category' => 'Changer de catégorie', - '%s updated the task %s' => '%s a mis à jour la tâche %s', - '%s opened the task %s' => '%s a ouvert la tâche %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s a déplacé la tâche %s à la position n°%d dans la colonne « %s »', - '%s moved the task %s to the column "%s"' => '%s a déplacé la tâche %s dans la colonne « %s »', - '%s created the task %s' => '%s a créé la tâche %s', - '%s closed the task %s' => '%s a fermé la tâche %s', - '%s created a subtask for the task %s' => '%s a créé une sous-tâche pour la tâche %s', - '%s updated a subtask for the task %s' => '%s a mis à jour une sous-tâche appartenant à la tâche %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Assigné à %s avec un estimé de %s/%sh', - 'Not assigned, estimate of %sh' => 'Personne assigné, estimé de %sh', - '%s updated a comment on the task %s' => '%s a mis à jour un commentaire appartenant à la tâche %s', - '%s commented the task %s' => '%s a ajouté un commentaire sur la tâche %s', - '%s\'s activity' => 'Activité du projet %s', - 'RSS feed' => 'Flux RSS', - '%s updated a comment on the task #%d' => '%s a mis à jour un commentaire sur la tâche n°%d', - '%s commented on the task #%d' => '%s a ajouté un commentaire sur la tâche n°%d', - '%s updated a subtask for the task #%d' => '%s a mis à jour une sous-tâche appartenant à la tâche n°%d', - '%s created a subtask for the task #%d' => '%s a créé une sous-tâche pour la tâche n°%d', - '%s updated the task #%d' => '%s a mis à jour la tâche n°%d', - '%s created the task #%d' => '%s a créé la tâche n°%d', - '%s closed the task #%d' => '%s a fermé la tâche n°%d', - '%s open the task #%d' => '%s a ouvert la tâche n°%d', - '%s moved the task #%d to the column "%s"' => '%s a déplacé la tâche n°%d dans la colonne « %s »', - '%s moved the task #%d to the position %d in the column "%s"' => '%s a déplacé la tâche n°%d à la position n°%d dans la colonne « %s »', - 'Activity' => 'Activité', - 'Default values are "%s"' => 'Les valeurs par défaut sont « %s »', - 'Default columns for new projects (Comma-separated)' => 'Colonnes par défaut pour les nouveaux projets (séparation par des virgules)', - 'Task assignee change' => 'Modification de la personne assignée à une tâche', - '%s change the assignee of the task #%d to %s' => '%s a changé la personne assignée à la tâche n˚%d pour %s', - '%s changed the assignee of the task %s to %s' => '%s a changé la personne assignée à la tâche %s pour %s', - 'New password for the user "%s"' => 'Nouveau mot de passe pour l\'utilisateur « %s »', - 'Choose an event' => 'Choisir un événement', - 'Create a task from an external provider' => 'Créer une tâche depuis un fournisseur externe', - 'Change the assignee based on an external username' => 'Changer l\'assigné en fonction d\'un utilisateur externe', - 'Change the category based on an external label' => 'Changer la catégorie en fonction d\'un libellé externe', - 'Reference' => 'Référence', - 'Label' => 'Libellé', - 'Database' => 'Base de données', - 'About' => 'À propos', - 'Database driver:' => 'Type de base de données :', - 'Board settings' => 'Paramètres du tableau', - 'Webhook settings' => 'Paramètres pour les webhooks', - 'Reset token' => 'Regénérer le jeton de sécurité', - 'API endpoint:' => 'URL de l\'API :', - 'Refresh interval for private board' => 'Intervalle pour rafraîchir un tableau privé', - 'Refresh interval for public board' => 'Intervalle pour rafraîchir un tableau public', - 'Task highlight period' => 'Durée pour mettre une tâche en évidence', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Durée en seconde pour considérer une tâche comme récemment modifiée (0 pour désactiver, 2 jours par défaut)', - 'Frequency in second (60 seconds by default)' => 'Fréquence en seconde (60 secondes par défaut)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Fréquence en seconde (0 pour désactiver, 10 secondes par défaut)', - 'Application URL' => 'URL de l\'application', - 'Token regenerated.' => 'Jeton de sécurité regénéré.', - 'Date format' => 'Format des dates', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Le format ISO est toujours accepté, exemple : « %s » et « %s »', - 'New private project' => 'Nouveau projet privé', - 'This project is private' => 'Ce projet est privé', - 'Add' => 'Ajouter', - 'Start date' => 'Date de début', - 'Time estimated' => 'Temps estimé', - 'There is nothing assigned to you.' => 'Il n\'y a rien d\'assigné pour vous.', - 'My tasks' => 'Mes tâches', - 'Activity stream' => 'Flux d\'activité', - 'Dashboard' => 'Tableau de bord', - 'Confirmation' => 'Confirmation', - 'Allow everybody to access to this project' => 'Autoriser tout le monde à accéder à ce projet', - 'Everybody have access to this project.' => 'Tout le monde a accès à ce projet.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Créer un commentaire depuis un fournisseur externe', - 'Project management' => 'Gestion des projets', - 'My projects' => 'Mes projets', - 'Columns' => 'Colonnes', - 'Task' => 'Tâche', - 'Your are not member of any project.' => 'Vous n\'êtes membre d\'aucun projet.', - 'Percentage' => 'Pourcentage', - 'Number of tasks' => 'Nombre de tâches', - 'Task distribution' => 'Répartition des tâches', - 'Reportings' => 'Rapports', - 'Task repartition for "%s"' => 'Répartition des tâches pour « %s »', - 'Analytics' => 'Analytique', - 'Subtask' => 'Sous-tâche', - 'My subtasks' => 'Mes sous-tâches', - 'User repartition' => 'Répartition des utilisateurs', - 'User repartition for "%s"' => 'Répartition des utilisateurs pour « %s »', - 'Clone this project' => 'Cloner ce projet', - 'Column removed successfully.' => 'Colonne supprimée avec succès.', - 'Not enough data to show the graph.' => 'Pas assez de données pour afficher le graphique.', - 'Previous' => 'Précédent', - 'The id must be an integer' => 'L\'id doit être un entier', - 'The project id must be an integer' => 'L\'id du projet doit être un entier', - 'The status must be an integer' => 'Le statut doit être un entier', - 'The subtask id is required' => 'L\'id de la sous-tâche est obligatoire', - 'The subtask id must be an integer' => 'L\'id de la sous-tâche doit être un entier', - 'The task id is required' => 'L\'id de la tâche est obligatoire', - 'The task id must be an integer' => 'L\'id de la tâche doit être un entier', - 'The user id must be an integer' => 'L\'id de l\'utilisateur doit être un entier', - 'This value is required' => 'Cette valeur est obligatoire', - 'This value must be numeric' => 'Cette valeur doit être numérique', - 'Unable to create this task.' => 'Impossible de créer cette tâche', - 'Cumulative flow diagram' => 'Diagramme de flux cumulé', - 'Cumulative flow diagram for "%s"' => 'Diagramme de flux cumulé pour « %s »', - 'Daily project summary' => 'Résumé journalier du projet', - 'Daily project summary export' => 'Export du résumé journalier du projet', - 'Daily project summary export for "%s"' => 'Export du résumé quotidien du projet pour « %s »', - 'Exports' => 'Exports', - 'This export contains the number of tasks per column grouped per day.' => 'Cet export contient le nombre de tâches par colonne groupé par jour.', - 'Active swimlanes' => 'Swimlanes actives', - 'Add a new swimlane' => 'Ajouter une nouvelle swimlane', - 'Change default swimlane' => 'Modifier la swimlane par défaut', - 'Default swimlane' => 'Swimlane par défaut', - 'Do you really want to remove this swimlane: "%s"?' => 'Voulez-vous vraiment supprimer cette swimlane : « %s » ?', - 'Inactive swimlanes' => 'Swimlanes inactives', - 'Remove a swimlane' => 'Supprimer une swimlane', - 'Show default swimlane' => 'Afficher la swimlane par défaut', - 'Swimlane modification for the project "%s"' => 'Modification d\'une swimlane pour le projet « %s »', - 'Swimlane removed successfully.' => 'Swimlane supprimée avec succès.', - 'Swimlanes' => 'Swimlanes', - 'Swimlane updated successfully.' => 'Swimlane mise à jour avec succès.', - 'The default swimlane have been updated successfully.' => 'La swimlane par défaut a été mise à jour avec succès.', - 'Unable to remove this swimlane.' => 'Impossible de supprimer cette swimlane.', - 'Unable to update this swimlane.' => 'Impossible de mettre à jour cette swimlane.', - 'Your swimlane have been created successfully.' => 'Votre swimlane a été créée avec succès.', - 'Example: "Bug, Feature Request, Improvement"' => 'Exemple: « Incident, Demande de fonctionnalité, Amélioration »', - 'Default categories for new projects (Comma-separated)' => 'Catégories par défaut pour les nouveaux projets (séparation par des virgules)', - 'Integrations' => 'Intégrations', - 'Integration with third-party services' => 'Intégration avec des services externes', - 'Subtask Id' => 'Identifiant de la sous-tâche', - 'Subtasks' => 'Sous-tâches', - 'Subtasks Export' => 'Exportation des sous-tâches', - 'Subtasks exportation for "%s"' => 'Exportation des sous-tâches pour le projet « %s »', - 'Task Title' => 'Titre de la tâche', - 'Untitled' => 'Sans nom', - 'Application default' => 'Valeur par défaut de l\'application', - 'Language:' => 'Langue :', - 'Timezone:' => 'Fuseau horaire :', - 'All columns' => 'Toutes les colonnes', - 'Calendar' => 'Agenda', - 'Next' => 'Suivant', - '#%d' => 'n˚%d', - 'All swimlanes' => 'Toutes les swimlanes', - 'All colors' => 'Toutes les couleurs', - 'Moved to column %s' => 'Tâche déplacée à la colonne %s', - 'User dashboard' => 'Tableau de bord de l\'utilisateur', - 'Allow only one subtask in progress at the same time for a user' => 'Autoriser une seule sous-tâche en progrès en même temps pour un utilisateur', - 'Edit column "%s"' => 'Modifier la colonne « %s »', - 'Select the new status of the subtask: "%s"' => 'Selectionnez le nouveau statut de la sous-tâche : « %s »', - 'Subtask timesheet' => 'Feuille de temps des sous-tâches', - 'There is nothing to show.' => 'Il n\'y a rien à montrer.', - 'Time Tracking' => 'Feuille de temps', - 'You already have one subtask in progress' => 'Vous avez déjà une sous-tâche en progrès', - 'Which parts of the project do you want to duplicate?' => 'Quelles parties du projet voulez-vous dupliquer ?', - 'Disallow login form' => 'Interdire le formulaire d\'authentification', - 'Start' => 'Début', - 'End' => 'Fin', - 'Task age in days' => 'Âge de la tâche en jours', - 'Days in this column' => 'Jours dans cette colonne', - '%dd' => '%dj', - 'Add a new link' => 'Ajouter un nouveau lien', - 'Do you really want to remove this link: "%s"?' => 'Voulez-vous vraiment supprimer ce lien : « %s » ?', - 'Do you really want to remove this link with task #%d?' => 'Voulez-vous vraiment supprimer ce lien avec la tâche n°%d ?', - 'Field required' => 'Champ obligatoire', - 'Link added successfully.' => 'Lien créé avec succès.', - 'Link updated successfully.' => 'Lien mis à jour avec succès.', - 'Link removed successfully.' => 'Lien supprimé avec succès.', - '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', - 'Unable to create your link.' => 'Impossible d\'ajouter ce lien.', - 'Unable to update your link.' => 'Impossible de mettre à jour ce lien.', - 'Unable to remove this link.' => 'Impossible de supprimer ce lien.', - 'relates to' => 'est liée à', - 'blocks' => 'bloque', - 'is blocked by' => 'est bloquée par', - 'duplicates' => 'duplique', - 'is duplicated by' => 'est dupliquée par', - 'is a child of' => 'est un enfant de', - 'is a parent of' => 'est un parent de', - 'targets milestone' => 'vise l\'étape importante', - 'is a milestone of' => 'est une étape importante incluant', - 'fixes' => 'corrige', - 'is fixed by' => 'est corrigée par', - 'This task' => 'Cette tâche', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Déplier les tâches', - 'Collapse tasks' => 'Replier les tâches', - 'Expand/collapse tasks' => 'Plier/déplier les tâches', - 'Close dialog box' => 'Fermer une boîte de dialogue', - 'Submit a form' => 'Enregistrer un formulaire', - 'Board view' => 'Page du tableau', - 'Keyboard shortcuts' => 'Raccourcis clavier', - 'Open board switcher' => 'Ouvrir le sélecteur de tableau', - 'Application' => 'Application', - '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', - 'CAD - Canadian Dollar' => 'CAD - Dollar canadien', - 'CHF - Swiss Francs' => 'CHF - Franc suisse', - 'Custom Stylesheet' => 'Feuille de style personalisée', - 'download' => 'télécharger', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Livre sterling', - 'INR - Indian Rupee' => 'INR - Roupie indienne', - 'JPY - Japanese Yen' => 'JPY - Yen', - 'NZD - New Zealand Dollar' => 'NZD - Dollar néo-zélandais', - 'RSD - Serbian dinar' => 'RSD - Dinar serbe', - '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', - 'Move the task to another column when assignee is cleared' => 'Déplacer la tâche dans une autre colonne lorsque celle-ci n\'est plus assignée', - 'Source column' => 'Colonne d\'origine', - 'Transitions' => 'Transitions', - 'Executer' => 'Exécutant', - 'Time spent in the column' => 'Temps passé dans la colonne', - 'Task transitions' => 'Transitions des tâches', - 'Task transitions export' => 'Export des transitions des tâches', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Ce rapport contient tous les mouvements de colonne pour chaque tâche avec la date, l\'utilisateur et le temps passé pour chaque transition.', - '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', - 'Webhook URL' => 'URL du webhook', - '%s remove the assignee of the task %s' => '%s a enlevé la personne assignée à la tâche %s', - 'Enable Gravatar images' => 'Activer les images Gravatar', - 'Information' => 'Informations', - 'Check two factor authentication code' => 'Vérification du code pour l\'authentification à deux-facteurs', - 'The two factor authentication code is not valid.' => 'Le code pour l\'authentification à deux-facteurs n\'est pas valide.', - 'The two factor authentication code is valid.' => 'Le code pour l\'authentification à deux-facteurs est valide.', - 'Code' => 'Code', - 'Two factor authentication' => 'Authentification à deux-facteurs', - 'This QR code contains the key URI: ' => 'Ce code QR contient l\'url de la clé : ', - 'Check my code' => 'Vérifier mon code', - 'Secret key: ' => 'Clé secrète : ', - 'Test your device' => 'Testez votre appareil', - 'Assign a color when the task is moved to a specific column' => 'Assigner une couleur lorsque la tâche est déplacée dans une colonne spécifique', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Graphique d\'avancement pour « %s »', - 'Burndown chart' => 'Graphique d\'avancement', - 'This chart show the task complexity over the time (Work Remaining).' => 'Ce graphique représente la complexité des tâches en fonction du temps (travail restant).', - 'Screenshot taken %s' => 'Capture d\'écran prise le %s', - 'Add a screenshot' => 'Ajouter une capture d\'écran', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Prenez une capture d\'écran et appuyez sur CTRL+V ou ⌘+V pour coller ici.', - 'Screenshot uploaded successfully.' => 'Capture d\'écran téléchargée avec succès.', - 'SEK - Swedish Krona' => 'SEK - Couronne suédoise', - 'Identifier' => 'Identificateur', - 'Disable two factor authentication' => 'Désactiver l\'authentification à deux facteurs', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Voulez-vous vraiment désactiver l\'authentification à deux facteurs pour cet utilisateur : « %s » ?', - 'Edit link' => 'Modifier un lien', - 'Start to type task title...' => 'Entrez le titre de la tâche...', - 'A task cannot be linked to itself' => 'Une tâche ne peut être liée à elle-même', - 'The exact same link already exists' => 'Un lien identique existe déjà', - 'Recurrent task is scheduled to be generated' => 'La tâche récurrente est programmée pour être créée', - 'Score' => 'Complexité', - 'The identifier must be unique' => 'L\'identifiant doit être unique', - 'This linked task id doesn\'t exists' => 'L\'identifiant de la task liée n\'existe pas', - 'This value must be alphanumeric' => 'Cette valeur doit être alphanumérique', - 'Edit recurrence' => 'Modifier la récurrence', - 'Generate recurrent task' => 'Générer une tâche récurrente', - 'Trigger to generate recurrent task' => 'Déclencheur pour générer la tâche récurrente', - 'Factor to calculate new due date' => 'Facteur pour calculer la nouvelle date d\'échéance', - 'Timeframe to calculate new due date' => 'Échelle de temps pour calculer la nouvelle date d\'échéance', - 'Base date to calculate new due date' => 'Date à utiliser pour calculer la nouvelle date d\'échéance', - 'Action date' => 'Date de l\'action', - 'Base date to calculate new due date: ' => 'Date utilisée pour calculer la nouvelle date d\'échéance : ', - 'This task has created this child task: ' => 'Cette tâche a créée la tâche enfant : ', - 'Day(s)' => 'Jour(s)', - 'Existing due date' => 'Date d\'échéance existante', - 'Factor to calculate new due date: ' => 'Facteur pour calculer la nouvelle date d\'échéance : ', - 'Month(s)' => 'Mois', - 'Recurrence' => 'Récurrence', - 'This task has been created by: ' => 'Cette tâche a été créée par :', - 'Recurrent task has been generated:' => 'Une tâche récurrente a été générée :', - 'Timeframe to calculate new due date: ' => 'Échelle de temps pour calculer la nouvelle date d\'échéance : ', - 'Trigger to generate recurrent task: ' => 'Déclencheur pour générer la tâche récurrente : ', - 'When task is closed' => 'Lorsque la tâche est fermée', - 'When task is moved from first column' => 'Lorsque la tâche est déplacée en dehors de la première colonne', - 'When task is moved to last column' => 'Lorsque la tâche est déplacée dans la dernière colonne', - 'Year(s)' => 'Année(s)', - 'Calendar settings' => 'Paramètres du calendrier', - 'Project calendar view' => 'Vue en mode projet du calendrier', - 'Project settings' => 'Paramètres du projet', - 'Show subtasks based on the time tracking' => 'Afficher les sous-tâches basé sur le suivi du temps', - 'Show tasks based on the creation date' => 'Afficher les tâches en fonction de la date de création', - 'Show tasks based on the start date' => 'Afficher les tâches en fonction de la date de début', - 'Subtasks time tracking' => 'Suivi du temps par rapport aux sous-tâches', - 'User calendar view' => 'Vue en mode utilisateur du calendrier', - 'Automatically update the start date' => 'Mettre à jour automatiquement la date de début', - 'iCal feed' => 'Abonnement iCal', - 'Preferences' => 'Préférences', - 'Security' => 'Sécurité', - 'Two factor authentication disabled' => 'Authentification à deux facteurs désactivée', - 'Two factor authentication enabled' => 'Authentification à deux facteurs activée', - 'Unable to update this user.' => 'Impossible de mettre à jour cet utilisateur.', - 'There is no user management for private projects.' => 'Il n\'y a pas de gestion d\'utilisateurs pour les projets privés.', - 'User that will receive the email' => 'Utilisateur qui va reçevoir l\'email', - 'Email subject' => 'Sujet de l\'email', - 'Date' => 'Date', - 'Add a comment log when moving the task between columns' => 'Ajouter un commentaire d\'information lorsque une tâche est déplacée dans une autre colonne', - 'Move the task to another column when the category is changed' => 'Déplacer une tâche vers une autre colonne lorsque la catégorie a changé', - 'Send a task by email to someone' => 'Envoyer une tâche par email à quelqu\'un', - 'Reopen a task' => 'Rouvrir une tâche', - 'Column change' => 'Changement de colonne', - 'Position change' => 'Changement de position', - 'Swimlane change' => 'Changement de swimlane', - 'Assignee change' => 'Changement d\'assigné', - '[%s] Overdue tasks' => '[%s] Tâches en retard', - 'Notification' => 'Notification', - '%s moved the task #%d to the first swimlane' => '%s a déplacé la tâche n°%d dans la première swimlane', - '%s moved the task #%d to the swimlane "%s"' => '%s a déplacé la tâche n°%d dans la swimlane « %s »', - 'Swimlane' => 'Swimlane', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s a déplacé la tâche %s dans la première swimlane', - '%s moved the task %s to the swimlane "%s"' => '%s a déplacé la tâche %s dans la swimlane « %s »', - 'This report contains all subtasks information for the given date range.' => 'Ce rapport contient les informations de toutes les sous-tâches pour la période sélectionnée.', - 'This report contains all tasks information for the given date range.' => 'Ce rapport contient les informations de toutes les tâches pour la période sélectionnée.', - 'Project activities for %s' => 'Activité des projets pour « %s »', - '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', - 'There is no category now' => 'Il n\'y a plus de catégorie maintenant', - 'New category: %s' => 'Nouvelle catégorie : %s', - 'New color: %s' => 'Nouvelle couleur : %s', - 'New complexity: %d' => 'Nouvelle complexité : %d', - 'The due date have been removed' => 'La date d\'échéance a été enlevée', - 'There is no description anymore' => 'Il n\'y a plus de description maintenant', - 'Recurrence settings have been modified' => 'Les réglages de la récurrence ont été modifiés', - 'Time spent changed: %sh' => 'Le temps passé a été changé : %sh', - 'Time estimated changed: %sh' => 'Le temps estimé a été changé : %sh', - 'The field "%s" have been updated' => 'Le champ « %s » a été mis à jour', - 'The description has been modified:' => 'La description a été modifiée', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Voulez-vous vraiment fermer la tâche « %s » ainsi que toutes ses sous-tâches ?', - 'I want to receive notifications for:' => 'Je veux reçevoir les notifications pour :', - 'All tasks' => 'Toutes les Tâches', - 'Only for tasks assigned to me' => 'Seulement les tâches qui me sont assignées', - 'Only for tasks created by me' => 'Seulement les tâches que j\'ai créées', - 'Only for tasks created by me and assigned to me' => 'Seulement les tâches créées par moi-même et celles qui me sont assignées', - '%%Y-%%m-%%d' => '%%d/%%m/%%Y', - 'Total for all columns' => 'Total pour toutes les colonnes', - 'You need at least 2 days of data to show the chart.' => 'Vous avez besoin d\'au minimum 2 jours de données pour afficher le graphique.', - '<15m' => '<15m', - '<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', - 'Reset filters' => 'Réinitialiser les filtres', - 'My tasks due tomorrow' => 'Mes tâches qui arrivent à échéance demain', - 'Tasks due today' => 'Tâches qui arrivent à échéance aujourd\'hui', - 'Tasks due tomorrow' => 'Tâches qui arrivent à échéance demain', - 'Tasks due yesterday' => 'Tâches qui sont arrivées à échéance hier', - 'Closed tasks' => 'Tâches fermées', - 'Open tasks' => 'Tâches ouvertes', - 'Not assigned' => 'Non assignées', - 'View advanced search syntax' => 'Voir la syntaxe pour la recherche avancée', - 'Overview' => 'Vue d\'ensemble', - 'Board/Calendar/List view' => 'Vue Tableau/Calendrier/Liste', - 'Switch to the board view' => 'Basculer vers le tableau', - 'Switch to the calendar view' => 'Basculer vers le calendrier', - 'Switch to the list view' => 'Basculer vers la vue en liste', - 'Go to the search/filter box' => 'Aller au champ de recherche', - 'There is no activity yet.' => 'Il n\'y a pas encore d\'activité.', - 'No tasks found.' => 'Aucune tâche trouvée.', - 'Keyboard shortcut: "%s"' => 'Raccourci clavier : « %s »', - 'List' => 'Liste', - 'Filter' => 'Filtre', - 'Advanced search' => 'Recherche avancée', - 'Example of query: ' => 'Exemple de requête : ', - 'Search by project: ' => 'Rechercher par projet : ', - 'Search by column: ' => 'Rechercher par colonne : ', - 'Search by assignee: ' => 'Rechercher par assigné : ', - 'Search by color: ' => 'Rechercher par couleur : ', - 'Search by category: ' => 'Rechercher par catégorie : ', - 'Search by description: ' => 'Rechercher par description : ', - 'Search by due date: ' => 'Rechercher par date d\'échéance : ', - 'Lead and Cycle time for "%s"' => 'Lead et cycle time pour « %s »', - 'Average time spent into each column for "%s"' => 'Temps passé moyen dans chaque colonne pour « %s »', - 'Average time spent into each column' => 'Temps moyen passé dans chaque colonne', - 'Average time spent' => 'Temps moyen passé', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Ce graphique montre le temps passé moyen dans chaque colonne pour les %d dernières tâches.', - 'Average Lead and Cycle time' => 'Durée moyenne du lead et cycle time', - 'Average lead time: ' => 'Lead time moyen : ', - 'Average cycle time: ' => 'Cycle time moyen : ', - '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.' => 'Ce graphique montre la durée moyenne du lead et cycle time pour les %d dernières tâches.', - 'Average time into each column' => 'Temps moyen dans chaque colonne', - 'Lead and cycle time' => 'Lead et cycle time', - 'Lead time: ' => 'Lead time : ', - 'Cycle time: ' => 'Temps de cycle : ', - 'Time spent into each column' => 'Temps passé dans chaque colonne', - 'The lead time is the duration between the task creation and the completion.' => 'Le lead time est la durée entre la création de la tâche et sa complétion.', - 'The cycle time is the duration between the start date and the completion.' => 'Le cycle time est la durée entre la date de début et la complétion.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Si la tâche n\'est pas fermée, l\'heure courante est utilisée à la place de la date de complétion.', - 'Set automatically the start date' => 'Définir automatiquement la date de début', - 'Edit Authentication' => 'Modifier l\'authentification', - '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.', - 'Trigger automatically subtask time tracking' => 'Déclencher automatiquement le suivi du temps pour les sous-tâches', - 'Include closed tasks in the cumulative flow diagram' => 'Inclure les tâches fermées dans le diagramme de flux cumulé', - 'Current swimlane: %s' => 'Swimlane actuelle : %s', - 'Current column: %s' => 'Colonne actuelle : %s', - 'Current category: %s' => 'Catégorie actuelle : %s', - 'no category' => 'aucune catégorie', - 'Current assignee: %s' => 'Assigné actuel : %s', - 'not assigned' => 'non assigné', - 'Author:' => 'Auteur :', - 'contributors' => 'contributeurs', - 'License:' => 'Licence :', - 'License' => 'Licence', - 'Enter the text below' => 'Entrez le texte ci-dessous', - 'Gantt chart for %s' => 'Diagramme de Gantt pour %s', - 'Sort by position' => 'Trier par position', - 'Sort by date' => 'Trier par date', - 'Add task' => 'Ajouter une tâche', - 'Start date:' => 'Date de début :', - 'Due date:' => 'Date d\'échéance :', - 'There is no start date or due date for this task.' => 'Il n\'y a pas de date de début ou de date de fin pour cette tâche.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Déplacer ou redimensionner une tâche va changer la date de début et la date de fin de la tâche.', - 'There is no task in your project.' => 'Il n\'y a aucune tâche dans votre projet.', - 'Gantt chart' => 'Diagramme de Gantt', - 'People who are project managers' => 'Personnes qui sont gestionnaires de projet', - 'People who are project members' => 'Personnes qui sont membres de projet', - 'NOK - Norwegian Krone' => 'NOK - Couronne norvégienne', - 'Show this column' => 'Montrer cette colonne', - 'Hide this column' => 'Cacher cette colonne', - 'open file' => 'ouvrir le fichier', - 'End date' => 'Date de fin', - 'Users overview' => 'Vue d\'ensemble des utilisateurs', - 'Members' => 'Membres', - 'Shared project' => 'Projet partagé', - 'Project managers' => 'Gestionnaires de projet', - 'Gantt chart for all projects' => 'Diagramme de Gantt pour tous les projets', - 'Projects list' => 'Liste des projets', - 'Gantt chart for this project' => 'Diagramme de Gantt pour ce projet', - 'Project board' => 'Tableau du projet', - 'End date:' => 'Date de fin :', - 'There is no start date or end date for this project.' => 'Il n\'y a pas de date de début ou de date de fin pour ce projet.', - 'Projects Gantt chart' => 'Diagramme de Gantt des projets', - 'Change task color when using a specific task link' => 'Changer la couleur de la tâche lorsqu\'un lien spécifique est utilisé', - 'Task link creation or modification' => 'Création ou modification d\'un lien sur une tâche', - 'Milestone' => 'Étape importante', - 'Documentation: %s' => 'Documentation : %s', - 'Switch to the Gantt chart view' => 'Passer à la vue en diagramme de Gantt', - 'Reset the search/filter box' => 'Réinitialiser le champ de recherche', - 'Documentation' => 'Documentation', - 'Table of contents' => 'Table des matières', - 'Gantt' => 'Gantt', - 'Author' => 'Auteur', - 'Version' => 'Version', - 'Plugins' => 'Extensions', - 'There is no plugin loaded.' => 'Il n\'y a aucune extension chargée.', - 'Set maximum column height' => 'Définir la hauteur max. des colonnes', - 'Remove maximum column height' => 'Enlever la hauteur max. des colonnes', - 'My notifications' => 'Mes notifications', - 'Custom filters' => 'Filtres personalisés', - 'Your custom filter have been created successfully.' => 'Votre filter personalisé a été créé avec succès.', - 'Unable to create your custom filter.' => 'Impossible de créer votre filter personalisé.', - 'Custom filter removed successfully.' => 'Filtre personalisé supprimé avec succès.', - 'Unable to remove this custom filter.' => 'Impossible de supprimer ce filter personalisé.', - 'Edit custom filter' => 'Modification d\'un filtre personalisé', - 'Your custom filter have been updated successfully.' => 'Votre filtre personalisé a été mis à jour avec succès.', - 'Unable to update custom filter.' => 'Impossible de mettre à jour votre filtre personalisé.', - 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Nouveau fichier joint sur la tâche n°%d : %s', - 'New comment on task #%d' => 'Nouveau commentaire sur la tâche n°%d', - 'Comment updated on task #%d' => 'Commentaire mis à jour sur la tâche n°%d', - 'New subtask on task #%d' => 'Nouvelle sous-tâche sur la tâche n°%d', - 'Subtask updated on task #%d' => 'Sous-tâche mise à jour sur la tâche n°%d', - 'New task #%d: %s' => 'Nouvelle tâche n°%d : %s', - 'Task updated #%d' => 'Tâche n°%d mise à jour', - 'Task #%d closed' => 'Tâche n°%d fermée', - 'Task #%d opened' => 'Tâche n°%d ouverte', - 'Column changed for task #%d' => 'Changement de colonne pour la tâche n°%d', - 'New position for task #%d' => 'Nouvelle position pour la tâche n°%d', - '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', - 'No new notifications.' => 'Aucune notification.', - 'Mark all as read' => 'Tout marquer comme lu', - 'Mark as read' => 'Marquer comme lu', - 'Total number of tasks in this column across all swimlanes' => 'Nombre total de tâches dans cette colonne pour toutes les swimlanes', - 'Collapse swimlane' => 'Replier la swimlane', - 'Expand swimlane' => 'Déplier la swimlane', - 'Add a new filter' => 'Ajouter un nouveau filtre', - 'Share with all project members' => 'Partager avec tous les membres du projet', - 'Shared' => 'Partagé', - '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é', - 'Import users from CSV file' => 'Importer des utilisateurs depuis un fichier CSV', - '%d user(s) have been imported successfully.' => '%d utilisateur(s) ont été importés avec succès.', - 'Comma' => 'Virgule', - 'Semi-colon' => 'Point-virgule', - 'Tab' => 'Tabulation', - 'Vertical bar' => 'Barre verticale', - 'Double Quote' => 'Guillemet double', - 'Single Quote' => 'Guillement simple', - '%s attached a file to the task #%d' => '%s a attaché un fichier sur la tâche n°%d', - 'There is no column or swimlane activated in your project!' => 'Il n\'y a aucune colonne ou swimlane dans votre projet !', - 'Append filter (instead of replacement)' => 'Ajouter le filtre au lieu de le remplaçer', - 'Append/Replace' => 'Ajouter/Remplaçer', - 'Append' => 'Ajouter', - 'Replace' => 'Remplaçer', - 'Import' => 'Importation', - 'change sorting' => 'changer l\'ordre', - 'Tasks Importation' => 'Importation des tâches', - 'Delimiter' => 'Délimiteur', - 'Enclosure' => 'Caractère d\'encadrement', - 'CSV File' => 'Fichier CSV', - 'Instructions' => 'Instructions', - 'Your file must use the predefined CSV format' => 'Votre fichier doit utiliser le format CSV prédéfini', - 'Your file must be encoded in UTF-8' => 'Votre fichier doit être encodé en UTF-8', - 'The first row must be the header' => 'La première ligne doit être le titre des colonnes', - 'Duplicates are not verified for you' => 'Les doublons ne sont pas vérifiés pour vous', - 'The due date must use the ISO format: YYYY-MM-DD' => 'La date d\'échéance doit utiliser le format ISO : AAAA-MM-JJ', - 'Download CSV template' => 'Télécharger le modèle CSV', - 'No external integration registered.' => 'Aucune intégration externe enregistrée.', - 'Duplicates are not imported' => 'Les doublons ne sont pas importés', - 'Usernames must be lowercase and unique' => 'Les noms d\'utilisateurs doivent être en minuscule et unique', - 'Passwords will be encrypted if present' => 'Les mots de passe seront chiffrés si présent', - '%s attached a new file to the task %s' => '%s a attaché un nouveau fichier à la tâche %s', - 'Link type' => 'Type de lien', - 'Assign automatically a category based on a link' => 'Assigner automatiquement une catégorie en fonction d\'un lien', - 'BAM - Konvertible Mark' => 'BAM - Mark convertible', - 'Assignee Username' => 'Utilisateur assigné', - 'Assignee Name' => 'Nom de l\'assigné', - 'Groups' => 'Groupes', - 'Members of %s' => 'Membres de %s', - 'New group' => 'Nouveau groupe', - 'Group created successfully.' => 'Groupe créé avec succès.', - 'Unable to create your group.' => 'Impossible de créé votre groupe.', - 'Edit group' => 'Modifier le groupe', - 'Group updated successfully.' => 'Groupe mis à jour avec succès.', - 'Unable to update your group.' => 'Impossible de mettre à jour votre groupe.', - 'Add group member to "%s"' => 'Ajouter un membre au groupe « %s »', - 'Group member added successfully.' => 'Membre ajouté avec succès au groupe.', - 'Unable to add group member.' => 'Impossible d\'ajouter ce membre au groupe.', - 'Remove user from group "%s"' => 'Supprimer un utilisateur d\'un groupe « %s »', - 'User removed successfully from this group.' => 'Utilisateur supprimé avec succès de ce groupe.', - 'Unable to remove this user from the group.' => 'Impossible de supprimer cet utilisateur du groupe.', - 'Remove group' => 'Supprimer le groupe', - 'Group removed successfully.' => 'Groupe supprimé avec succès.', - 'Unable to remove this group.' => 'Impossible de supprimer ce groupe.', - 'Project Permissions' => 'Permissions du projet', - 'Manager' => 'Gestionnaire', - 'Project Manager' => 'Chef de projet', - 'Project Member' => 'Membre du projet', - 'Project Viewer' => 'Visualiseur de projet', - 'Your account is locked for %d minutes' => 'Votre compte est vérouillé pour %d minutes', - 'Invalid captcha' => 'Captcha invalid', - 'The name must be unique' => 'Le nom doit être unique', - 'View all groups' => 'Voir tous les groupes', - 'View group members' => 'Voir les membres du groupe', - 'There is no user available.' => 'Il n\'y a aucun utilisateur disponible', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Voulez-vous vraiment supprimer l\'utilisateur « %s » du groupe « %s » ?', - 'There is no group.' => 'Il n\'y a aucun groupe.', - 'External Id' => 'Identifiant externe', - 'Add group member' => 'Ajouter un membre au groupe', - 'Do you really want to remove this group: "%s"?' => 'Voulez-vous vraiment supprimer ce groupe : « %s » ?', - 'There is no user in this group.' => 'Il n\'y a aucun utilisateur dans ce groupe', - 'Remove this user' => 'Supprimer cet utilisateur', - 'Permissions' => 'Permissions', - 'Allowed Users' => 'Utilisateurs autorisés', - 'No user have been allowed specifically.' => 'Aucun utilisateur a été autorisé spécifiquement.', - 'Role' => 'Rôle', - 'Enter user name...' => 'Entrez le nom de l\'utilisateur...', - 'Allowed Groups' => 'Groupes autorisés', - 'No group have been allowed specifically.' => 'Aucun groupe a été autorisé spécifiquement.', - 'Group' => 'Groupe', - 'Group Name' => 'Nom du groupe', - 'Enter group name...' => 'Entrez le nom du groupe...', - 'Role:' => 'Rôle :', - 'Project members' => 'Membres du projet', - 'Compare hours for "%s"' => 'Comparer les heures pour « %s »', - '%s mentioned you in the task #%d' => '%s vous a mentionné dans la tâche n°%d', - '%s mentioned you in a comment on the task #%d' => '%s vous a mentionné dans un commentaire de la tâche n°%d', - 'You were mentioned in the task #%d' => 'Vous avez été mentionné dans la tâche n°%d', - 'You were mentioned in a comment on the task #%d' => 'Vous avez été mentionné dans un commentaire de la tâche n°%d', - 'Mentioned' => 'Mentionné', - 'Compare Estimated Time vs Actual Time' => 'Comparer le temps estimé et le temps actuel', - 'Estimated hours: ' => 'Heures estimées : ', - 'Actual hours: ' => 'Heures actuelles : ', - 'Hours Spent' => 'Heures passées', - 'Hours Estimated' => 'Heures estimées', - 'Estimated Time' => 'Temps estimé', - 'Actual Time' => 'Temps actuel', - 'Estimated vs actual time' => 'Temps estimé vs actuel', - 'RUB - Russian Ruble' => 'RUB - Rouble russe', - 'Assign the task to the person who does the action when the column is changed' => 'Assigner la tâche à la personne qui fait l\'action lorsque la colonne est changée', - 'Close a task in a specific column' => 'Fermer une tâche dans une colonne specifique', - 'Time-based One-time Password Algorithm' => 'Mot de passe à usage unique basé sur le temps', - 'Two-Factor Provider: ' => 'Fournisseur d\'authentification à deux facteurs : ', - 'Disable two-factor authentication' => 'Désactiver l\'authentification à deux-facteurs', - 'Enable two-factor authentication' => 'Activer l\'authentification à deux-facteurs', - 'There is no integration registered at the moment.' => 'Il n\'y a aucune intégration enregistrée pour le moment.', - 'Password Reset for Kanboard' => 'Réinitialisation du mot de passe pour Kanboard', - 'Forgot password?' => 'Mot de passe oublié ?', - 'Enable "Forget Password"' => 'Activer la fonctionnalité « Mot de passe oublié »', - 'Password Reset' => 'Réinitialisation du mot de passe', - 'New password' => 'Nouveau mot de passe', - 'Change Password' => 'Changer de mot de passe', - 'To reset your password click on this link:' => 'Pour réinitialiser votre mot de passe cliquer sur ce lien :', - 'Last Password Reset' => 'Dernières réinitialisation de mot de passe', - 'The password has never been reinitialized.' => 'Le mot de passe n\'a jamais été réinitialisé.', - 'Creation' => 'Création', - 'Expiration' => 'Expiration', - 'Password reset history' => 'Historique de la réinitialisation du mot de passe', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Toutes les tâches de la colonne « %s » et de la swimlane « %s » ont été fermées avec succès.', - '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.', - '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é', - 'Task priority' => 'Priorité des tâches', - 'General' => 'Général', - 'Dates' => 'Dates', - 'Default priority' => 'Priorité par défaut', - 'Lowest priority' => 'Priorité basse', - 'Highest priority' => 'Priorité haute', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Si vous mettez zéro pour la priorité basse et haute, cette fonctionnalité sera désactivée.', - 'Close a task when there is no activity' => 'Fermer une tâche sans activité', - 'Duration in days' => 'Durée en jours', - 'Send email when there is no activity on a task' => 'Envoyer un email lorsqu\'il n\'y a pas d\'activité sur une tâche', - 'Unable to fetch link information.' => 'Impossible de récupérer les informations sur le lien.', - 'Daily background job for tasks' => 'Tâche planifiée quotidienne pour les tâches', - 'Auto' => 'Auto', - 'Related' => 'Relié', - 'Attachment' => 'Pièce-jointe', - 'Title not found' => 'Titre non trouvé', - 'Web Link' => 'Lien web', - 'External links' => 'Liens externes', - 'Add external link' => 'Ajouter un lien externe', - 'Type' => 'Type', - 'Dependency' => 'Dépendance', - 'Add internal link' => 'Ajouter un lien interne', - 'Add a new external link' => 'Ajouter un nouveau lien externe', - 'Edit external link' => 'Modifier un lien externe', - 'External link' => 'Lien externe', - 'Copy and paste your link here...' => 'Copier-coller vôtre lien ici...', - 'URL' => 'URL', - 'Internal links' => 'Liens internes', - 'Assign to me' => 'Assigner à moi', - 'Me' => 'Moi', - 'Do not duplicate anything' => 'Ne rien dupliquer', - 'Projects management' => 'Gestion des projets', - 'Users management' => 'Gestion des utilisateurs', - 'Groups management' => 'Gestion des groupes', - 'Create from another project' => 'Créer depuis un autre projet', - 'open' => 'ouvert', - 'closed' => 'fermé', - 'Priority:' => 'Priorité :', - 'Reference:' => 'Référence :', - 'Complexity:' => 'Complexité :', - 'Swimlane:' => 'Swimlane :', - 'Column:' => 'Colonne :', - 'Position:' => 'Position :', - 'Creator:' => 'Créateur :', - 'Time estimated:' => 'Temps estimé :', - '%s hours' => '%s heures', - 'Time spent:' => 'Temps passé :', - 'Created:' => 'Créé le :', - 'Modified:' => 'Modifié le :', - 'Completed:' => 'Terminé le :', - '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 : ', - 'New due date: ' => 'Nouvelle date d\'échéance : ', - 'Start date changed: ' => 'Date de début modifiée : ', - 'Disable private projects' => 'Désactiver les projets privés', - 'Do you really want to remove this custom filter: "%s"?' => 'Voulez-vous vraiment supprimer ce filtre personnalisé : « %s » ?', - 'Remove a custom filter' => 'Supprimer un filtre personnalisé', - 'User activated successfully.' => 'Utilisateur activé avec succès.', - 'Unable to enable this user.' => 'Impossible d\'activer cet utilisateur.', - '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', - 'Two Factor' => 'Deux-Facteurs', - 'Disable user' => 'Désactiver l\'utilisateur', - 'Do you really want to disable this user: "%s"?' => 'Voulez-vous vraiment désactiver cet utilisateur : « %s » ?', - 'Enable user' => 'Activer un utilisateur', - 'Do you really want to enable this user: "%s"?' => 'Voulez-vous vraiment activer cet utilisateur : « %s » ?', - 'Download' => 'Télécharger', - 'Uploaded: %s' => 'Uploadé : %s', - 'Size: %s' => 'Taille : %s', - 'Uploaded by %s' => 'Uploadé par %s', - 'Filename' => 'Nom du fichier', - 'Size' => 'Taille', - 'Column created successfully.' => 'La colonne a été créée avec succès.', - 'Another column with the same name exists in the project' => 'Une autre colonne existe avec le même nom dans le projet', - 'Default filters' => 'Filtres par défaut', - 'Your board doesn\'t have any columns!' => 'Votre tableau n\'a aucune colonne', - 'Change column position' => 'Changer la position de la colonne', - 'Switch to the project overview' => 'Aller à l\'aperçu du projet', - 'User filters' => 'Filtres des utilisateurs', - 'Category filters' => 'Filtres des catégories', - 'Upload a file' => 'Uploader un fichier', - 'View file' => 'Voir le fichier', - 'Last activity' => 'Dernières activités', - 'Change subtask position' => 'Changer la position de la sous-tâche', - 'This value must be greater than %d' => 'Cette valeur doit être plus grande que %d', - 'Another swimlane with the same name exists in the project' => 'Une autre swimlane existe avec le même nom dans le projet', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Exemple : http://exemple.kanboard.net/ (utilisé pour générer les URLs absolues)', - 'Actions duplicated successfully.' => 'Actions dupliquées avec succès.', - 'Unable to duplicate actions.' => 'Impossible de dupliquer les actions.', - 'Add a new action' => 'Ajouter une nouvelle action', - 'Import from another project' => 'Importer depuis un autre projet', - 'There is no action at the moment.' => 'Il n\'y a aucune action pour le moment.', - 'Import actions from another project' => 'Importer les actions depuis un autre projet', - 'There is no available project.' => 'Il n\'y a pas de projet disponible.', - 'Local File' => 'Fichier local', - 'Configuration' => 'Configuration', - 'PHP version:' => 'Version de PHP :', - 'PHP SAPI:' => 'PHP SAPI :', - 'OS version:' => 'Version du système d\'exploitation :', - 'Database version:' => 'Version de la base de donnée :', - 'Browser:' => 'Navigateur web :', - 'Task view' => 'Vue détaillée d\'une tâche', - 'Edit task' => 'Modifier la tâche', - 'Edit description' => 'Modifier la description', - 'New internal link' => 'Nouveau lien interne', - 'Display list of keyboard shortcuts' => 'Afficher la liste des raccourcis claviers', - 'Menu' => 'Menu', - 'Set start date' => 'Définir la date de début', - 'Avatar' => 'Avatar', - 'Upload my avatar image' => 'Uploader mon image d\'avatar', - 'Remove my image' => 'Supprimer mon image', - 'The OAuth2 state parameter is invalid' => 'Le paramètre "state" de OAuth2 est invalide', - 'User not found.' => 'Utilisateur introuvable.', - 'Search in activity stream' => 'Chercher dans le flux d\'activité', - 'My activities' => 'Mes activités', - 'Activity until yesterday' => 'Activités jusqu\'à hier', - 'Activity until today' => 'Activités jusqu\'à aujourd\'hui', - 'Search by creator: ' => 'Rechercher par créateur : ', - 'Search by creation date: ' => 'Rechercher par date de création : ', - 'Search by task status: ' => 'Rechercher par le statut des tâches : ', - 'Search by task title: ' => 'Rechercher par le titre des tâches : ', - 'Activity stream search' => 'Recherche dans le flux d\'activité', - 'Projects where "%s" is manager' => 'Projets où « %s » est gestionnaire', - 'Projects where "%s" is member' => 'Projets où « %s » est membre du projet', - 'Open tasks assigned to "%s"' => 'Tâches ouvertes assignées à « %s »', - 'Closed tasks assigned to "%s"' => 'Tâches fermées assignées à « %s »', - 'Assign automatically a color based on a priority' => 'Assigner automatiquement une couleur par rapport à une priorité', - 'Overdue tasks for the project(s) "%s"' => 'Tâches en retard pour le projet(s) « %s »', - 'Upload files' => 'Uploader les fichiers', - 'Installed Plugins' => 'Extensions installées', - 'Plugin Directory' => 'Liste des extensions', - 'Plugin installed successfully.' => 'Extension installée avec succès.', - 'Plugin updated successfully.' => 'Extension mise à jour avec succès.', - 'Plugin removed successfully.' => 'Extension supprimée avec succès.', - 'Subtask converted to task successfully.' => 'Sous-tâche convertie en tâche avec succès.', - 'Unable to convert the subtask.' => 'Impossible de convertir cette sous-tâche.', - 'Unable to extract plugin archive.' => 'Impossible d\'extraire l\'archive de l\'extension.', - 'Plugin not found.' => 'Extension introuvable.', - 'You don\'t have the permission to remove this plugin.' => 'Vous n\'avez pas la permission de supprimer ce plugin.', - 'Unable to download plugin archive.' => 'Impossible de télécharger l\'achive du plugin.', - 'Unable to write temporary file for plugin.' => 'Impossible d\'écrire le fichier temporaire pour l\'extension.', - 'Unable to open plugin archive.' => 'Impossible d\'ouvrir l\'archive du plugin.', - 'There is no file in the plugin archive.' => 'Il n\'y a aucun fichier dans l\'archive du plugin.', - 'Create tasks in bulk' => 'Créer plusieurs tâches en même temps', - 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'Votre instance de Kanboard n\'est pas configurée pour installer des extension depuis l\'interface utilisateur.', - 'There is no plugin available.' => 'Il n\'a aucune extension disponible.', - 'Install' => 'Installer', - 'Update' => 'Mettre à jour', - 'Up to date' => 'À jour', - 'Not available' => 'Non disponible', - 'Remove plugin' => 'Supprimer l\'extension', - 'Do you really want to remove this plugin: "%s"?' => 'Voulez-vous vraiment supprimer cette extension : « %s » ?', - 'Uninstall' => 'Désinstaller', - 'Listing' => 'Listing', - 'Metadata' => 'Metadonnées', - 'Manage projects' => 'Gérer les projets', - 'Convert to task' => 'Convertir en tâche', - 'Convert sub-task to task' => 'Convertir une sous-tâche en tâche', - 'Do you really want to convert this sub-task to a task?' => 'Voulez-vous vraiment convertir cette sous-tâche en tâche ?', - 'My task title' => 'Mon titre pour la tâche', - 'Enter one task by line.' => 'Entrez une tâche par ligne.', - 'Number of failed login:' => 'Nombre de connexion échouées :', - 'Account locked until:' => 'Compte bloqué jusqu\'au :', - 'Email settings' => 'Paramètres des emails', - '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é.', - 'Tag updated successfully.' => 'Libellé mis à jour avec succès.', - 'Unable to update this tag.' => 'Impossible de mettre à jour ce libellé.', - 'Tag removed successfully.' => 'Libellé supprimé avec succès.', - 'Unable to remove this tag.' => 'Impossible de supprimer ce libellé.', - 'Global tags management' => 'Gestion des libellés globaux', - 'Tags' => 'Libellés', - 'Tags management' => 'Gestion des libellés', - 'Add new tag' => 'Ajouter un nouveau libellé', - 'Edit a tag' => 'Mettre à jour un libellé', - 'Project tags' => 'Libellés du projet', - 'There is no specific tag for this project at the moment.' => 'Il n\'y a aucun libellé spécifique pour ce projet pour le moment.', - 'Tag' => 'Libellé', - 'Remove a tag' => 'Supprimer un libellé', - 'Do you really want to remove this tag: "%s"?' => 'Voulez-vous vraiment supprimer ce libellé : « %s » ?', - 'Global tags' => 'Libellés globaux', - 'There is no global tag at the moment.' => 'Il n\'y a aucun libellé global pour le moment.', - 'This field cannot be empty' => 'Ce champ ne peut être vide', -); diff --git a/sources/app/Locale/hu_HU/translations.php b/sources/app/Locale/hu_HU/translations.php deleted file mode 100644 index c80c0a2..0000000 --- a/sources/app/Locale/hu_HU/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => ' ', - 'None' => 'Nincs', - 'edit' => 'szerkesztés', - 'Edit' => 'Szerkesztés', - 'remove' => 'törlés', - 'Remove' => 'Törlés', - 'Yes' => 'Igen', - 'No' => 'Nem', - 'cancel' => 'Mégsem', - 'or' => 'vagy', - 'Yellow' => 'Sárga', - 'Blue' => 'Kék', - 'Green' => 'Zöld', - 'Purple' => 'Lila', - 'Red' => 'Piros', - 'Orange' => 'Narancs', - 'Grey' => 'Szürke', - 'Brown' => 'Barna', - 'Deep Orange' => 'Sötét narancs', - 'Dark Grey' => 'Sötét szürke', - 'Pink' => 'Rózsaszín', - 'Teal' => 'Pávakék', - 'Cyan' => 'Ciánkék', - 'Lime' => 'Lime', - 'Light Green' => 'Világos zöld', - 'Amber' => 'Borostyán', - 'Save' => 'Mentés', - 'Login' => 'Bejelentkezés', - 'Official website:' => 'Hivatalos honlap:', - 'Unassigned' => 'Nincs felelős', - 'View this task' => 'Feladat megtekintése', - 'Remove user' => 'Felhasználó törlése', - 'Do you really want to remove this user: "%s"?' => 'Valóban törölni akarja ezt a felhasználót: "%s"?', - 'All users' => 'Minden felhasználó', - 'Username' => 'Felhasználónév', - 'Password' => 'Jelszó', - 'Administrator' => 'Rendszergazda', - 'Sign in' => 'Jelentkezzen be', - 'Users' => 'Felhasználók', - 'No user' => 'Nincs felhasználó', - 'Forbidden' => 'tiltott', - 'Access Forbidden' => 'Hozzáférés megtagadva', - 'Edit user' => 'Felhasználó módosítása', - 'Logout' => 'Kilépés', - 'Bad username or password' => 'Rossz felhasználónév vagy jelszó', - 'Edit project' => 'Projekt szerkesztése', - 'Name' => 'Név', - 'Projects' => 'Projektek', - 'No project' => 'Nincs projekt', - 'Project' => 'Projekt', - 'Status' => 'Állapot', - 'Tasks' => 'Feladat', - 'Board' => 'Tábla', - 'Actions' => 'Műveletek', - 'Inactive' => 'Inaktív', - 'Active' => 'Aktív', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Valóban törölni akarja ezt a projektet: "%s"?', - 'Remove project' => 'Projekt törlése', - 'Edit the board for "%s"' => 'Tábla szerkesztése: "%s"', - 'All projects' => 'Minden projekt', - 'Add a new column' => 'Új oszlop', - '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!', - 'Settings' => 'Beállítások', - 'Application settings' => 'Alkalmazás beállítások', - 'Language' => 'Nyelv', - 'Webhook token:' => 'Webhook token:', - 'API token:' => 'API token:', - 'Database size:' => 'Adatbázis méret:', - 'Download the database' => 'Adatbázis letöltése', - 'Optimize the database' => 'Adatbázis optimalizálása', - '(VACUUM command)' => '(VACUUM parancs)', - '(Gzip compressed Sqlite file)' => '(Gzip tömörített SQLite fájl)', - 'Close a task' => 'Feladat lezárása', - 'Edit a task' => 'Feladat módosítása', - 'Column' => 'Oszlop', - 'Color' => 'Szín', - 'Assignee' => 'Felelős', - 'Create another task' => 'Új feladat létrehozása', - 'New task' => 'Új feladat', - 'Open a task' => 'Feladat felnyitás', - 'Do you really want to open this task: "%s"?' => 'Valóban meg akarja nyitni ezt a feladatot: "%s"?', - 'Back to the board' => 'Vissza a táblához', - 'There is nobody assigned' => 'Nincs felelős', - 'Column on the board:' => 'Tábla oszlopa: ', - 'Close this task' => 'Feladat lezárása', - 'Open this task' => 'Feladat felnyitása', - 'There is no description.' => 'Nincs elérhető leírás.', - 'Add a new task' => 'Új feladat hozzáadása', - 'The username is required' => 'Felhasználói név szükséges', - 'The maximum length is %d characters' => 'A maximális hossz %d karakter', - 'The minimum length is %d characters' => 'A minimális hossza %d karakter', - 'The password is required' => 'Jelszó szükséges', - 'This value must be an integer' => 'Ez az érték csak egész szám lehet', - 'The username must be unique' => 'A felhasználó nevének egyedinek kell lennie', - 'The user id is required' => 'A felhasználói azonosítót meg kell adni', - 'Passwords don\'t match' => 'A jelszavak nem egyeznek', - 'The confirmation is required' => 'Megerősítés szükséges', - 'The project is required' => 'A projektet meg kell adni', - 'The id is required' => 'Az ID-t (azonosítót) meg kell adni', - 'The project id is required' => 'A projekt ID-t (azonosítót) meg kell adni', - 'The project name is required' => 'A projekt nevét meg kell adni', - 'The title is required' => 'A címet meg kell adni', - 'Settings saved successfully.' => 'A beállítások sikeresen mentve.', - 'Unable to save your settings.' => 'A beállítások mentése sikertelen.', - 'Database optimization done.' => 'Adatbázis optimalizálás kész.', - 'Your project have been created successfully.' => 'Projekt sikeresen létrehozva', - 'Unable to create your project.' => 'Projekt létrehozása sikertelen.', - 'Project updated successfully.' => 'Projekt sikeresen frissítve.', - 'Unable to update this project.' => 'Projekt frissítése sikertelen.', - 'Unable to remove this project.' => 'Projekt törlése sikertelen.', - 'Project removed successfully.' => 'Projekt sikeresen törölve.', - 'Project activated successfully.' => 'Projekt sikeresen aktiválva.', - 'Unable to activate this project.' => 'Projekt aktiválása sikertelen.', - 'Project disabled successfully.' => 'Projekt sikeresen letiltva.', - 'Unable to disable this project.' => 'Projekt letiltása sikertelen.', - 'Unable to open this task.' => 'A feladat felnyitása sikertelen.', - 'Task opened successfully.' => 'Feladat sikeresen megnyitva .', - 'Unable to close this task.' => 'A feladat lezárása sikertelen.', - 'Task closed successfully.' => 'Feladat sikeresen lezárva.', - 'Unable to update your task.' => 'Feladat frissítése sikertelen.', - 'Task updated successfully.' => 'Feladat sikeresen frissítve.', - 'Unable to create your task.' => 'Feladat létrehozása sikertelen.', - 'Task created successfully.' => 'Feladat sikeresen létrehozva.', - 'User created successfully.' => 'Felhasználó létrehozva.', - 'Unable to create your user.' => 'Felhasználó létrehozása sikertelen.', - 'User updated successfully.' => 'Felhasználó sikeresen frissítve.', - 'Unable to update your user.' => 'Felhasználó frissítése sikertelen.', - 'User removed successfully.' => 'Felhasználó sikeresen törölve.', - 'Unable to remove this user.' => 'Felhasználó törlése sikertelen.', - 'Board updated successfully.' => 'Tábla sikeresen frissítve.', - 'Ready' => 'Előkészítés', - 'Backlog' => 'Napló', - 'Work in progress' => 'Folyamatban', - 'Done' => 'Kész', - 'Application version:' => 'Alkalmazás verzió:', - 'Id' => 'ID', - '%d closed tasks' => '%d lezárt feladat', - 'No task for this project' => 'Nincs feladat ebben a projektben', - 'Public link' => 'Nyilvános hivatkozás', - 'Timezone' => 'Időzóna', - 'Sorry, I didn\'t find this information in my database!' => 'Ez az információ nem található az adatbázisban!', - 'Page not found' => 'Az oldal nem található', - 'Complexity' => 'Bonyolultság', - 'Task limit' => 'Maximális számú feladat', - '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ő', - 'Invalid date' => 'Érvénytelen dátum', - 'Automatic actions' => 'Automatikus intézkedések', - 'Your automatic action have been created successfully.' => 'Az automatikus intézkedés sikeresen elkészült.', - 'Unable to create your automatic action.' => 'Automatikus intézkedés létrehozása nem lehetséges.', - 'Remove an action' => 'Intézkedés törlése', - 'Unable to remove this action.' => 'Intézkedés törlése nem lehetséges.', - 'Action removed successfully.' => 'Intézkedés sikeresen törölve.', - 'Automatic actions for the project "%s"' => 'Automatikus intézkedések a projektben: "%s"', - 'Add an action' => 'Intézkedés létrehozása', - 'Event name' => 'Esemény neve', - 'Action name' => 'Intézkedés neve', - 'Action parameters' => 'Intézkedés paraméterei', - 'Action' => 'Intézkedés', - 'Event' => 'Esemény', - 'When the selected event occurs execute the corresponding action.' => 'Ha a kiválasztott esemény bekövetkezik, hajtsa végre a megfelelő intézkedéseket.', - 'Next step' => 'Következő lépés', - 'Define action parameters' => 'Határozza meg az intézkedés paramétereit', - 'Do you really want to remove this action: "%s"?' => 'Valóban törölni akarja ezt az intézkedést: "%s"?', - 'Remove an automatic action' => 'Automatikus intézkedés törlése', - 'Assign the task to a specific user' => 'Feladat kiosztása megadott felhasználónak', - 'Assign the task to the person who does the action' => 'Feladat kiosztása az intézkedő személynek', - 'Duplicate the task to another project' => 'Feladat másolása másik projektbe', - 'Move a task to another column' => 'Feladat mozgatása másik oszlopba', - 'Task modification' => 'Feladat módosítása', - 'Task creation' => 'Feladat létrehozása', - 'Closing a task' => 'Feladat lezárása', - 'Assign a color to a specific user' => 'Szín hozzárendelése a felhasználóhoz', - 'Column title' => 'Oszlopfejléc', - 'Position' => 'Pozíció', - 'Duplicate to another project' => 'Másolás másik projektbe', - 'Duplicate' => 'Másolás', - 'link' => 'hivatkozás', - 'Comment updated successfully.' => 'Megjegyzés sikeresen frissítve.', - 'Unable to update your comment.' => 'Megjegyzés frissítése sikertelen.', - 'Remove a comment' => 'Megjegyzés törlése', - 'Comment removed successfully.' => 'Megjegyzés sikeresen törölve.', - 'Unable to remove this comment.' => 'Megjegyzés törölése nem lehetséges.', - 'Do you really want to remove this comment?' => 'Valóban törölni szeretné ezt a megjegyzést?', - 'Current password for the user "%s"' => 'Felhasználó jelenlegi jelszava: "%s"', - 'The current password is required' => 'A jelenlegi jelszót meg kell adni', - 'Wrong password' => 'Hibás jelszó', - 'Unknown' => 'Ismeretlen', - 'Last logins' => 'Legutóbbi bejelentkezések', - 'Login date' => 'Bejelentkezés dátuma', - 'Authentication method' => 'Azonosítási módszer', - 'IP address' => 'IP-cím', - 'User agent' => 'User Agent', - 'Persistent connections' => 'Tartós (perzisztens) kapcsolatok', - 'No session.' => 'Nincs session.', - 'Expiration date' => 'Lejárati dátum', - 'Remember Me' => 'Emlékezz rám', - 'Creation date' => 'Létrehozás dátuma', - 'Everybody' => 'Minden felhasználó', - 'Open' => 'Nyitott', - 'Closed' => 'Lezárt', - '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', - 'Email address invalid' => 'Érvénytelen e-mail cím', - 'Your external account is not linked anymore to your profile.' => 'Az ön külső számlája és az ön profilja közötti kapcsolat megszűnt.', - 'Unable to unlink your external account.' => 'Nem sikerült megszüntetni a kapcsolatot az ön külső számlájával.', - 'External authentication failed' => 'A külső jelszó ellenőrzés nem sikerült', - 'Your external account is linked to your profile successfully.' => 'Az ön külső számlája sikeresen össze lett kapcsolva az ön profiljával.', - 'Email' => 'E-mail', - 'Task removed successfully.' => 'Feladat sikeresen törölve.', - 'Unable to remove this task.' => 'A feladatot nem lehet törölni.', - 'Remove a task' => 'Feladat törlése', - 'Do you really want to remove this task: "%s"?' => 'Valóban törölni akarja ezt a feladatot: "%s"?', - 'Assign automatically a color based on a category' => 'Szín hozzárendelése automatikusan kategória alapján', - 'Assign automatically a category based on a color' => 'Kategória hozzárendelése automatikusan szín alapján', - 'Task creation or modification' => 'Feladat létrehozása vagy módosítása', - 'Category' => 'Kategória', - 'Category:' => 'Kategória:', - 'Categories' => 'Kategóriák', - 'Your category have been created successfully.' => 'Kategória sikeresen létrehozva.', - 'Unable to create your category.' => 'A kategória létrehozása nem lehetséges.', - 'Your category have been updated successfully.' => 'Kategória sikeresen frissítve.', - 'Unable to update your category.' => 'Kategória frissítése nem lehetséges.', - 'Remove a category' => 'Kategória törlése', - 'Category removed successfully.' => 'Kategória törlése megtörtént.', - 'Unable to remove this category.' => 'A kategória törlése nem lehetséges.', - 'Category modification for the project "%s"' => 'Kategória módosítása a projektben "%s"', - 'Category Name' => 'Kategória neve', - 'Add a new category' => 'Új kategória', - 'Do you really want to remove this category: "%s"?' => 'Valóban törölni akarja ezt a kategóriát: "%s"?', - 'All categories' => 'Minden kategória', - 'No category' => 'Nincs kategória', - 'The name is required' => 'A név megadása kötelező', - 'Remove a file' => 'Fájl törlése', - 'Unable to remove this file.' => 'Fájl törlése nem lehetséges.', - 'File removed successfully.' => 'Fájl sikeresen törölve.', - 'Attach a document' => 'Fájl csatolása', - 'Do you really want to remove this file: "%s"?' => 'Valóban törölni akarja ezt a fájlt: "%s"?', - 'Attachments' => 'Mellékletek', - 'Edit the task' => 'Feladat módosítása', - 'Add a comment' => 'Új megjegyzés', - 'Edit a comment' => 'Megjegyzés szerkesztése', - 'Summary' => 'Összegzés', - 'Time tracking' => 'Idő követés', - 'Estimate:' => 'Becsült:', - 'Spent:' => 'Eltöltött:', - 'Do you really want to remove this sub-task?' => 'Valóban törölni akarja ezt a részfeladatot?', - 'Remaining:' => 'Hátralévő:', - 'hours' => 'óra', - 'spent' => 'eltöltött', - 'estimated' => 'becsült', - 'Sub-Tasks' => 'Részfeladatok', - 'Add a sub-task' => 'Részfeladat létrehozása', - 'Original estimate' => 'Eredeti időbecslés', - 'Create another sub-task' => 'További részfeladat létrehozása', - 'Time spent' => 'Eltöltött idő', - 'Edit a sub-task' => 'Részfeladat szerkesztése', - 'Remove a sub-task' => 'Részfeladat törlése', - 'The time must be a numeric value' => 'Idő csak számérték lehet', - 'Todo' => 'Teendő', - 'In progress' => 'Folyamatban', - 'Sub-task removed successfully.' => 'Részfeladat sikeresen törölve.', - 'Unable to remove this sub-task.' => 'Részfeladat törlése nem lehetséges.', - 'Sub-task updated successfully.' => 'Részfeladat sikeresen frissítve.', - 'Unable to update your sub-task.' => 'Részfeladat frissítése nem lehetséges.', - 'Unable to create your sub-task.' => 'Részfeladat létrehozása nem lehetséges.', - 'Sub-task added successfully.' => 'Részfeladat sikeresen létrehozva.', - 'Maximum size: ' => 'Maximális méret: ', - 'Unable to upload the file.' => 'Fájl feltöltése nem lehetséges.', - 'Display another project' => 'Másik projekt megjelenítése', - 'Created by %s' => 'Készítette: %s', - 'Tasks Export' => 'Feladatok exportálása', - 'Tasks exportation for "%s"' => 'Feladatok exportálása: "%s"', - 'Start Date' => 'Kezdés dátuma', - 'End Date' => 'Befejezés dátuma', - 'Execute' => 'Végrehajt', - 'Task Id' => 'Feladat ID', - 'Creator' => 'Készítette', - 'Modification date' => 'Módosítás dátuma', - 'Completion date' => 'Befejezés határideje', - 'Clone' => 'Másolat', - 'Project cloned successfully.' => 'A projekt sikeresen másolva.', - 'Unable to clone this project.' => 'A projekt másolása sikertelen.', - 'Enable email notifications' => 'E-mail értesítések engedélyezése', - 'Task position:' => 'Feladat helye:', - 'The task #%d have been opened.' => 'Feladat #%d megnyitva.', - 'The task #%d have been closed.' => 'Feladat #%d lezárva.', - 'Sub-task updated' => 'Részfeladat frissítve', - 'Title:' => 'Cím', - 'Status:' => 'Állapot:', - 'Assignee:' => 'Felelős:', - 'Time tracking:' => 'Idő követés:', - 'New sub-task' => 'Új részfeladat', - 'New attachment added "%s"' => 'Új melléklet "%s" hozzáadva.', - 'New comment posted by %s' => 'Új megjegyzés %s', - 'New attachment' => 'Új melléklet', - 'New comment' => 'Új megjegyzés', - 'Comment updated' => 'Megjegyzés frissítve', - 'New subtask' => 'Új részfeladat', - 'Subtask updated' => 'Részfeladat frissítve', - 'Task updated' => 'Feladat frissítve', - 'Task closed' => 'Feladat lezárva', - 'Task opened' => 'Feladat megnyitva', - 'I want to receive notifications only for those projects:' => 'Csak ezekről a projektekről kérek értesítést:', - 'view the task on Kanboard' => 'feladat megtekintése a Kanboardon', - 'Public access' => 'Nyilvános hozzáférés', - 'Active tasks' => 'Aktív feladatok', - 'Disable public access' => 'Nyilvános hozzáférés letiltása', - 'Enable public access' => 'Nyilvános hozzáférés engedélyezése', - 'Public access disabled' => 'Nyilvános hozzáférés letiltva', - 'Do you really want to disable this project: "%s"?' => 'Tényleg szeretné letiltani ezt a projektet: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Tényleg szeretné engedélyezni ezt a projektet: "%s"?', - 'Project activation' => 'Projekt aktiválás', - 'Move the task to another project' => 'Feladat áthelyezése másik projektbe', - 'Move to another project' => 'Áthelyezés másik projektbe', - 'Do you really want to duplicate this task?' => 'Tényleg szeretné megkettőzni ezt a feladatot?', - 'Duplicate a task' => 'Feladat másolása', - 'External accounts' => 'Külső fiókok', - 'Account type' => 'Fiók típusa', - 'Local' => 'Helyi', - 'Remote' => 'Távoli', - 'Enabled' => 'Engedélyezve', - 'Disabled' => 'Letiltva', - 'Username:' => 'Felhasználónév:', - 'Name:' => 'Név:', - 'Email:' => 'E-mail:', - 'Notifications:' => 'Értesítések:', - 'Notifications' => 'Értesítések', - 'Account type:' => 'Fiók típusa:', - 'Edit profile' => 'Profil szerkesztése', - 'Change password' => 'Jelszó módosítása', - 'Password modification' => 'Jelszó módosítása', - 'External authentications' => 'Külső azonosítás', - 'Never connected.' => 'Sosem csatlakozva.', - 'No external authentication enabled.' => 'A külső azonosítás nincs engedélyezve.', - 'Password modified successfully.' => 'A jelszó sikeresen módosítva.', - 'Unable to change the password.' => 'A jelszó módosítása sikertelen.', - 'Change category' => 'Kategória módosítása', - '%s updated the task %s' => '%s frissítette a feladatot %s', - '%s opened the task %s' => '%s megnyitott a feladatot %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s átmozgatta a feladatot %s #%d pozícióba a "%s" oszlopban', - '%s moved the task %s to the column "%s"' => '%s átmozgatta a feladatot %s "%s" oszlopba', - '%s created the task %s' => '%s létrehozta a feladatot %s', - '%s closed the task %s' => '%s lezárta a feladatot %s', - '%s created a subtask for the task %s' => '%s létrehozott egy részfeladat a feladathoz %s', - '%s updated a subtask for the task %s' => '%s frissített egy részfeladatot a feladathoz %s', - 'Assigned to %s with an estimate of %s/%sh' => '%s-nek kiosztva %s/%s óra becsült idő mellett', - 'Not assigned, estimate of %sh' => 'Nincs kiosztva, becsült idő: %s óra', - '%s updated a comment on the task %s' => '%s frissítette a megjegyzését a feladatban %s', - '%s commented the task %s' => '%s megjegyzést fűzött a feladathoz %s', - '%s\'s activity' => 'Tevékenységek: %s', - 'RSS feed' => 'RSS feed', - '%s updated a comment on the task #%d' => '%s frissített egy megjegyzést a feladatban #%d', - '%s commented on the task #%d' => '%s megjegyzést tett a feladathoz #%d', - '%s updated a subtask for the task #%d' => '%s frissített egy részfeladatot a feladatban #%d', - '%s created a subtask for the task #%d' => '%s létrehozott egy részfeladatot a feladatban #%d', - '%s updated the task #%d' => '%s frissítette a feladatot #%d', - '%s created the task #%d' => '%s létrehozta a feladatot #%d', - '%s closed the task #%d' => '%s lezárta a feladatot #%d', - '%s open the task #%d' => '%s megnyitotta a feladatot #%d', - '%s moved the task #%d to the column "%s"' => '%s átmozgatta a feladatot #%d a "%s" oszlopba', - '%s moved the task #%d to the position %d in the column "%s"' => '%s átmozgatta a feladatot #%d a %d pozícióba a "%s" oszlopban', - 'Activity' => 'Tevékenységek', - 'Default values are "%s"' => 'Az alapértelmezett értékek: %s', - 'Default columns for new projects (Comma-separated)' => 'Alapértelmezett oszlopok az új projektekben (vesszővel elválasztva)', - 'Task assignee change' => 'Felelős módosítása', - '%s change the assignee of the task #%d to %s' => '%s a felelőst módosította #%d %s', - '%s changed the assignee of the task %s to %s' => '%s a felelőst %s módosította: %s', - 'New password for the user "%s"' => 'Felhasználó új jelszava: %s', - 'Choose an event' => 'Válasszon eseményt', - 'Create a task from an external provider' => 'Feladat létrehozása külsős számára', - 'Change the assignee based on an external username' => 'Felelős módosítása külső felhasználónév alapján', - 'Change the category based on an external label' => 'Kategória módosítása külső címke alapján', - 'Reference' => 'Hivatkozás', - 'Label' => 'Címke', - 'Database' => 'Adatbázis', - 'About' => 'Kanboard információ', - 'Database driver:' => 'Adatbázis motor:', - 'Board settings' => 'Tábla beállítások', - 'Webhook settings' => 'Webhook beállítások', - 'Reset token' => 'Token újragenerálása', - 'API endpoint:' => 'API végpont:', - 'Refresh interval for private board' => 'Privát táblák frissítési intervalluma', - 'Refresh interval for public board' => 'Nyilvános táblák frissítési intervalluma', - 'Task highlight period' => 'Feladat kiemelés időtartama', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Mennyi ideig tekintendő egy feladat "mostanában" módosítottnak (másodpercben) (0: funkció letiltva, alapértelmezés szerint 2 nap)', - 'Frequency in second (60 seconds by default)' => 'Gyakoriság másodpercben (alapértelmezetten 60 másodperc)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Gyakoriság másodpercben (0 funkció letiltva, alapértelmezetten 10 másodperc)', - 'Application URL' => 'Alkalmazás URL', - 'Token regenerated.' => 'Token újragenerálva.', - 'Date format' => 'Dátum formátum', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formátum mindig elfogadott, pl: "%s" és "%s"', - 'New private project' => 'Új privát projekt', - 'This project is private' => 'Ez egy privát projekt', - 'Add' => 'Hozzáadás', - 'Start date' => 'Kezdés dátuma', - 'Time estimated' => 'Becsült időtartam', - 'There is nothing assigned to you.' => 'Nincs kiosztott feladat.', - 'My tasks' => 'Feladataim', - 'Activity stream' => 'Legutóbbi tevékenységek', - 'Dashboard' => 'Vezérlőpult', - 'Confirmation' => 'Megerősítés', - 'Allow everybody to access to this project' => 'A projekt elérése mindenkinek engedélyezett', - 'Everybody have access to this project.' => 'Mindenki elérheti a projektet', - 'Webhooks' => 'Webhook', - 'API' => 'API', - 'Create a comment from an external provider' => 'Megjegyzés létrehozása külső felhasználótól', - 'Project management' => 'Projekt menedzsment', - 'My projects' => 'Projektjeim', - 'Columns' => 'Oszlopok', - 'Task' => 'Feladat', - 'Your are not member of any project.' => 'Ön nem tagja projektnek.', - 'Percentage' => 'Százalék', - 'Number of tasks' => 'A feladatok száma', - 'Task distribution' => 'Feladatelosztás', - 'Reportings' => 'Jelentések', - 'Task repartition for "%s"' => 'Feladat újraosztása: %s', - 'Analytics' => 'Analitika', - 'Subtask' => 'Részfeladat', - 'My subtasks' => 'Részfeladataim', - 'User repartition' => 'Felhasználó újrafelosztás', - 'User repartition for "%s"' => 'Felhasználó újrafelosztás: %s', - 'Clone this project' => 'Projekt másolása', - 'Column removed successfully.' => 'Oszlop sikeresen törölve.', - 'Not enough data to show the graph.' => 'Nincs elég adat a grafikonhoz.', - 'Previous' => 'Előző', - 'The id must be an integer' => 'Az ID csak egész szám lehet', - 'The project id must be an integer' => 'A projekt ID csak egész szám lehet', - 'The status must be an integer' => 'Az állapot csak egész szám lehet', - 'The subtask id is required' => 'A részfeladat ID-t meg kell adni', - 'The subtask id must be an integer' => 'A részfeladat ID csak egész szám lehet', - 'The task id is required' => 'A feladat ID-t meg kell adni', - 'The task id must be an integer' => 'A feladat ID csak egész szám lehet', - 'The user id must be an integer' => 'A felhasználói ID csak egész szám lehet', - 'This value is required' => 'Ez a mező kötelező', - 'This value must be numeric' => 'Ez a mező csak szám lehet', - 'Unable to create this task.' => 'A feladat nem hozható létre,', - 'Cumulative flow diagram' => 'Kumulatív folyamatábra', - 'Cumulative flow diagram for "%s"' => 'Kumulatív folyamatábra: %s', - 'Daily project summary' => 'Napi projektösszefoglaló', - 'Daily project summary export' => 'Napi projektösszefoglaló exportálása', - 'Daily project summary export for "%s"' => 'Napi projektösszefoglaló exportálása: %s', - 'Exports' => 'Exportálások', - 'This export contains the number of tasks per column grouped per day.' => 'Ez az export tartalmazza a feladatok számát oszloponként összesítve, napokra lebontva.', - 'Active swimlanes' => 'Aktív sávok', - 'Add a new swimlane' => 'Új sáv', - 'Change default swimlane' => 'Alapértelmezett sáv megváltoztatása', - 'Default swimlane' => 'Alapértelmezett folyamat', - 'Do you really want to remove this swimlane: "%s"?' => 'Valóban törölni akarja ezt a sávot: %s ?', - 'Inactive swimlanes' => 'Inaktív sávok', - 'Remove a swimlane' => 'Sáv törlés', - 'Show default swimlane' => 'Alapértelmezett sáv megjelenítése', - 'Swimlane modification for the project "%s"' => '%s projekt sávjainak módosítása', - 'Swimlane removed successfully.' => 'Sáv sikeresen törölve.', - 'Swimlanes' => 'Sávok', - 'Swimlane updated successfully.' => 'Sáv sikeresen frissítve', - 'The default swimlane have been updated successfully.' => 'Az alapértelmezett sáv sikeresen frissítve.', - 'Unable to remove this swimlane.' => 'A sáv törlése sikertelen.', - 'Unable to update this swimlane.' => 'A sáv frissítése sikertelen.', - 'Your swimlane have been created successfully.' => 'A sáv sikeresen létrehozva.', - 'Example: "Bug, Feature Request, Improvement"' => 'Például: Hiba, Új funkció, Fejlesztés', - 'Default categories for new projects (Comma-separated)' => 'Alapértelmezett kategóriák az új projektekben (Vesszővel elválasztva)', - 'Integrations' => 'Integráció', - 'Integration with third-party services' => 'Integráció harmadik féllel', - 'Subtask Id' => 'Részfeladat id', - 'Subtasks' => 'Részfeladatok', - 'Subtasks Export' => 'Részfeladat exportálás', - 'Subtasks exportation for "%s"' => 'Részfeladatok exportálása: %s', - 'Task Title' => 'Feladat címe', - 'Untitled' => 'Névtelen', - 'Application default' => 'Alkalmazás alapértelmezett', - 'Language:' => 'Nyelv:', - 'Timezone:' => 'Időzóna:', - 'All columns' => 'Minden oszlop', - 'Calendar' => 'Naptár', - 'Next' => 'Következő', - '#%d' => '#%d', - 'All swimlanes' => 'Minden sáv', - 'All colors' => 'Minden szín', - 'Moved to column %s' => '%s oszlopba áthelyezve', - 'User dashboard' => 'Felhasználói vezérlőpult', - 'Allow only one subtask in progress at the same time for a user' => 'Egyszerre csak egy folyamatban levő részfeladat engedélyezése a felhasználóknak', - 'Edit column "%s"' => 'Oszlop szerkesztés: %s', - 'Select the new status of the subtask: "%s"' => 'Részfeladat állapot változtatás: %s', - 'Subtask timesheet' => 'Részfeladat idővonal', - 'There is nothing to show.' => 'Nincs megjelenítendő adat.', - 'Time Tracking' => 'Idő követés', - 'You already have one subtask in progress' => 'Már van egy folyamatban levő részfeladata', - 'Which parts of the project do you want to duplicate?' => 'A projekt mely részeit szeretné másolni?', - 'Disallow login form' => 'A login ablak letiltása', - 'Start' => 'Kezdet', - 'End' => 'Vég', - 'Task age in days' => 'Feladat életkora napokban', - 'Days in this column' => 'Napok ebben az oszlopban', - '%dd' => '%dd', - 'Add a new link' => 'Új hivatkozás hozzáadása', - 'Do you really want to remove this link: "%s"?' => 'Biztos törölni akarja a hivatkozást: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Biztos törölni akarja a(z) #%d. feladatra mutató hivatkozást?', - 'Field required' => 'Kötelező mező', - 'Link added successfully.' => 'Hivatkozás sikeresen létrehozva.', - 'Link updated successfully.' => 'Hivatkozás sikeresen frissítve.', - 'Link removed successfully.' => 'Hivatkozás sikeresen törölve.', - '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.', - 'Unable to create your link.' => 'Hivatkozás létrehozása sikertelen.', - 'Unable to update your link.' => 'Hivatkozás frissítése sikertelen.', - 'Unable to remove this link.' => 'Hivatkozás törlése sikertelen.', - 'relates to' => 'hozzá tartozik:', - 'blocks' => 'letiltva:', - 'is blocked by' => 'letitoltta:', - 'duplicates' => 'eredeti:', - 'is duplicated by' => 'másolat:', - 'is a child of' => 'szülője:', - 'is a parent of' => 'gyermeke:', - 'targets milestone' => 'megcélzott mérföldkő:', - 'is a milestone of' => 'ehhez a mérföldkőhöz tartozik:', - 'fixes' => 'javítás:', - 'is fixed by' => 'javította:', - 'This task' => 'Ez a feladat', - '<1h' => '<1ó', - '%dh' => '%dó', - 'Expand tasks' => 'Feladatok lenyitása', - 'Collapse tasks' => 'Feladatok összecsukása', - 'Expand/collapse tasks' => 'Feladatok lenyitása/összecsukása', - 'Close dialog box' => 'Ablak bezárása', - 'Submit a form' => 'Űrlap beküldése', - 'Board view' => 'Tábla nézet', - 'Keyboard shortcuts' => 'Billentyű kombinációk', - 'Open board switcher' => 'Tábla választó lenyitása', - 'Application' => 'Alkalmazás', - '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', - 'CAD - Canadian Dollar' => 'CAD - Kanadai dollár', - 'CHF - Swiss Francs' => 'CHF - Svájci frank', - 'Custom Stylesheet' => 'Egyéni stíluslap', - 'download' => 'letöltés', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Angol font', - 'INR - Indian Rupee' => 'INR - Indiai rúpia', - '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', - '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', - 'Move the task to another column when assignee is cleared' => 'Feladat másik oszlopba helyezése felhasználóhoz rendélés törlésekor', - 'Source column' => 'Forrás oszlop', - 'Transitions' => 'Állapot-átmenetek', - 'Executer' => 'Végrehajtó', - 'Time spent in the column' => 'Az oszlopban töltött idő', - 'Task transitions' => 'Feladat állapot-átmenetek', - 'Task transitions export' => 'Feladat állapot-átmenetek exportálása', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Ez a riport az összes feladatra vonatkozóan tartalmazza az oszlop mozgatásokat. Szerepel benne a dátum, a felhasználó neve, és az egyes állapot-átemenetekkel eltöltött idő.', - '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', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s eltávolította a %s feladathoz rendelt személyt', - 'Enable Gravatar images' => 'Gravatár képek engedélyezése', - 'Information' => 'Információ', - 'Check two factor authentication code' => 'Két fázisú beléptető kód ellenőrzése', - 'The two factor authentication code is not valid.' => 'A két fázisú beléptető kód érvénytelen', - 'The two factor authentication code is valid.' => 'A két fázisú beléptető kód érvényes', - 'Code' => 'Kód', - 'Two factor authentication' => 'Két fázisú beléptetés', - 'This QR code contains the key URI: ' => 'Ez a QR kód a következő kulcs URI-t tartalmazza: ', - 'Check my code' => 'A kódom ellenőrzése', - 'Secret key: ' => 'Titkos kulcs', - 'Test your device' => 'Az eszköz ellenőrzése', - 'Assign a color when the task is moved to a specific column' => 'Szín hozzárendelése, ha a feladatot egy adott oszlopba mozgatták', - '%s via Kanboard' => '%s a Kanboard-on keresztül', - // 'Burndown chart for "%s"' => '', - // 'Burndown chart' => '', - 'This chart show the task complexity over the time (Work Remaining).' => 'Ez a diagram a feladat időbeli bonyolultságát ábrázolja (mennyi munka van hátra)', - 'Screenshot taken %s' => 'A képernyőmentés megtörtént, %s', - 'Add a screenshot' => 'Képernyőmentés hozzáadása', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Végezzen képernyőmentést, majd a CTRL+V vagy ⌘+V megnyomásával másolja be ide.', - 'Screenshot uploaded successfully.' => 'A képernyőmentés feltöltése sikeresen megtörtént.', - 'SEK - Swedish Krona' => 'SEK - Svéd korona', - 'Identifier' => 'Azonosító', - 'Disable two factor authentication' => 'A kétfázisú beléptetés letiltása', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Valóban le akarja tiltani a kétfázisú beléptetést ennél a felhasználónál: "%s"?', - 'Edit link' => 'Hivatkozás szerkesztése', - 'Start to type task title...' => 'Kezdje el begépelni a feladat címét... ', - 'A task cannot be linked to itself' => 'Egy feladatot nem lehet önmagához kapcsolni', - 'The exact same link already exists' => 'Már létezik pontosan ugyanez a hivatkozás', - 'Recurrent task is scheduled to be generated' => 'Az ismétlődő feladat előállítása ütemezve lett', - 'Score' => 'Pontszám', - 'The identifier must be unique' => 'Egyedi azonosító szükséges', - 'This linked task id doesn\'t exists' => 'Ez a hivatkozott feladat nem létezik', - 'This value must be alphanumeric' => 'Alfanumerikus érték szükséges', - 'Edit recurrence' => 'Ismétlődés szerkesztése', - 'Generate recurrent task' => 'Ismétlődő feladat előállítása', - 'Trigger to generate recurrent task' => 'Az ismétlődő feladatot előállító trigger', - 'Factor to calculate new due date' => 'Az új határidő kiszámításához használt tényező', - 'Timeframe to calculate new due date' => 'Az új határidő kiszámításához használt időablak', - 'Base date to calculate new due date' => 'A határidő kiszámításához használt kezdő dátum', - 'Action date' => 'Intézkedés dátuma', - 'Base date to calculate new due date: ' => 'Az új határidő kiszámításához használt kezdő dátum: ', - 'This task has created this child task: ' => 'Ez a feladat a következő leszármazott feladatot hozta létre: ', - 'Day(s)' => 'Nap(ok)', - 'Existing due date' => 'A jelenlegi határidő', - 'Factor to calculate new due date: ' => 'Az új határidő kiszámításához használt tényező: ', - 'Month(s)' => 'Hónap(ok)', - 'Recurrence' => 'Ismétlődés', - 'This task has been created by: ' => 'Ezt a feladatot a következő személy hozta létre: ', - 'Recurrent task has been generated:' => 'Ismétlődő feladat lett létrehozva: ', - 'Timeframe to calculate new due date: ' => 'Az új határidő kiszámításához használt időablak: ', - 'Trigger to generate recurrent task: ' => 'Az ismétlődő feladatot előállító trigger: ', - 'When task is closed' => 'Mikor a feladat be lett zárva', - 'When task is moved from first column' => 'Mikor a feladat az első oszlopból el lett mozgatva', - 'When task is moved to last column' => 'Mikor a feladat az utolsó oszlopba lett elmozgatva', - 'Year(s)' => 'Év(ek)', - 'Calendar settings' => 'Naptár beállítások', - 'Project calendar view' => 'A projekt megjelenítése naptári formában', - 'Project settings' => 'Projekt beállítások', - 'Show subtasks based on the time tracking' => 'A részfeladatok megjelenítése az idő nyomkövetés alapján', - 'Show tasks based on the creation date' => 'A feladatok megjelenítése a létrehozás dátuma alapján', - 'Show tasks based on the start date' => 'A feladatok megjelenítése a kezdő dátum alapján', - 'Subtasks time tracking' => 'A részfeladatok idejének megjelenítése', - 'User calendar view' => 'A felhasználó naptárának megjelenítése', - 'Automatically update the start date' => 'A kezdő dátum automatikus módosítása', - // 'iCal feed' => '', - 'Preferences' => 'Preferenciák', - 'Security' => 'Biztonság', - 'Two factor authentication disabled' => 'A két fázisú beléptetés tiltva van', - 'Two factor authentication enabled' => 'A két fázisú beléptetés engedélyezve van', - 'Unable to update this user.' => 'A felhasználó {adatainak} módosítása nem sikerült.', - 'There is no user management for private projects.' => 'A privát projektek esetén nincs felhasználó kezelés', - 'User that will receive the email' => 'Az email-t a következő felhaszáló fogja megkapni', - 'Email subject' => 'Email tárgy', - 'Date' => 'Dátum', - 'Add a comment log when moving the task between columns' => 'Egy napló megjegyzés létrehozása a feladat oszlopok közötti mozgatásakor', - 'Move the task to another column when the category is changed' => 'A feladat átmozgatása egy másik oszlopba, ha megváltozik a kategória', - 'Send a task by email to someone' => 'Email-en egy feladat küldése valakinek', - 'Reopen a task' => 'Egy feladat újbóli megnyitása', - 'Column change' => 'Oszlop módosítás', - 'Position change' => 'Helyzet módosítás', - 'Swimlane change' => 'Sáv módosítás', - 'Assignee change' => 'Felelős módosítása', - '[%s] Overdue tasks' => '[%s] késésben lévő feladat', - 'Notification' => 'Értesítés', - '%s moved the task #%d to the first swimlane' => '%s a #%d feladatot az első sávba mozgatta', - '%s moved the task #%d to the swimlane "%s"' => '%s a #%d feladatot a "%s" sávba mozgatta', - 'Swimlane' => 'Sáv', - 'Gravatar' => 'Gravatár', - '%s moved the task %s to the first swimlane' => '%s a %s feladatot az első sávba mozgatta', - '%s moved the task %s to the swimlane "%s"' => '%s a %s feladatot a "%s" sávba mozgatta', - 'This report contains all subtasks information for the given date range.' => 'Ez a riport az adott dátumtartományra vonatkozón az összes részfeladatot tartalmazza', - 'This report contains all tasks information for the given date range.' => 'Ez a riport az adott dátumtartományra vonatkozóan az összes feladatot tartalmazza', - 'Project activities for %s' => '%s projekt tevékenységei', - 'view the board on Kanboard' => 'a tábla megjelenítése a Kanboard-on', - 'The task have been moved to the first swimlane' => 'A feladat ez első sávba lett elmozgatva', - 'The task have been moved to another swimlane:' => 'A feladat egy másik sávba lett elmozgatva', - 'New title: %s' => 'Új cím: %s', - 'The task is not assigned anymore' => 'A feladatnak már nincs felelőse', - 'New assignee: %s' => 'Az új felelős: %s', - 'There is no category now' => 'Jelenleg nincs kategória', - 'New category: %s' => 'Az új kategória: %s', - 'New color: %s' => 'Az új szín: %s', - 'New complexity: %d' => 'Az új bonyolultság: %d', - 'The due date have been removed' => 'A határidő törölve lett', - 'There is no description anymore' => 'Többé már nincs leírás', - 'Recurrence settings have been modified' => 'Az ismétlődés beállításai módosultak', - 'Time spent changed: %sh' => 'Módosult a ráfordított idő: %s óra', - 'Time estimated changed: %sh' => 'Módosult az időbecslés: %s óra', - 'The field "%s" have been updated' => 'A "%s" mező módosítva lett', - 'The description has been modified:' => 'A leírás módosítva lett:', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Valóban be akarja zárni a "%s" feladatot, valamint a hozzá tartozó részfeladatokat?', - 'I want to receive notifications for:' => 'Értesítéseket szeretnék kapni a következőkről:', - 'All tasks' => 'Az összes feladat', - 'Only for tasks assigned to me' => 'Csak a hozzám rendelt feladatok', - 'Only for tasks created by me' => 'Csak az általam létrehozott feladatok', - 'Only for tasks created by me and assigned to me' => 'Csak az általam lérehozott és a hozzám rendelt feladatok', - '%%Y-%%m-%%d' => '%%Y-%%m-%%d', - 'Total for all columns' => 'Az összes oszlop összege', - 'You need at least 2 days of data to show the chart.' => 'Legalább 2 nap adatára van szükség az ábra megjelenítéséshez', - '<15m' => '15p', - '<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', - 'Reset filters' => 'Szűrő alaphelyzetbe állítás', - 'My tasks due tomorrow' => 'Holnapi határidejű feladataim', - 'Tasks due today' => 'Mai határidejű feladatok', - 'Tasks due tomorrow' => 'Holnapi határidejű feladatok', - 'Tasks due yesterday' => 'Tegnapi határidejű feladatok', - 'Closed tasks' => 'Lezárt feladatok', - 'Open tasks' => 'Nyitott feladatok', - 'Not assigned' => 'Nincs felelős', - 'View advanced search syntax' => 'Részletes keresés megjelenítése', - 'Overview' => 'Áttekintés', - 'Board/Calendar/List view' => 'Tábla/Naptár/Lista nézet', - 'Switch to the board view' => 'Átkapcsolás tábla nézetbe', - 'Switch to the calendar view' => 'Átkapcsolás naptár nézetbe', - 'Switch to the list view' => 'Átkapcsolás lista nézetbe', - 'Go to the search/filter box' => 'Ugrás a keresés/szűrés dobozhoz', - 'There is no activity yet.' => 'Még nincs tevékenység', - 'No tasks found.' => 'Nincs feladat.', - 'Keyboard shortcut: "%s"' => 'Billentyű parancsok: "%s"', - 'List' => 'Lista', - 'Filter' => 'Szűrő', - 'Advanced search' => 'Keresés haladóknak', - 'Example of query: ' => 'Lekérdezési példa: ', - 'Search by project: ' => 'Keresés projekt alapján: ', - 'Search by column: ' => 'Keresés oszlop alapján: ', - 'Search by assignee: ' => 'Keresés felelős alapján: ', - 'Search by color: ' => 'Keresés szín alapján: ', - 'Search by category: ' => 'Keresés kategória alapján: ', - 'Search by description: ' => 'Keresés leírás alapján: ', - 'Search by due date: ' => 'Keresés határidő alapján: ', - 'Lead and Cycle time for "%s"' => 'A "%s" átfutási ideje és ciklusideje', - 'Average time spent into each column for "%s"' => 'A "%s" során az egyes oszlopokban töltött átlagos idő', - 'Average time spent into each column' => 'Az egyes oszlopokban töltött átlagos idő', - 'Average time spent' => 'Az eltöltött átlagos idő', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Ez az ábra az utolsó %d feladatra vonatkozóan mutatja az egyes oszlopkban eltöltött átlagos időt.', - 'Average Lead and Cycle time' => 'Átlagos átfutási idő és ciklusidő', - 'Average lead time: ' => 'Átlagos átfutási idő: ', - 'Average cycle time: ' => 'Átlagos ciklusidő: ', - 'Cycle Time' => 'Ciklusidő', - 'Lead Time' => 'Átfutási idő', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Ez az ábra az utolsó %d feladatra vonatkozóan mutatja az átlagos átfutási időt és ciklusidőt az idő függvényében.', - 'Average time into each column' => 'Az egyes oszlopokban töltött átlagos idő', - 'Lead and cycle time' => 'Átfutási és ciklusidő', - 'Lead time: ' => 'Átfutási idő: ', - 'Cycle time: ' => 'Ciklusidő: ', - 'Time spent into each column' => 'Az egyes oszlopokban töltött idő', - 'The lead time is the duration between the task creation and the completion.' => 'Az átfutási idő a feladat létrehozása és befejezése között eltelt idő.', - 'The cycle time is the duration between the start date and the completion.' => 'A ciklusidő a feladat elkezdése és befejezése közötti eltelt idő.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Ha a feladat még nincs lezárva, akkor befejezés ideje helyett az aktuális idő lesz használva.', - 'Set automatically the start date' => 'A kezdési idő automatikus beállítása', - 'Edit Authentication' => 'A beléptetés szerkesztése', - '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.', - 'Trigger automatically subtask time tracking' => 'A részfeladatok időfelhasználas-követésének automatikus indítása', - 'Include closed tasks in the cumulative flow diagram' => 'A lezárt feladatok szerepeltetáse az összesített folyamatábrán', - 'Current swimlane: %s' => 'Aktuális sáv: %s', - 'Current column: %s' => 'Aktuális oszlop: %s', - 'Current category: %s' => 'Aktuális kategória: %s', - 'no category' => 'nincs kategória', - 'Current assignee: %s' => 'Aktuális felelős: %s', - 'not assigned' => 'nincs kijelölt felelős', - 'Author:' => 'Szerző:', - 'contributors' => 'bedolgozók', - 'License:' => 'Engedély:', - 'License' => 'Engedély', - 'Enter the text below' => 'Adja be a lenti szöveget', - 'Gantt chart for %s' => 'Gantt diagram a %s számára', - 'Sort by position' => 'Rendezés hely szerint', - 'Sort by date' => 'Rendezés idő szerint', - 'Add task' => 'Feladat hozzáadása', - 'Start date:' => 'Kezdés ideje: ', - 'Due date:' => 'Határidő: ', - 'There is no start date or due date for this task.' => 'Ehhez a feladathoz nem adtak meg kezdési időt vagy határidőt.', - 'Moving or resizing a task will change the start and due date of the task.' => 'A feladat elmozgatása vagy méretének megváltoztatása meg fogja változtatni a feladat kezdési idejét és határidejét.', - 'There is no task in your project.' => 'Az ön projektjében nincsenek feladatok.', - 'Gantt chart' => 'Gantt diagram', - 'People who are project managers' => 'Projekt vezetők', - 'People who are project members' => 'Projekt tagok', - 'NOK - Norwegian Krone' => 'NOK - Norvég korona', - 'Show this column' => 'Oszlop mutatása', - 'Hide this column' => 'Oszlop elrejtése', - 'open file' => 'fájl megnyitás', - 'End date' => 'Végdátum', - 'Users overview' => 'Felhasználók áttekintése', - 'Members' => 'Tagok', - 'Shared project' => 'Közös projekt', - 'Project managers' => 'Projektvezetők', - 'Gantt chart for all projects' => 'Gantt diagram az összes projektre vonatkozóan', - 'Projects list' => 'Projekt lista', - 'Gantt chart for this project' => 'Gantt diagram erre a projektre vonatkozóan', - 'Project board' => 'Projekt tábla', - 'End date:' => 'Befejezés dátuma: ', - 'There is no start date or end date for this project.' => 'Ennél a projektnél nem adták meg a kezdés és a befejezés dátumát.', - 'Projects Gantt chart' => 'A projektek Gantt diagramja', - 'Change task color when using a specific task link' => 'Az egyes specifikus feladat hivatkozások használatakor a feladat színének megváltoztatása', - 'Task link creation or modification' => 'Feladat hivatkozás létrehozása vagy módosítása', - 'Milestone' => 'Mérföldkő', - 'Documentation: %s' => 'Dokumentáció: %s', - 'Switch to the Gantt chart view' => 'Átkapcsolás a Gantt diagram nézetre', - 'Reset the search/filter box' => 'A keresés/szűrés doboz alaphelyzetbe állítása', - 'Documentation' => 'Dokumentáció', - 'Table of contents' => 'Tartalomjegyzék', - 'Gantt' => 'Gantt', - 'Author' => 'Szerző', - 'Version' => 'Verzió', - 'Plugins' => 'Plugin-ek', - 'There is no plugin loaded.' => 'Nincs betöltött plugin.', - 'Set maximum column height' => 'Max. oszlopmagasság beállítása', - 'Remove maximum column height' => 'Max. oszlopmagasság törlése', - 'My notifications' => 'Emlékeztetőim', - 'Custom filters' => 'Egyedi szűrők', - 'Your custom filter have been created successfully.' => 'Az ön egyedi szűrője sikeresen létrejött.', - 'Unable to create your custom filter.' => 'Nem sikerült létrehozni az ön egyedi szűrőjét.', - 'Custom filter removed successfully.' => 'Az egyedi szűrő sikeresen törölve lett.', - 'Unable to remove this custom filter.' => 'Nem sikerült egy egyedi szűrő törlése.', - 'Edit custom filter' => 'Egyedi szűrő szerkesztése', - 'Your custom filter have been updated successfully.' => 'Az ön egyedi szűrője sikeresen módosult.', - 'Unable to update custom filter.' => 'Nem sikerült az egyedi szűrő módosítása', - 'Web' => 'Web (háló)', - 'New attachment on task #%d: %s' => 'A #%d számú feladatnak új melléklete van: %s', - 'New comment on task #%d' => 'A #%d számú feladatnak új megjegyzése van', - 'Comment updated on task #%d' => 'A #%d szűmú feladathoz tartozó megjegyzés módosult', - 'New subtask on task #%d' => 'A #%d számú feladatnak új részfeladata van', - 'Subtask updated on task #%d' => 'A #%d számú feladat részfeladata módosult', - 'New task #%d: %s' => 'Új #%d számú feladat: %s', - 'Task updated #%d' => 'A #%d számú feladat módosult', - 'Task #%d closed' => 'A #%d számú feladat le lett zárva', - 'Task #%d opened' => 'A #%d számú feladat meg lett nyitva', - 'Column changed for task #%d' => 'A #%d számú feladat oszlopa módosult', - 'New position for task #%d' => 'A #%d számú feladat új helyre került', - 'Swimlane changed for task #%d' => 'A #%d számú feladat új sávba került', - 'Assignee changed on task #%d' => 'A #%d számú feladat felelőse megváltozott', - '%d overdue tasks' => '%d db feladatnál van határidő túllépés', - 'Task #%d is overdue' => 'A #%d számú feladat határideje lejárt', - 'No new notifications.' => 'Nincs új emlékeztető.', - 'Mark all as read' => 'Az összes megjelölése olvasottként', - 'Mark as read' => 'Megjelölés olvasottként', - 'Total number of tasks in this column across all swimlanes' => 'Az ebben az oszlopban, az összes sávban lévő feladatok száma', - 'Collapse swimlane' => 'Sáv összecsukása', - 'Expand swimlane' => 'Sáv lenyitása', - 'Add a new filter' => 'Új szűrő hozzáadása', - 'Share with all project members' => 'Megosztás minden projekt taggal', - 'Shared' => 'Megosztva', - '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!', - 'Import users from CSV file' => 'Felhasználók importálása CSV fájlból', - '%d user(s) have been imported successfully.' => '%d felhasználó sikeresen importálva.', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - '%s attached a file to the task #%d' => '%s hozzákapcsolt a #%d feladathoz egy fájlt', - 'There is no column or swimlane activated in your project!' => 'Az ön projektjében nincs aktív oszlop vagy sáv!', - 'Append filter (instead of replacement)' => 'Szűrő hozzáfűzése (a helyettesítés helyett)', - 'Append/Replace' => 'Hozzáfűzés/Helyettesítés', - 'Append' => 'Hozzáfűz', - 'Replace' => 'Helyettesít', - 'Import' => 'Importál', - 'change sorting' => 'rendezési sorrend megváltoztatása', - 'Tasks Importation' => 'Feladat importálás', - // 'Delimiter' => '', - // 'Enclosure' => '', - 'CSV File' => 'CSV fájl', - 'Instructions' => 'Utasítások', - 'Your file must use the predefined CSV format' => 'A fájlnak az előre definiált CSV formátumot kell használnia', - 'Your file must be encoded in UTF-8' => 'A fájlnak UTF-8 karakterkódolást kell használnia', - 'The first row must be the header' => 'Az első sor kötelezően a fejléc', - 'Duplicates are not verified for you' => 'Az ismétlődések nincsenek ellenőrizve.', - 'The due date must use the ISO format: YYYY-MM-DD' => 'A határidőt ISO formátumban kell megadni: YYYY-MM-DD', - 'Download CSV template' => 'A CSV minta (template) letöltése', - 'No external integration registered.' => 'Nincs külső integráció regisztrálva.', - 'Duplicates are not imported' => 'Az ismétlődő értékek nem lesznek beimportálva', - 'Usernames must be lowercase and unique' => 'A felhasználói nevekre kötelező, hogy kisbetűsek és egyediek legyenek', - 'Passwords will be encrypted if present' => 'A jelszavak titkosítva lesznek', - '%s attached a new file to the task %s' => '%s a %s feladathoz egy új fájlt kapcsolt hozzá', - 'Link type' => 'Hivatkozás típus', - 'Assign automatically a category based on a link' => 'A hivatkozás alapján kategória automatikus hozzárendelése', - 'BAM - Konvertible Mark' => 'BAM - Konvertibilis márka', - 'Assignee Username' => 'A felelős felhasználói neve', - 'Assignee Name' => 'A felelős neve', - 'Groups' => 'Csoportok', - 'Members of %s' => 'A %s tagjai', - 'New group' => 'Új csoport', - 'Group created successfully.' => 'A csoport sikeresen létrejött.', - 'Unable to create your group.' => 'Nem sikerült a csoport létrehozása.', - 'Edit group' => 'Csoport szerkesztése', - 'Group updated successfully.' => 'A csoport módosítása sikeresen megtörtént', - 'Unable to update your group.' => 'Nem sikerült a csoport módosítása', - 'Add group member to "%s"' => 'Csoport tag hozzáadáasa "%s"-hez', - 'Group member added successfully.' => 'Tag hozzáadás sikeresen megtörtént', - 'Unable to add group member.' => 'Nem sikerült a tagot hozzáadni a csoporthoz.', - 'Remove user from group "%s"' => 'Felhasználó eltávolítása a "%s" csoportból', - 'User removed successfully from this group.' => 'A felhasználó sikeresen el lett távolítva a csoportból.', - 'Unable to remove this user from the group.' => 'Nem sikerült a felhasználó eltávolítása a csoportból', - 'Remove group' => 'Csoport törlése', - 'Group removed successfully.' => 'A csoport törlése sikeresen megtörtént.', - 'Unable to remove this group.' => 'Nem sikerült a csoport törlése.', - 'Project Permissions' => 'Projekt engedélyek', - 'Manager' => 'Vezető', - 'Project Manager' => 'Projekt vezető', - 'Project Member' => 'Projekt tag', - 'Project Viewer' => 'Projekt megtekintés', - 'Your account is locked for %d minutes' => 'Az ön számlája %d percre zárolva lett.', - 'Invalid captcha' => 'Érvénytelen captcha', - 'The name must be unique' => 'A névnek egyedinek kell lennie', - 'View all groups' => 'Az összes csoport megtekintése', - 'View group members' => 'A csoporttagok megtekintése', - 'There is no user available.' => 'Nincs ilyen felhasználó.', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Valóban el kívánja távolítani a "%s" felhasználót a "%s" csoportból?', - 'There is no group.' => 'Nincs ilyen csoport.', - 'External Id' => 'Külső azonosító', - 'Add group member' => 'Csoporttag hozzáadása', - 'Do you really want to remove this group: "%s"?' => 'Valóban törölni kívánja ezt a csoportot: "%s"?', - 'There is no user in this group.' => 'Nincs egy felhasználó sem ebben a csoportban.', - 'Remove this user' => 'A felhasználó eltávolítása', - 'Permissions' => 'Engedélyek', - 'Allowed Users' => 'Megengedett felhasználók', - 'No user have been allowed specifically.' => 'Egyedileg semelyik felhasználó sem lett engedélyezve.', - 'Role' => 'Szerepkör', - 'Enter user name...' => 'Adja be a felhasználó nevét...', - 'Allowed Groups' => 'Megengedett csoportok', - 'No group have been allowed specifically.' => 'Egyedileg semelyik csoport sem lett engedélyezve.', - 'Group' => 'Csoport', - 'Group Name' => 'Csoport név', - 'Enter group name...' => 'Adja meg a csoport nevét...', - 'Role:' => 'Szerepkör:', - 'Project members' => 'Projekt tagok', - 'Compare hours for "%s"' => 'Az órák összehasonlítása "%s" számára', - '%s mentioned you in the task #%d' => '%s megemlítette önt a #%d feladatban', - '%s mentioned you in a comment on the task #%d' => '%s megemlítette önt a #%d feladathoz fűzött megjegyzésben', - 'You were mentioned in the task #%d' => 'Ön meg lett említve a #%d feladatban', - 'You were mentioned in a comment on the task #%d' => 'Ön meg lett említve a #%d feladathoz fűzött megjegyzésben', - 'Mentioned' => 'Meg lett említve', - 'Compare Estimated Time vs Actual Time' => 'A becsült és a tényleges idő összehasonlítása', - 'Estimated hours: ' => 'Becsült órák: ', - 'Actual hours: ' => 'Tényleges órák: ', - 'Hours Spent' => 'Ráfordítás órákban', - 'Hours Estimated' => 'Becsült idő órákban', - 'Estimated Time' => 'Becsült idő', - 'Actual Time' => 'Tényleges idő', - 'Estimated vs actual time' => 'Becsült idő ill. tényleges idő', - 'RUB - Russian Ruble' => 'RUB - Orosz rubel', - 'Assign the task to the person who does the action when the column is changed' => 'A feladat hozzárendelése ahhoz a személyhez, aki az oszlop megváltoztatásakor intézkedik', - 'Close a task in a specific column' => 'A megadott oszlopban lévő feladat lezárása', - 'Time-based One-time Password Algorithm' => 'Idő alapú, egyszer használható jelszó algoritmus', - 'Two-Factor Provider: ' => 'Két tényezős bejelentkezés szolgáltatója', - 'Disable two-factor authentication' => 'Két tényezős bejelentkezés tiltása', - 'Enable two-factor authentication' => 'Két tényezős bejelentkezés engedélyezése', - 'There is no integration registered at the moment.' => 'Jelenleg nincs regisztrált integráció.', - 'Password Reset for Kanboard' => 'Jelszó alaphelyzetbe állítása', - 'Forgot password?' => 'Elfelejtett jelszó?', - 'Enable "Forget Password"' => '"Elfelejtett jelszó" engedélyezése', - 'Password Reset' => 'Jelszó alaphelyzetbe állíása', - 'New password' => 'Új jelszó', - 'Change Password' => 'Jelszó megváltoztatása', - 'To reset your password click on this link:' => 'A jelszó megváltoztatásáshoz kattintson erre a hivatkozásra', - 'Last Password Reset' => 'Jelszó alaphelyzetbe állítás utoljára ekkor', - 'The password has never been reinitialized.' => 'A jelszó soha sem lett alaphelyzetbe állítva.', - 'Creation' => 'Létrehozás', - 'Expiration' => 'Lejárat', - 'Password reset history' => 'A jelszó alaphelyzetbe állítás története', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'A "%s" oszlophoz és a "%s" sávhoz tartozó összes feladat sikeresen le lett zárva.', - 'Do you really want to close all tasks of this column?' => 'Valóban le kívánja zárni az oszlophoz tartozó összes feladatot?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d feladat lesz lezárva, ezek a "%s" oszlopban és a "%s" sávban vannak.', - 'Close all tasks of this column' => 'Az oszlophoz tartozó összes feladat lezárása', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Egy plugin sem regisztrált projekt értesítési módszert. Egyedi értesítések még mindig beállíthatók a felhasználói profilban.', - 'My dashboard' => 'Az én dashboard-om', - 'My profile' => 'Az én profilom', - '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', - 'Task priority' => 'Feladat prioritás', - 'General' => 'Általános', - 'Dates' => 'Dátumok', - 'Default priority' => 'Alap prioritás', - 'Lowest priority' => 'Legalacsonyabb prioritás', - 'Highest priority' => 'Legmagasabb prioritás', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Ha nullát ad meg a legalacsonyabb és legmagasabb prioritásként, akkor ez a jellemző letiltásra kerül.', - 'Close a task when there is no activity' => 'A feladat lezárása, ha nincs tevékenység', - 'Duration in days' => 'Hossz napokban', - 'Send email when there is no activity on a task' => 'email küldése, ha egy feladathoz nincs tevékenység', - 'Unable to fetch link information.' => 'A hivatkozás adatainak sikertelen beolvasása', - 'Daily background job for tasks' => 'A feladatokhoz tartozó napi háttér munkák', - 'Auto' => 'Automatikus', - 'Related' => 'Kapcsolódó', - 'Attachment' => 'Csatolmány', - 'Title not found' => 'Nincs ilyen cím', - 'Web Link' => 'Web hivatkozás', - 'External links' => 'Külső hivatkozások', - 'Add external link' => 'Külső hivatkozás hozzáadása', - 'Type' => 'Típus', - 'Dependency' => 'Függőség', - 'Add internal link' => 'Belső hivatkozás hozzáadása', - 'Add a new external link' => 'Új külső hivatkozás hozzáadása', - 'Edit external link' => 'Külső hivatkozás szerkesztése', - 'External link' => 'Külső hivatkozás', - 'Copy and paste your link here...' => 'Másold be a hivatkozást ide...', - 'URL' => 'URL', - 'Internal links' => 'Belső hivatkozások', - 'Assign to me' => 'Rendeld hozzám', - 'Me' => 'Hozzám', - 'Do not duplicate anything' => 'Semmit se duplázz meg', - 'Projects management' => 'Projekt kezelés', - 'Users management' => 'Felhasználók kezelése', - 'Groups management' => 'Csoportok kezelése', - 'Create from another project' => 'Létrehozás egy másik projektből', - 'open' => 'nyitva', - 'closed' => 'zárva', - 'Priority:' => 'Prioritás:', - 'Reference:' => 'Hivatkozás:', - 'Complexity:' => 'Komplexitás:', - 'Swimlane:' => 'Sáv:', - 'Column:' => 'Oszlop:', - 'Position:' => 'Pozíció:', - 'Creator:' => 'Létrehozó:', - 'Time estimated:' => 'Becsült idő:', - '%s hours' => '%s óra', - 'Time spent:' => 'Eltelt idő:', - 'Created:' => 'Létrehozva:', - 'Modified:' => 'Módosítva:', - 'Completed:' => 'Elkészült:', - '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: ', - 'New due date: ' => 'Új határidő: ', - 'Start date changed: ' => 'Kezdő dátum megváltozott: ', - 'Disable private projects' => 'Privát projektek tiltása', - 'Do you really want to remove this custom filter: "%s"?' => 'Valóban el kívánja távolítani ezt az egyedi szűrőt: "%s"?', - 'Remove a custom filter' => 'Egyedi szűrő eltávolítása', - 'User activated successfully.' => 'A felhasználó sikeresen aktiválva lett.', - 'Unable to enable this user.' => 'Nem sikerült a felhasználó engedélyezése.', - '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', - 'Two Factor' => 'Két tényezős', - 'Disable user' => 'Felhasználó tiltása', - 'Do you really want to disable this user: "%s"?' => 'Valóban le akarja tiltani ezt a felhasználót: "%s"?', - 'Enable user' => 'Felhasználó engedélyezése', - 'Do you really want to enable this user: "%s"?' => 'Valóban engedélyezni akarja ezt a felhasználót: "%s"?', - 'Download' => 'Letöltés', - 'Uploaded: %s' => 'Feltöltve: %s', - 'Size: %s' => 'méret %s', - 'Uploaded by %s' => 'Feltöltve %s által', - 'Filename' => 'Fájlnév', - 'Size' => 'Méret', - 'Column created successfully.' => 'Az oszlop sikeresen létrejött', - 'Another column with the same name exists in the project' => 'A projektben már létezik egy ugyanilyen nevű oszlop', - 'Default filters' => 'Alap szűrők', - 'Your board doesn\'t have any columns!' => 'A táblának nincsenek oszlopai!', - 'Change column position' => 'Oszlop helyzetének megváltoztatása', - 'Switch to the project overview' => 'Projektek áttekintése', - 'User filters' => 'Felhasználók szűrése', - 'Category filters' => 'Kategóriák szűrése', - 'Upload a file' => 'Fájl feltöltése', - 'View file' => 'Fájl megtekintése', - 'Last activity' => 'Utolsó aktivitás', - 'Change subtask position' => 'Részfeladat helyzetének megváltoztatása', - 'This value must be greater than %d' => 'Ennek az értéknek nagyobbnak kell lennie, mint %d', - 'Another swimlane with the same name exists in the project' => 'A projektben létezik egy ugyanilyen nevű másik sáv', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Példa: http://example.kanboard.net/ (ez abszolút URL-ek előállítására használható)', - 'Actions duplicated successfully.' => 'A tevékenység sikeresen meg lett duplázva.', - 'Unable to duplicate actions.' => 'A tevékenység megduplázása nem sikerült.', - 'Add a new action' => 'Új tevékenység létrehozása', - 'Import from another project' => 'Importálás egy másik projektből', - 'There is no action at the moment.' => 'Jelenleg nincs egy tevkenység sem.', - 'Import actions from another project' => 'Tevékenységek importálása egy másik projektből', - 'There is no available project.' => 'Nincs rendelkezésre álló projekt.', - 'Local File' => 'Helyi fájl', - 'Configuration' => 'Konfiguráció', - 'PHP version:' => 'PHP verzió:', - 'PHP SAPI:' => 'PHP SAPI:', - 'OS version:' => 'Operációs rendszer verzió:', - 'Database version:' => 'Adatbázis verzió:', - 'Browser:' => 'Böngésző:', - 'Task view' => 'Feladat nézet', - 'Edit task' => 'Feladat szerkesztése', - 'Edit description' => 'Leírás szerkesztése', - 'New internal link' => 'Új belső hivatkozás', - 'Display list of keyboard shortcuts' => 'Billentyű parancsok megjelenítése', - 'Menu' => 'Menü', - 'Set start date' => 'Kezdő időpont beállítása', - 'Avatar' => 'Avatár', - 'Upload my avatar image' => 'Kép feltöltése', - 'Remove my image' => 'Kép törése', - 'The OAuth2 state parameter is invalid' => 'Az OAuth2 állapot paraméter érvénytelen', - 'User not found.' => 'Nincs ilyen felhasználó.', - 'Search in activity stream' => 'Keresés a tevékenységek között', - 'My activities' => 'Tevékenységeim', - 'Activity until yesterday' => 'Tevékenységek tegnapig', - 'Activity until today' => 'Tevékenységek a mai napig', - 'Search by creator: ' => 'Keresés a létrehozó szerint: ', - 'Search by creation date: ' => 'Keresés a létrehozás ideje szerint: ', - 'Search by task status: ' => 'Keresés a feladat állapota szerint: ', - 'Search by task title: ' => 'Keresés a feladat címe szerint: ', - 'Activity stream search' => 'Tevékenységi láncban történő keresés', - 'Projects where "%s" is manager' => 'Azok a projektek, amelyekben "%s" vezető', - 'Projects where "%s" is member' => 'Azok a projektek, amelyekben "%s" tag', - 'Open tasks assigned to "%s"' => '"%s" -hez rendelt nyitott feladatok', - 'Closed tasks assigned to "%s"' => '"%s" -hez rendelt lezárt feladatok', - 'Assign automatically a color based on a priority' => 'A prioritás alapján szín automatikus hozzárendelése', - 'Overdue tasks for the project(s) "%s"' => 'A "%s" projekt(ek)hez tartozó, határidőt túllépő feladatok', - 'Upload files' => 'Fájlok feltöltése', - 'Installed Plugins' => 'Installált plugin-ek', - 'Plugin Directory' => 'Plugin könyvtár', - 'Plugin installed successfully.' => 'A plugin installálása sikerült.', - 'Plugin updated successfully.' => 'A plugin módosítása sikerült.', - 'Plugin removed successfully.' => 'A plugin törlése sikerült.', - 'Subtask converted to task successfully.' => 'Az alfeladat feladattá történő átalakítása sikerült.', - 'Unable to convert the subtask.' => 'Az alfeladat átalakítása nem sikerült.', - 'Unable to extract plugin archive.' => 'A plugin archívum kibontása nem sikerült.', - 'Plugin not found.' => 'A plugin nem található.', - 'You don\'t have the permission to remove this plugin.' => 'Nincs joga ennek a plugin-nek az eltávolításához.', - 'Unable to download plugin archive.' => 'A plugin archívum letöltése nem sikerült.', - 'Unable to write temporary file for plugin.' => 'A plugin-hez nem sikerült egy átmeneti fájl létrehozása.', - 'Unable to open plugin archive.' => 'Nem sikerült a plugin archívum megnyitása.', - 'There is no file in the plugin archive.' => 'A plugin archívumban nincs egyetelen egy fájl sem.', - 'Create tasks in bulk' => 'Feladatok tömeges létrehozása', - 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'Az Ön Kanboard példánya úgy lett konfigurálva, hogy ne lehessen plugin-eket installálni a felhasználói felületről.', - 'There is no plugin available.' => 'Nem áll plugin rendelkezésre.', - 'Install' => 'Installálás', - 'Update' => 'Módosítás', - 'Up to date' => 'Naprakész', - 'Not available' => 'Nem áll rendelkezésre', - 'Remove plugin' => 'Plugin eltávolítása', - 'Do you really want to remove this plugin: "%s"?' => 'Valóban el kívánja távolítani ezt a plugin-t: "%s"?', - // 'Uninstall' => '', - 'Listing' => 'Listázás', - 'Metadata' => 'Metaadat', - 'Manage projects' => 'Projektek kezelése', - 'Convert to task' => 'Feladattá történő átalakítás', - 'Convert sub-task to task' => 'Alfeladat feladattá történő átalakítása', - 'Do you really want to convert this sub-task to a task?' => 'Valóban feladattá akarja átalakítani ezt az alfeladatot?', - 'My task title' => 'A feladat címe', - 'Enter one task by line.' => 'Minden sorban egy feladatot adjon meg.', - 'Number of failed login:' => 'A sikertelen bejelentkezések száma:', - 'Account locked until:' => 'A számla zárolva a következő időpontig:', - // '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' => '', -); diff --git a/sources/app/Locale/id_ID/translations.php b/sources/app/Locale/id_ID/translations.php deleted file mode 100644 index d377651..0000000 --- a/sources/app/Locale/id_ID/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => ' ', - 'None' => 'Tidak satupun', - 'edit' => 'modifikasi', - 'Edit' => 'Modifikasi', - 'remove' => 'hapus', - 'Remove' => 'Hapus', - 'Yes' => 'Ya', - 'No' => 'Tidak', - 'cancel' => 'batal', - 'or' => 'atau', - 'Yellow' => 'Kuning', - 'Blue' => 'Biru', - 'Green' => 'Hijau', - 'Purple' => 'Ungu', - 'Red' => 'Merah', - 'Orange' => 'Jingga', - 'Grey' => 'Abu-abu', - 'Brown' => 'Coklat', - 'Deep Orange' => 'Oranye', - 'Dark Grey' => 'Abu-abu Gelap', - 'Pink' => 'Merah Muda', - 'Teal' => 'Teal', - 'Cyan' => 'Sian', - 'Lime' => 'Lime', - 'Light Green' => 'Hijau Muda', - 'Amber' => 'Amber', - 'Save' => 'Simpan', - 'Login' => 'Masuk', - '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 » ?', - 'All users' => 'Semua pengguna', - 'Username' => 'Nama pengguna', - 'Password' => 'Kata sandi', - 'Administrator' => 'Administrator', - 'Sign in' => 'Masuk', - 'Users' => 'Pengguna', - 'No user' => 'Tidak ada pengguna', - 'Forbidden' => 'Terlarang', - 'Access Forbidden' => 'Akses Dilarang', - 'Edit user' => 'Rubah Pengguna', - 'Logout' => 'Keluar', - 'Bad username or password' => 'Nama pengguna atau kata sandri buruk', - 'Edit project' => 'Rubah proyek', - 'Name' => 'Nama', - 'Projects' => 'Proyek', - 'No project' => 'Tidak ada proyek', - 'Project' => 'Proyek', - 'Status' => 'Status', - 'Tasks' => 'Tugas', - 'Board' => 'Papan', - 'Actions' => 'Tindakan', - 'Inactive' => 'Non Aktif', - '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', - '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 » ?', - 'Remove project' => 'Hapus proyek', - 'Edit the board for "%s"' => 'Rubah papan untuk « %s »', - 'All projects' => 'Semua proyek', - 'Add a new column' => 'Tambah kolom baru', - '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!', - '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)', - '(Gzip compressed Sqlite file)' => '(File Sqlite yang terkompress Gzip)', - 'Close a task' => 'Tutup tugas', - 'Edit a task' => 'Edit tugas', - 'Column' => 'Kolom', - 'Color' => 'Warna', - 'Assignee' => 'Orang yang ditugaskan', - '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 » ?', - 'Back to the board' => 'Kembali ke papan', - 'There is nobody assigned' => 'Tidak ada orang yand ditugaskan', - '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 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', - '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 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 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.', - '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.', - 'Unable to remove this project.' => 'Tidak dapat menghapus proyek ini.', - 'Project removed successfully.' => 'Proyek berhasil dihapus.', - 'Project activated successfully.' => 'Proyek berhasil diaktivasi.', - '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.', - 'Unable to open this task.' => 'Tidak dapat membuka tugas ini.', - '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 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 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.', - '%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 !', - 'Page not found' => 'Halaman tidak ditemukan', - 'Complexity' => 'Kompleksitas', - '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 added successfully.' => 'Komentar berhasil ditambahkan.', - 'Unable to create your comment.' => 'Tidak dapat menambahkan komentar anda.', - 'Due Date' => 'Batas Tanggal Terakhir', - 'Invalid date' => 'Tanggal tidak valid', - '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.', - 'Remove an action' => 'Hapus tindakan', - '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 »', - '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.', - '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 » ?', - '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', - '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', - 'Task creation' => 'Membuat tugas', - 'Closing a task' => 'Menutup tugas', - 'Assign a color to a specific user' => 'Menetapkan warna untuk pengguna tertentu', - 'Column title' => 'Judul kolom', - 'Position' => 'Posisi', - 'Duplicate to another project' => 'Duplikasi ke proyek lain', - 'Duplicate' => 'Duplikasi', - 'link' => 'tautan', - 'Comment updated successfully.' => 'Komentar berhasil diperbaharui.', - 'Unable to update your comment.' => 'Tidak dapat memperbaharui 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', - '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', - 'No session.' => 'Tidak ada sesi.', - 'Expiration date' => 'Tanggal kadaluarsa', - 'Remember Me' => 'Ingat Saya', - 'Creation date' => 'Tanggal dibuat', - '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.', - 'External authentication failed' => 'Otentifikasi eksternal gagal', - 'Your external account is linked to your profile successfully.' => 'Akun eksternal anda berhasil dihubungkan ke profil anda.', - 'Email' => 'Email', - '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 » ?', - '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', - '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.', - '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 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 » ?', - 'All categories' => 'Semua kategori', - 'No category' => 'Tidak ada kategori', - 'The name is required' => 'Nama diperlukan', - 'Remove a file' => 'Hapus berkas', - '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 » ?', - 'Attachments' => 'Lampiran', - 'Edit the task' => 'Modifikasi tugas', - 'Add a comment' => 'Tambahkan komentar', - 'Edit a comment' => 'Modifikasi komentar', - 'Summary' => 'Ringkasan', - 'Time tracking' => 'Pelacakan waktu', - 'Estimate:' => 'Estimasi :', - 'Spent:' => 'Menghabiskan:', - 'Do you really want to remove this sub-task?' => 'Apakah anda yakin akan menghapus sub-tugas ini ?', - 'Remaining:' => 'Tersisa:', - 'hours' => 'jam', - 'spent' => 'menghabiskan', - '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', - 'Remove a sub-task' => 'Hapus sub-tugas', - 'The time must be a numeric value' => 'Waktu harus berisikan numerik', - 'Todo' => 'Yang harus dilakukan', - 'In progress' => 'Sedang 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 added successfully.' => 'Sub-tugas berhasil dibuat.', - 'Maximum size: ' => 'Ukuran maksimum: ', - 'Unable to upload the file.' => 'Tidak dapat mengunggah berkas.', - 'Display another project' => 'Lihat proyek lain', - 'Created by %s' => 'Dibuat oleh %s', - 'Tasks Export' => 'Ekspor Tugas', - 'Tasks exportation for "%s"' => 'Tugas di ekspor untuk « %s »', - 'Start Date' => 'Tanggal Mulai', - 'End Date' => 'Tanggal Berakhir', - 'Execute' => 'Eksekusi', - 'Task Id' => 'Id Tugas', - 'Creator' => 'Pembuat', - 'Modification date' => 'Tanggal modifikasi', - 'Completion date' => 'Tanggal penyelesaian', - 'Clone' => 'Klon', - '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 :', - '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 :', - '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' => 'Lampirkan baru', - 'New comment' => 'Komentar baru', - 'Comment updated' => 'Komentar diperbaharui', - 'New subtask' => 'Sub-tugas baru', - 'Subtask updated' => 'Sub-tugas diperbaharui', - 'Task updated' => 'Tugas diperbaharui', - 'Task closed' => 'Tugas ditutup', - 'Task opened' => 'Tugas dibuka', - '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', - 'Public access' => 'Akses publik', - 'Active tasks' => 'Tugas aktif', - '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 » ?', - '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 ?', - 'Duplicate a task' => 'Duplikasi tugas', - 'External accounts' => 'Akun eksternal', - 'Account type' => 'Tipe akun', - 'Local' => 'Lokal', - 'Remote' => 'Jauh', - 'Enabled' => 'Aktif', - 'Disabled' => 'Nonaktif', - 'Username:' => 'Nama pengguna :', - 'Name:' => 'Nama :', - 'Email:' => 'Email :', - 'Notifications:' => 'Pemberitahuan :', - 'Notifications' => 'Pemberitahuan', - 'Account type:' => 'Tipe akun :', - 'Edit profile' => 'Modifikasi profil', - 'Change password' => 'Rubah kata sandri', - 'Password modification' => 'Modifikasi kata sandi', - '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', - '%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 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', - '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 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 open the task #%d' => '%s membuka tugas n°%d', - '%s moved the task #%d to the column "%s"' => '%s memindahkan tugas n°%d ke kolom « %s »', - '%s moved the task #%d to the position %d in the column "%s"' => '%s memindahkan tugas n°%d ke posisi n°%d dalam kolom « %s »', - 'Activity' => 'Aktifitas', - 'Default values are "%s"' => 'Standar nilai 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 change 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 »', - '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', - 'Reference' => 'Referensi', - 'Label' => 'Label', - 'Database' => 'Basis data', - 'About' => 'Tentang', - 'Database driver:' => 'Driver basis data :', - 'Board settings' => 'Pengaturan papan', - 'Webhook settings' => 'Pengaturan webhook', - 'Reset token' => 'Mereset 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)', - '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 »', - 'New private project' => 'Proyek pribadi baru', - 'This project is private' => 'Proyek ini adalah pribadi', - 'Add' => 'Tambah', - 'Start date' => 'Tanggal mulai', - 'Time estimated' => 'Perkiraan waktu', - 'There is nothing assigned to you.' => 'Tidak ada yang diberikan kepada 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', - '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', - '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.', - 'Percentage' => 'Persentasi', - 'Number of tasks' => 'Jumlah dari tugas', - 'Task distribution' => 'Pembagian tugas', - 'Reportings' => 'Pelaporan', - 'Task repartition for "%s"' => 'Pembagian tugas untuk « %s »', - 'Analytics' => 'Analitis', - 'Subtask' => 'Subtugas', - 'My subtasks' => 'Subtugas saya', - 'User repartition' => 'Partisi ulang pengguna', - 'User repartition for "%s"' => 'Partisi ulang pengguna untuk « %s »', - 'Clone this project' => 'Gandakan 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 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', - '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', - 'Cumulative flow diagram' => 'Diagram alir kumulatif', - 'Cumulative flow diagram for "%s"' => 'Diagram alir kumulatif untuk « %s »', - 'Daily project summary' => 'Ringkasan proyek harian', - 'Daily project summary export' => 'Ekspor ringkasan proyek harian', - 'Daily project summary export for "%s"' => 'Ekspor ringkasan proyek harian untuk « %s »', - 'Exports' => 'Ekspor', - 'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom dikelompokan perhari.', - '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 » ?', - '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 »', - '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.', - '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)', - 'Integrations' => 'Integrasi', - 'Integration with third-party services' => 'Integrasi dengan layanan pihak ketiga', - 'Subtask Id' => 'Id Subtugas', - 'Subtasks' => 'Subtugas', - 'Subtasks Export' => 'Ekspor Subtugas', - 'Subtasks exportation for "%s"' => 'Ekspor subtugas untuk « %s »', - 'Task Title' => 'Judul Tugas', - 'Untitled' => 'Tanpa nama', - 'Application default' => 'Aplikasi standar', - 'Language:' => 'Bahasa :', - 'Timezone:' => 'Zona waktu :', - 'All columns' => 'Semua kolom', - 'Calendar' => 'Kalender', - 'Next' => 'Selanjutnya', - '#%d' => 'n˚%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?', - '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', - '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', - 'Link added successfully.' => 'Tautan berhasil ditambahkan.', - 'Link updated successfully.' => 'Tautan berhasil diperbaharui.', - '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 remove this link.' => 'Tidak dapat menghapus tautan ini.', - 'relates to' => 'berhubungan dengan', - 'blocks' => 'blok', - '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', - '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', - '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', - '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 :', - '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', - 'download' => 'unduh', - 'EUR - Euro' => 'EUR - Euro', - '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', - 'RSD - Serbian dinar' => 'RSD - Dinar Serbia', - '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', - 'Move the task to another column when assignee is cleared' => 'Pindahkan tugas ke kolom lain ketika orang yang ditugaskan dibersihkan', - 'Source column' => 'Sumber kolom', - 'Transitions' => 'Transisi', - 'Executer' => 'Eksekusi', - 'Time spent in the column' => 'Waktu yang dihabiskan dalam kolom', - 'Task transitions' => 'Transisi tugas', - 'Task transitions export' => 'Ekspor transisi tugas', - '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', - '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', - '%s remove the assignee of the task %s' => '%s menghapus penugasan dari tugas %s', - 'Enable Gravatar images' => 'Mengaktifkan 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.', - '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', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Grafik Burndown untku « %s »', - '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.', - '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', - 'Start to type task title...' => 'Mulai mengetik judul tugas...', - 'A task cannot be linked to itself' => 'Sebuah 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', - 'Score' => 'Skor', - 'The identifier must be unique' => 'Identifier harus unik', - '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', - '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: ', - '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:', - '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', - '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 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', - 'Preferences' => 'Preferensi', - 'Security' => 'Keamanan', - 'Two factor authentication disabled' => 'Otentifikasi dua faktor dimatikan', - 'Two factor authentication enabled' => 'Otentifikasi dua faktor dihidupkan', - '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', - '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', - 'Column change' => 'Kolom berubah', - 'Position change' => 'Posisi berubah', - 'Swimlane change' => 'Swimlane berubah', - 'Assignee change' => 'Penerima berubah', - '[%s] Overdue tasks' => '[%s] Tugas terlambat', - '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 swimlane "%s"' => '%s memindahkan tugas n°%d ke swimlane « %s »', - '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.', - '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 »', - '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', - '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', - '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', - 'The description has been modified:' => 'Deskripsi telah dimodifikasi', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Apakah anda yakin akan menutup tugas « %s » beserta semua sub-tugasnya ?', - 'I want to receive notifications for:' => 'Saya ingin menerima pemberitahuan untuk :', - 'All tasks' => 'Semua tugas', - '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', - 'Only for tasks created by me and assigned to me' => 'Hanya untuk tugas yang dibuat oleh saya dan ditugaskan ke saya', - '%%Y-%%m-%%d' => '%%d/%%m/%%Y', - 'Total for all columns' => 'Total untuk semua kolom', - 'You need at least 2 days of data to show the chart.' => 'Anda memerlukan setidaknya 2 hari dari data yang menunjukkan grafik.', - '<15m' => '<15m', - '<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', - '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', - 'Not assigned' => 'Tidak ditugaskan', - 'View advanced search syntax' => 'Lihat sintaks pencarian lanjutan', - 'Overview' => 'Ikhtisar', - '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.', - 'No tasks found.' => 'Tidak ada tugas yang ditemukan.', - 'Keyboard shortcut: "%s"' => 'Keyboard shortcut : « %s »', - 'List' => 'Daftar', - 'Filter' => 'Filter', - '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 : ', - 'Lead and Cycle time for "%s"' => 'Memimpin dan Siklus waktu untuk « %s »', - 'Average time spent into each column for "%s"' => 'Rata-rata waktu yang dihabiskan dalam setiap kolom untuk « %s »', - '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', - '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.', - '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 : ', - '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.', - 'Set automatically the start date' => 'Secara otomatis mengatur tanggal mulai', - 'Edit Authentication' => 'Modifikasi 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', - 'no category' => 'tidak ada kategori', - 'Current assignee: %s' => 'Saat ini ditugaskan : %s', - 'not assigned' => 'Belum ditugaskan', - 'Author:' => 'Penulis :', - 'contributors' => 'kontributor', - 'License:' => 'Lisensi :', - 'License' => 'Lisensi', - 'Enter the text below' => 'Masukkan teks di bawah', - 'Gantt chart for %s' => 'Grafik Gantt untuk %s', - 'Sort by position' => 'Urutkan berdasarkan posisi', - 'Sort by date' => 'Urutkan berdasarkan tanggal', - 'Add task' => 'Tambah tugas', - '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.', - 'Gantt chart' => 'Grafik Gantt', - 'People who are project managers' => 'Orang-orang yang menjadi manajer proyek', - 'People who are project members' => 'Orang-orang yang menjadi anggota proyek', - 'NOK - Norwegian Krone' => 'NOK - Krone Norwegia', - 'Show this column' => 'Perlihatkan kolom ini', - 'Hide this column' => 'Sembunyikan kolom ini', - 'open file' => 'buka berkas', - 'End date' => 'Waktu berakhir', - 'Users overview' => 'Ikhtisar pengguna', - 'Members' => 'Anggota', - 'Shared project' => 'Proyek bersama', - 'Project managers' => 'Manajer proyek', - 'Gantt chart for all projects' => 'Grafik Gantt untuk semua proyek', - 'Projects list' => 'Daftar proyek', - 'Gantt chart for this project' => 'Grafik Gantt untuk proyek ini', - 'Project board' => 'Papan proyek', - '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', - 'Task link creation or modification' => 'Tautan pembuatan atau modifikasi tugas ', - 'Milestone' => 'Milestone', - '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', - 'Documentation' => 'Dokumentasi', - 'Table of contents' => 'Daftar isi', - 'Gantt' => 'Gantt', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - 'Link type' => 'Tipe tautan', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - 'Project members' => 'Anggota proyek', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/it_IT/translations.php b/sources/app/Locale/it_IT/translations.php deleted file mode 100644 index 4ae1419..0000000 --- a/sources/app/Locale/it_IT/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'Nessuno', - 'edit' => 'modifica', - 'Edit' => 'Modifica', - 'remove' => 'cancella', - 'Remove' => 'Cancella', - 'Yes' => 'Si', - 'No' => 'No', - 'cancel' => 'annulla', - 'or' => 'o', - 'Yellow' => 'Giallo', - 'Blue' => 'Blu', - 'Green' => 'Verde', - 'Purple' => 'Viola', - 'Red' => 'Rosso', - 'Orange' => 'Arancione', - 'Grey' => 'Grigio', - 'Brown' => 'Marrone', - 'Deep Orange' => 'Arancio scuro', - 'Dark Grey' => 'Grigio scuro', - 'Pink' => 'Rosa', - 'Teal' => 'Verde foglia di tè', - 'Cyan' => 'Ciano', - // 'Lime' => '', - 'Light Green' => 'Verde chiaro', - 'Amber' => 'Ambra', - 'Save' => 'Salva', - 'Login' => 'Accedi', - 'Official website:' => 'Sito web ufficiale:', - 'Unassigned' => 'Non assegnato', - 'View this task' => 'Visualizza questo task', - 'Remove user' => 'Cancella un utente', - 'Do you really want to remove this user: "%s"?' => 'Veramente vuoi cancellare questo utente: "%s" ?', - 'All users' => 'Tutti gli utenti', - 'Username' => 'Nome utente', - 'Password' => 'Password', - 'Administrator' => 'Amministratore', - 'Sign in' => 'Accedi', - 'Users' => 'Utenti', - 'No user' => 'Nessun utente', - 'Forbidden' => 'Vietato', - 'Access Forbidden' => 'Accesso vietato', - 'Edit user' => 'Modifica un utente', - 'Logout' => 'Esci', - 'Bad username or password' => 'Utente o password errati', - 'Edit project' => 'Modifica progetto', - 'Name' => 'Nome', - 'Projects' => 'Progetti', - 'No project' => 'Nessun progetto', - 'Project' => 'Progetto', - 'Status' => 'Stato', - 'Tasks' => 'Task', - 'Board' => 'Bacheca', - 'Actions' => 'Azioni', - 'Inactive' => 'Inattivo', - 'Active' => 'Attivo', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Vuoi davvero eliminare il seguente progetto: "%s" ?', - 'Remove project' => 'Cancella il progetto', - 'Edit the board for "%s"' => 'Modifica la bacheca per "%s"', - 'All projects' => 'Tutti i progetti', - 'Add a new column' => 'Aggiungi una nuova colonna', - 'Title' => 'Titolo', - '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!', - 'Settings' => 'Impostazioni', - 'Application settings' => 'Impostazioni dell\'applicazione', - 'Language' => 'Lingua', - 'Webhook token:' => 'Identificatore (token) per i webhooks :', - 'API token:' => 'Token dell\'API:', - 'Database size:' => 'Dimensioni della base dati:', - 'Download the database' => 'Scaricare la base dati', - 'Optimize the database' => 'Ottimizare la base dati', - '(VACUUM command)' => '(Comando VACUUM)', - '(Gzip compressed Sqlite file)' => '(File Sqlite compresso in Gzip)', - 'Close a task' => 'Chiudi un task', - 'Edit a task' => 'Modifica un task', - 'Column' => 'Colonna', - 'Color' => 'Colore', - 'Assignee' => 'Assegnatario', - 'Create another task' => 'Crea un nuovo task', - 'New task' => 'Nuovo task', - 'Open a task' => 'Apri un task', - 'Do you really want to open this task: "%s"?' => 'Desideri davvero aprire questo task: "%s" ?', - 'Back to the board' => 'Torna alla bacheca', - 'There is nobody assigned' => 'Nessuno è assegnato a questo task', - 'Column on the board:' => 'Colonna sulla bacheca: ', - 'Close this task' => 'Chiudi questo task', - 'Open this task' => 'Apri questo task', - 'There is no description.' => 'Nessuna descrizione presente.', - 'Add a new task' => 'Aggiungere un nuovo task', - 'The username is required' => 'Si richiede un nome di utente', - 'The maximum length is %d characters' => 'La lunghezza massima è di %d caratteri', - 'The minimum length is %d characters' => 'La lunghezza minima è di %d caratteri', - 'The password is required' => 'Si richiede una password', - 'This value must be an integer' => 'questo valore deve essere un intero', - 'The username must be unique' => 'Il nome di utente deve essere unico', - 'The user id is required' => 'Si richiede l\'identificatore dell\'utente', - 'Passwords don\'t match' => 'Le password non corrispondono', - 'The confirmation is required' => 'Si richiede una conferma', - 'The project is required' => 'Si richiede il progetto', - 'The id is required' => 'Si richiede l\'identificatore', - 'The project id is required' => 'Si richiede l\'identificatore del progetto', - 'The project name is required' => 'Si richiede il nome del progetto', - 'The title is required' => 'Si richiede un titolo', - 'Settings saved successfully.' => 'Impostazioni salvate con successo.', - 'Unable to save your settings.' => 'Impossibile salvare le impostazioni.', - 'Database optimization done.' => 'Ottimizzazione della base dati conclusa.', - 'Your project have been created successfully.' => 'Il tuo progetto è stato creato con successo.', - 'Unable to create your project.' => 'Impossibile creare il progetto.', - 'Project updated successfully.' => 'Progetto aggiornato con successo.', - 'Unable to update this project.' => 'Impossibile aggiornare il progetto.', - 'Unable to remove this project.' => 'Impossibile cancellare questo progetto.', - 'Project removed successfully.' => 'Progetto cancellato con successo.', - 'Project activated successfully.' => 'Progetto attivato con successo.', - 'Unable to activate this project.' => 'Impossibile attivare il progetto.', - 'Project disabled successfully.' => 'Progetto disattivato con successo.', - 'Unable to disable this project.' => 'Impossibile disattivare il progetto.', - 'Unable to open this task.' => 'Impossibile aprire questo task.', - 'Task opened successfully.' => 'Il task è stato aperto con successo.', - 'Unable to close this task.' => 'Impossibile chiudere questo task.', - 'Task closed successfully.' => 'Task chiuso con successo.', - 'Unable to update your task.' => 'Impossibile modificare questo task.', - 'Task updated successfully.' => 'Task modificato con successo.', - 'Unable to create your task.' => 'Impossibile creare questo task.', - 'Task created successfully.' => 'Task creato con successo.', - 'User created successfully.' => 'Utente creato con successo.', - 'Unable to create your user.' => 'Impossibile creare l\'utente.', - 'User updated successfully.' => 'Utente aggiornato con successo.', - 'Unable to update your user.' => 'Impossibile aggiornare questo utente.', - 'User removed successfully.' => 'Utente cancellato con successo.', - 'Unable to remove this user.' => 'Impossibile cancellare questo utente.', - 'Board updated successfully.' => 'Bacheca aggiornata con successo.', - 'Ready' => 'Pronto', - 'Backlog' => 'In attesa', - 'Work in progress' => 'In corso', - 'Done' => 'Fatto', - 'Application version:' => 'Versione dell\'applicazione:', - // 'Id' => '', - '%d closed tasks' => '%d task chiusi', - 'No task for this project' => 'Nessun task per questo progetto', - 'Public link' => 'Link pubblico', - 'Timezone' => 'Fuso orario', - 'Sorry, I didn\'t find this information in my database!' => 'Spiacente, non ho trovato questa informazione sul database!', - 'Page not found' => 'Pagina non trovata', - 'Complexity' => 'Complessità', - 'Task limit' => 'Limite di task', - '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', - 'Invalid date' => 'Data non valida', - 'Automatic actions' => 'Azioni automatiche', - 'Your automatic action have been created successfully.' => 'l\'azione automatica è stata creata con successo.', - 'Unable to create your automatic action.' => 'Impossibile creare quest\'azione automatica.', - 'Remove an action' => 'Cancellare un\'azione', - 'Unable to remove this action.' => 'Impossibile cancellare questa azione.', - 'Action removed successfully.' => 'Azione cancellata con successo.', - 'Automatic actions for the project "%s"' => 'Azioni automatiche per il progetto "%s"', - 'Add an action' => 'Aggiungi un\'azione', - 'Event name' => 'Nome dell\'evento', - 'Action name' => 'Nome dell\'azione', - 'Action parameters' => 'Parametri d\'azione', - 'Action' => 'Azione', - 'Event' => 'Evento', - 'When the selected event occurs execute the corresponding action.' => 'Quando si verifica l\'evento selezionato, eseguire l\'azione corrispondente.', - 'Next step' => 'Passo successivo', - 'Define action parameters' => 'Definire i parametri dell\'azione', - 'Do you really want to remove this action: "%s"?' => 'Vuoi davvero cancellare la seguente azione: "%s"?', - 'Remove an automatic action' => 'Cancella un\'azione automatica', - 'Assign the task to a specific user' => 'Assegna il task ad un utente specifico', - 'Assign the task to the person who does the action' => 'Assegna il task all\'utente che compie l\'azione', - 'Duplicate the task to another project' => 'Duplica il task in altro progetto', - 'Move a task to another column' => 'Sposta un task in un\'altra colonna', - 'Task modification' => 'Modifica di un task', - 'Task creation' => 'Creazione di un task', - 'Closing a task' => 'Chiusura di un task', - 'Assign a color to a specific user' => 'Assegna un colore ad un utente specifico', - 'Column title' => 'Titolo della colonna', - 'Position' => 'Posizione', - 'Duplicate to another project' => 'Duplica in un altro progetto', - 'Duplicate' => 'Duplica', - 'link' => 'relazione', - 'Comment updated successfully.' => 'Commento aggiornato con successo.', - 'Unable to update your comment.' => 'Impossibile aggiornare questo commento.', - 'Remove a comment' => 'Cancella un commento', - 'Comment removed successfully.' => 'Commento cancellato con successo.', - 'Unable to remove this comment.' => 'Impossibile cancellare questo commento.', - 'Do you really want to remove this comment?' => 'Vuoi davvero cancellare questo commento?', - 'Current password for the user "%s"' => 'Password attuale per l\'utente "%s"', - 'The current password is required' => 'Si richiede la password attuale', - 'Wrong password' => 'Password errata', - 'Unknown' => 'Sconociuto', - 'Last logins' => 'Ultimi accessi', - 'Login date' => 'Data di accesso', - 'Authentication method' => 'Metodo di autenticazione', - 'IP address' => 'Indirizzo IP', - 'User agent' => 'User agent', - 'Persistent connections' => 'Connessioni persistenti', - 'No session.' => 'Non esiste sessione.', - 'Expiration date' => 'Data di scadenza', - 'Remember Me' => 'Ricordami', - 'Creation date' => 'Data di creazione', - 'Everybody' => 'Tutti', - 'Open' => 'Aperto', - 'Closed' => 'Chiuso', - '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', - 'Email address invalid' => 'Indirizzo Email non valido', - 'Your external account is not linked anymore to your profile.' => 'Il tuo account esterno non è più collegato al tuo profilo.', - 'Unable to unlink your external account.' => 'Impossibile scollegare il tuo account esterno.', - 'External authentication failed' => 'Autenticazione esterna fallita', - 'Your external account is linked to your profile successfully.' => 'Il tuo account esterno è stato collegato al tuo profilo con successo.', - 'Email' => 'E-mail', - 'Task removed successfully.' => 'Task cancellato con successo.', - 'Unable to remove this task.' => 'Impossibile cancellare questo task.', - 'Remove a task' => 'Cancella un task', - 'Do you really want to remove this task: "%s"?' => 'Vuoi davvero cancellare questo task: "%s"?', - 'Assign automatically a color based on a category' => 'Assegna un colore in modo automatico basandosi sulla categoria', - 'Assign automatically a category based on a color' => 'Assegna una categoria in modo automatico basandosi sul colore', - 'Task creation or modification' => 'Creazione o modifica di task', - 'Category' => 'Categoria', - 'Category:' => 'Categoria:', - 'Categories' => 'Categorie', - 'Your category have been created successfully.' => 'La tua categoria è stata creata con successo.', - 'Unable to create your category.' => 'Impossibile creare la tua categoria.', - 'Your category have been updated successfully.' => 'La tua categoria è stata aggiornata con successo.', - 'Unable to update your category.' => 'Impossibile aggiornare la tua categoria.', - 'Remove a category' => 'Cancella una categoria', - 'Category removed successfully.' => 'Categoria cancellata con successo.', - 'Unable to remove this category.' => 'Impossibile cancellare questa categoria.', - 'Category modification for the project "%s"' => 'Modifica della categoria per il progetto "%s"', - 'Category Name' => 'Nome della categoria', - 'Add a new category' => 'Aggiungere una nuova categoria', - 'Do you really want to remove this category: "%s"?' => 'Vuoi davvero cancellare la seguente categoria: "%s"?', - 'All categories' => 'Tutte le categorie', - 'No category' => 'Senza categoria', - 'The name is required' => 'Si richiede un nome', - 'Remove a file' => 'Cancella un file', - 'Unable to remove this file.' => 'Impossibile cancellare questo file.', - 'File removed successfully.' => 'File cancellato con successo.', - 'Attach a document' => 'Allega un documento', - 'Do you really want to remove this file: "%s"?' => 'Vuoi davvero cancellare questo file: "%s"?', - 'Attachments' => 'Allegati', - 'Edit the task' => 'Modifica il task', - 'Add a comment' => 'Aggiungi un commento', - 'Edit a comment' => 'Modifica un commento', - 'Summary' => 'Sommario', - // 'Time tracking' => '', - 'Estimate:' => 'Stimato:', - 'Spent:' => 'Trascorso:', - 'Do you really want to remove this sub-task?' => 'Vuoi davvero cancellare questo sotto-task?', - 'Remaining:' => 'Rimangono', - 'hours' => 'ore', - 'spent' => 'trascorse', - 'estimated' => 'stimate', - 'Sub-Tasks' => 'Sotto-task', - 'Add a sub-task' => 'Aggiungi un sotto-task', - 'Original estimate' => 'Stima originale', - 'Create another sub-task' => 'Crea un altro sotto-task', - 'Time spent' => 'Tempo trascorso', - 'Edit a sub-task' => 'Modifica un sotto-task', - 'Remove a sub-task' => 'Cancella un sotto-task', - 'The time must be a numeric value' => 'Il tempo deve essere un valore numerico', - 'Todo' => 'Da fare', - 'In progress' => 'In corso', - 'Sub-task removed successfully.' => 'Sotto-task cancellato con successo.', - 'Unable to remove this sub-task.' => 'Impossibile cancellare questo sotto-task.', - 'Sub-task updated successfully.' => 'Sotto-task aggiornato con successo.', - 'Unable to update your sub-task.' => 'Impossibile aggiornare il tuo sotto-task.', - 'Unable to create your sub-task.' => 'Impossibile creare il tuo sotto-task.', - 'Sub-task added successfully.' => 'Sotto-task aggiunto con successo.', - 'Maximum size: ' => 'Dimensioni massime: ', - 'Unable to upload the file.' => 'Impossibile caricare il file.', - 'Display another project' => 'Mostra un altro progetto', - 'Created by %s' => 'Creato da %s', - 'Tasks Export' => 'Export dei task', - 'Tasks exportation for "%s"' => 'Export dei task per "%s"', - 'Start Date' => 'Data d\'inizio', - 'End Date' => 'Data di fine', - 'Execute' => 'Esegui', - 'Task Id' => 'Id del task', - 'Creator' => 'Creatore', - 'Modification date' => 'Data di modifica', - 'Completion date' => 'Data di termine', - 'Clone' => 'Clona', - 'Project cloned successfully.' => 'Progetto clonato con successo.', - 'Unable to clone this project.' => 'Impossibile clonare questo progetto', - 'Enable email notifications' => 'Abilita le notifiche via email', - 'Task position:' => 'Posizione del task:', - 'The task #%d have been opened.' => 'Il task #%d è stato aperto.', - 'The task #%d have been closed.' => 'Il task #%d è stato chiuso.', - 'Sub-task updated' => 'Sotto-task aggiornato', - 'Title:' => 'Titolo', - 'Status:' => 'Stato', - 'Assignee:' => 'Assegnatario:', - // 'Time tracking:' => '', - 'New sub-task' => 'Nuovo sotto-task', - 'New attachment added "%s"' => 'Nuovo allegato aggiunto "%s"', - 'New comment posted by %s' => 'Nuovo commento aggiunto da "%s"', - 'New attachment' => 'Nuovo allegato', - 'New comment' => 'Nuovo commento', - 'Comment updated' => 'Commento aggiornato', - 'New subtask' => 'Nuovo sotto-task', - 'Subtask updated' => 'Sotto-task aggiornato', - 'Task updated' => 'Task aggiornato', - 'Task closed' => 'Task chiuso', - 'Task opened' => 'Task aperto', - 'I want to receive notifications only for those projects:' => 'Vorrei ricevere le notifiche solo da questi progetti:', - 'view the task on Kanboard' => 'visualizza il task su Kanboard', - 'Public access' => 'Accesso pubblico', - 'Active tasks' => 'Task attivi', - 'Disable public access' => 'Disabilita l\'accesso pubblico', - 'Enable public access' => 'Abilita l\'accesso pubblico', - 'Public access disabled' => 'Accesso pubblico disattivato', - 'Do you really want to disable this project: "%s"?' => 'Vuoi davvero disabilitare il seguente progetto: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Vuoi davvero abilitare il seguente progetto: "%s"?', - 'Project activation' => 'Attivazione progetto', - 'Move the task to another project' => 'Sposta il task in un altro progetto', - 'Move to another project' => 'Sposta in un altro progetto', - 'Do you really want to duplicate this task?' => 'Vuoi davvero duplicare questo task?', - 'Duplicate a task' => 'Duplica il task', - 'External accounts' => 'Account esterni', - 'Account type' => 'Tipo di account', - 'Local' => 'Locale', - 'Remote' => 'Remoto', - 'Enabled' => 'Abilitato', - 'Disabled' => 'Disabilitato', - 'Username:' => 'Nome utente:', - 'Name:' => 'Nome:', - // 'Email:' => '', - 'Notifications:' => 'Notifiche:', - 'Notifications' => 'Notifiche', - 'Account type:' => 'Tipo di account', - 'Edit profile' => 'Modifica profilo', - 'Change password' => 'Cambia password', - 'Password modification' => 'Modifica della password', - 'External authentications' => 'Autenticazione esterna', - 'Never connected.' => 'Mai connesso.', - 'No external authentication enabled.' => 'Nessuna autenticazione esterna abilitata.', - 'Password modified successfully.' => 'Password modificata con successo.', - 'Unable to change the password.' => 'Impossibile cambiare la password.', - 'Change category' => 'Cambia categoria', - '%s updated the task %s' => '%s ha aggiornato il task %s', - '%s opened the task %s' => '%s ha aperto il task %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s ha spostato il task %s nella posizione #%d della colonna "%s"', - '%s moved the task %s to the column "%s"' => '%s ha spostato il task %s nella colonna "%s"', - '%s created the task %s' => '%s ha creato il task %s', - '%s closed the task %s' => '%s ha chiuso il task %s', - '%s created a subtask for the task %s' => '%s ha creato un sotto-task per il task %s', - '%s updated a subtask for the task %s' => '%s ha aggiornato un sotto-task per il task %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Assegnato a %s con una stima di %s/%sh', - 'Not assigned, estimate of %sh' => 'Non assegnato, stima %sh', - '%s updated a comment on the task %s' => '%s ha aggiornato un commento nel task %s', - '%s commented the task %s' => '%s ha commentato il task %s', - '%s\'s activity' => 'Attività di %s', - 'RSS feed' => 'Feed RSS', - '%s updated a comment on the task #%d' => '%s ha aggiornato un commento del task #%d', - '%s commented on the task #%d' => '%s ha commentato il task #%d', - '%s updated a subtask for the task #%d' => '%s ha aggiornato un sotto-task del task #%d', - '%s created a subtask for the task #%d' => '%s ha creato un sotto-task del task #%d', - '%s updated the task #%d' => '%s ha aggiornato il task #%d', - '%s created the task #%d' => '%s ha creato il task #%d', - '%s closed the task #%d' => '%s ha chiuso il task #%d', - '%s open the task #%d' => '%s ha aperto il task #%d', - '%s moved the task #%d to the column "%s"' => '%s ha spostato il task #%d nella colonna "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s ha spostato il task #%d nella posizione %d della colonna "%s"', - 'Activity' => 'Attività', - 'Default values are "%s"' => 'Valori di default "%s"', - 'Default columns for new projects (Comma-separated)' => 'Colonne di default per i nuovi progetti (Separati da virgola)', - 'Task assignee change' => 'Cambia l\'assegnatario del task', - '%s change the assignee of the task #%d to %s' => '%s dai l\'assegnazione del task #%d a %s', - '%s changed the assignee of the task %s to %s' => '%s ha cambiato l\'assegnatario del task %s a %s', - 'New password for the user "%s"' => 'Nuova password per l\'utente "%s"', - 'Choose an event' => 'Scegli un evento', - 'Create a task from an external provider' => 'Crea un task da un provider esterno', - 'Change the assignee based on an external username' => 'Cambia l\'assegnatario basandosi su un username esterno', - 'Change the category based on an external label' => 'Cambia la categoria basandosi su un\'etichetta esterna', - 'Reference' => 'Riferimento', - 'Label' => 'Etichetta', - // 'Database' => '', - 'About' => 'Informazioni', - 'Database driver:' => 'Driver per Database', - 'Board settings' => 'Impostazioni bacheca', - 'Webhook settings' => 'Impostazione Webhook', - 'Reset token' => 'Rigenera il token', - 'API endpoint:' => 'Endpoint dell\'API:', - 'Refresh interval for private board' => 'Intervallo di refresh per le bacheche private', - 'Refresh interval for public board' => 'Intervallo di refresh per le bacheche pubbliche', - 'Task highlight period' => 'Periodo di evidenza per il task', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Periodo (in secondi) per considerare un task come modificato recentemente (0 per disabilitare, 2 giorni di default)', - 'Frequency in second (60 seconds by default)' => 'Frequenza in secondi (60 secondi di default)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frequenza in secondi (0 secondi di default)', - 'Application URL' => 'URL dell\'applicazione', - 'Token regenerated.' => 'Token rigenerato.', - 'Date format' => 'Formato data', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Il formato ISO è sempre accettato, esempio: "%s" e "%s"', - 'New private project' => 'Nuovo progetto privato', - 'This project is private' => 'Questo progetto è privato', - 'Add' => 'Aggiungi', - 'Start date' => 'Data di inizio', - 'Time estimated' => 'Tempo stimato', - 'There is nothing assigned to you.' => 'Non c\'è nulla assegnato a te.', - 'My tasks' => 'I miei task', - 'Activity stream' => 'Flusso attività', - 'Dashboard' => 'Bacheca', - 'Confirmation' => 'Conferma', - 'Allow everybody to access to this project' => 'Abilita tutti ad accedere a questo progetto', - 'Everybody have access to this project.' => 'Tutti hanno accesso a questo progetto.', - // 'Webhooks' => '', - // 'API' => '', - 'Create a comment from an external provider' => 'Crea un commit da un provider esterno', - 'Project management' => 'Gestione progetti', - 'My projects' => 'I miei progetti', - 'Columns' => 'Colonne', - 'Task' => 'Task', - 'Your are not member of any project.' => 'Non sei membro di alcun progetto.', - 'Percentage' => 'Percentuale', - 'Number of tasks' => 'Numero di task', - 'Task distribution' => 'Distribuzione dei task', - 'Reportings' => 'Rapporti', - 'Task repartition for "%s"' => 'Ripartizione task per "%s"', - // 'Analytics' => '', - 'Subtask' => 'Sotto-task', - 'My subtasks' => 'I miei sotto-task', - 'User repartition' => 'Ripartizione per utente', - 'User repartition for "%s"' => 'Ripartizione utente per "%s"', - 'Clone this project' => 'Clona questo progetto', - 'Column removed successfully.' => 'Colonna rimossa con successo', - 'Not enough data to show the graph.' => 'Non ci sono abbastanza dati per visualizzare il grafico.', - 'Previous' => 'Precendete', - 'The id must be an integer' => 'L\'id deve essere un intero', - 'The project id must be an integer' => 'L\'id del progetto deve essere un intero', - 'The status must be an integer' => 'Lo status deve essere un intero', - 'The subtask id is required' => 'L\'id del sotto-task è necessario', - 'The subtask id must be an integer' => 'L\'id del sotto-task deve essere un intero', - 'The task id is required' => 'Richiesto l\'id del task', - 'The task id must be an integer' => 'L\'id del task deve essere un intero', - 'The user id must be an integer' => 'L\'id dell\'utente deve essere un intero', - 'This value is required' => 'Questo valore è necessario', - 'This value must be numeric' => 'Questo valore deve essere numerico', - 'Unable to create this task.' => 'Impossibile creare questo task', - 'Cumulative flow diagram' => 'Diagramma di flusso cumulativo', - 'Cumulative flow diagram for "%s"' => 'Diagramma di flusso comulativo per "%s"', - 'Daily project summary' => 'Sommario giornaliero del progetto', - 'Daily project summary export' => 'Export del sommario giornaliero del progetto', - 'Daily project summary export for "%s"' => 'Export del sommario giornaliero del progetto per "%s"', - 'Exports' => 'Esporta', - 'This export contains the number of tasks per column grouped per day.' => 'Questo export contiene il numero di task per colonna raggruppati per giorno', - 'Active swimlanes' => 'Corsie attive', - 'Add a new swimlane' => 'Aggiungi una corsia', - 'Change default swimlane' => 'Cambia la corsia predefinita', - 'Default swimlane' => 'Corsia predefinita', - 'Do you really want to remove this swimlane: "%s"?' => 'Vuoi davvero rimuovere la seguente corsia: "%s"?', - 'Inactive swimlanes' => 'Corsie inattive', - 'Remove a swimlane' => 'Rimuovi una corsia', - 'Show default swimlane' => 'Mostra la corsia predefinita', - 'Swimlane modification for the project "%s"' => 'Modifica corsia per il progetto "%s"', - 'Swimlane removed successfully.' => 'Corsia rimossa con successo.', - 'Swimlanes' => 'Corsie', - 'Swimlane updated successfully.' => 'Corsia aggiornata con successo.', - 'The default swimlane have been updated successfully.' => 'La corsia predefinita è stata aggiornata con successo.', - 'Unable to remove this swimlane.' => 'Impossibile rimuovere questa corsia.', - 'Unable to update this swimlane.' => 'Impossibile aggiornare questa corsia.', - 'Your swimlane have been created successfully.' => 'La tua corsia è stata creata con successo', - 'Example: "Bug, Feature Request, Improvement"' => 'Esempi: "Bug, Richiesta di Funzioni, Migliorie"', - 'Default categories for new projects (Comma-separated)' => 'Categorie di default per i progetti (Separati da virgola)', - 'Integrations' => 'Integrazioni', - 'Integration with third-party services' => 'Integrazione con servizi di terze parti', - 'Subtask Id' => 'Id del sotto-task', - 'Subtasks' => 'Sotto-task', - 'Subtasks Export' => 'Esporta i sotto-task', - 'Subtasks exportation for "%s"' => 'Export dei sotto-task per "%s"', - 'Task Title' => 'Titolo del task', - 'Untitled' => 'Senza titolo', - 'Application default' => 'Default dell\'applicazione', - 'Language:' => 'Lingua', - 'Timezone:' => 'Fuso Orario', - 'All columns' => 'Tutte le colonne', - 'Calendar' => 'Calendario', - 'Next' => 'Prossimo', - // '#%d' => '', - 'All swimlanes' => 'Tutte le corsie', - 'All colors' => 'Tutti i colori', - 'Moved to column %s' => 'Spostato sulla colonna "%s"', - 'User dashboard' => 'Bacheca utente', - 'Allow only one subtask in progress at the same time for a user' => 'Permetti un solo sotto-task in corso per utente alla volta', - 'Edit column "%s"' => 'Modifica la colonna "%s"', - 'Select the new status of the subtask: "%s"' => 'Seleziona il nuovo status per il sotto-task: "%s"', - 'Subtask timesheet' => 'Timesheet del sotto-task', - 'There is nothing to show.' => 'Nulla da mostrare.', - // 'Time Tracking' => '', - 'You already have one subtask in progress' => 'Hai già un sotto-task in corso', - 'Which parts of the project do you want to duplicate?' => 'Quali parti del progetto vuoi duplicare?', - 'Disallow login form' => 'Disabilita il form di login', - 'Start' => 'Inizio', - 'End' => 'Fine', - 'Task age in days' => 'Anzianità del task in giorni', - 'Days in this column' => 'Giorni in questa colonna', - '%dd' => '%dg', - 'Add a new link' => 'Aggiungi una nuova relazione', - 'Do you really want to remove this link: "%s"?' => 'Vuoi davvero rimuovere la seguente relazione: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Vuoi davvero rimuovere questa relazione dal task #%d?', - 'Field required' => 'Campo necessario', - 'Link added successfully.' => 'Relazione aggiunta con successo.', - 'Link updated successfully.' => 'Relazione aggiornata con successo.', - 'Link removed successfully.' => 'Relazione rimossa con successo.', - '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', - 'Unable to create your link.' => 'Impossibile creare la relazione.', - 'Unable to update your link.' => 'Impossibile aggiornare la relazione.', - 'Unable to remove this link.' => 'Impossibile rimuovere la relazione.', - 'relates to' => 'si riferisce a', - 'blocks' => 'blocca', - 'is blocked by' => 'è bloccato da', - 'duplicates' => 'duplica', - 'is duplicated by' => 'è duplicato da', - 'is a child of' => 'è un figlio di', - 'is a parent of' => 'è un genitore di', - 'targets milestone' => 'punta alla milestone', - 'is a milestone of' => 'è una milestone di', - 'fixes' => 'sistema', - 'is fixed by' => 'è sistemato da', - 'This task' => 'Questo task', - // '<1h' => '', - // '%dh' => '', - 'Expand tasks' => 'Espandi i task', - 'Collapse tasks' => 'Minimizza i task', - 'Expand/collapse tasks' => 'Espandi/minimizza i task', - 'Close dialog box' => 'Chiudi la finestra di dialogo', - 'Submit a form' => 'Invia i dati', - 'Board view' => 'Vista bacheca', - 'Keyboard shortcuts' => 'Scorciatoie da tastiera', - 'Open board switcher' => 'Apri il selettore di bacheche', - 'Application' => 'Applicazione', - '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', - 'CAD - Canadian Dollar' => 'CAD - Dollari Canadesi', - 'CHF - Swiss Francs' => 'CHF - Franchi Svizzeri', - 'Custom Stylesheet' => 'Foglio di stile personalizzato', - // 'download' => '', - // 'EUR - Euro' => '', - 'GBP - British Pound' => 'GBP - Pound Inglesi', - 'INR - Indian Rupee' => 'INR - Rupie Indiani', - 'JPY - Japanese Yen' => 'JPY - Yen Giapponesi', - 'NZD - New Zealand Dollar' => 'NZD - Dollari della Nuova Zelanda', - 'RSD - Serbian dinar' => 'RSD - Dinar Serbi', - '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', - 'Move the task to another column when assignee is cleared' => 'Sposta il task in un\'altra colonna quando l\'assegnatario viene cancellato', - 'Source column' => 'Colonna sorgente', - 'Transitions' => 'Transizioni', - 'Executer' => 'Esecutore', - 'Time spent in the column' => 'Tempo trascorso nella colonna', - 'Task transitions' => 'Transizioni dei task', - 'Task transitions export' => 'Export delle transizioni dei task', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Questo report contiene tutti gli spotamenti di colonna per ogni task con le date, l\'utente ed il tempo trascorso per ogni transizione', - '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.', - 'Webhook URL' => 'URL Webhook', - '%s remove the assignee of the task %s' => '%s rimuove l\'assegnatario del task %s', - 'Enable Gravatar images' => 'Abilita immagini Gravatar', - 'Information' => 'Informazioni', - 'Check two factor authentication code' => 'Controlla il codice di autenticazione "two-factor"', - 'The two factor authentication code is not valid.' => 'Il codice di autenticazione "two-factor" non è valido', - 'The two factor authentication code is valid.' => 'Il codice di autenticazione "two-factor" è valido', - 'Code' => 'Codice', - 'Two factor authentication' => 'Autenticazione "two-factor"', - 'This QR code contains the key URI: ' => 'Questo QR code contiene l\'URI: ', - 'Check my code' => 'Controlla il mio codice', - 'Secret key: ' => 'Chiave privata:', - 'Test your device' => 'Testa il tuo dispositivo', - 'Assign a color when the task is moved to a specific column' => 'Assegna un colore quando il task viene spostato in una colonna specifica', - '%s via Kanboard' => '%s tramite Kanboard', - 'Burndown chart for "%s"' => 'Grafico Burndown per "%s"', - 'Burndown chart' => 'Grafico Burndown', - 'This chart show the task complexity over the time (Work Remaining).' => 'Questo grafico mostra la complessità dei task nel tempo (Lavoro residuo).', - 'Screenshot taken %s' => 'Schermata catturata %s', - 'Add a screenshot' => 'Aggiungi una schermata', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Cattura una schermata e premi CTRL+V o ⌘+V per incollarla qui.', - 'Screenshot uploaded successfully.' => 'Schermata caricata con successo.', - 'SEK - Swedish Krona' => 'SEK - Corona svedese', - 'Identifier' => 'Identificatore', - 'Disable two factor authentication' => 'Disabilita l\'autenticazione "two-factor"', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Vuoi davvero disabilitare l\'autenticazione "two-factor" per questo utente: "%s"?', - 'Edit link' => 'Modifica relazione', - 'Start to type task title...' => 'Inzia a digitare il titolo di un task...', - 'A task cannot be linked to itself' => 'Un task non può essere correlato a se stesso', - 'The exact same link already exists' => 'La stessa relazione risulta già esistente', - 'Recurrent task is scheduled to be generated' => 'Il task ricorrente è pianificato per essere generato', - 'Score' => 'Punteggio', - 'The identifier must be unique' => 'L\'identificatore deve essere univoco', - 'This linked task id doesn\'t exists' => 'L\'id del task correlato non esiste', - 'This value must be alphanumeric' => 'Questo valore deve essere alfanumerico', - 'Edit recurrence' => 'Modifica ricorrenza', - 'Generate recurrent task' => 'Genera task ricorrente', - 'Trigger to generate recurrent task' => 'Trigger per generare il task ricorrente', - 'Factor to calculate new due date' => 'Fattore numerico per calcolare la nuova data di scadenza', - 'Timeframe to calculate new due date' => 'Lasso temporale per calcolare la nuova data di scadenza', - 'Base date to calculate new due date' => 'Data di partenza per calcolare la nuova data di scadenza', - 'Action date' => 'Data di azione (action date)', - 'Base date to calculate new due date: ' => 'Data di base per calcolare la nuova data di scadenza: ', - 'This task has created this child task: ' => 'Questo task ha creato il seguente task figlio: ', - 'Day(s)' => 'Giorno/i', - 'Existing due date' => 'Data di scadenza esistente', - 'Factor to calculate new due date: ' => 'Fattore numerico per calcolare la nuova data di scadenza: ', - 'Month(s)' => 'Mese/i', - 'Recurrence' => 'Ricorrenza', - 'This task has been created by: ' => 'Questo task è stato creato da: ', - 'Recurrent task has been generated:' => 'Il task ricorrente è stato generato:', - 'Timeframe to calculate new due date: ' => 'Lasso temporale per calcolare la nuova data di scadenza: ', - 'Trigger to generate recurrent task: ' => 'Trigger per generare il task ricorrente: ', - 'When task is closed' => 'Quando un task è chiuso', - 'When task is moved from first column' => 'Quando un task è spostato dalla prima colonna', - 'When task is moved to last column' => 'Quando un task è spostato nell\'ultima colonna', - 'Year(s)' => 'Anno/i', - 'Calendar settings' => 'Impostazioni del calendario', - 'Project calendar view' => 'Vista di progetto a calendario', - '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', - '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', - 'iCal feed' => 'feed iCal', - 'Preferences' => 'Preferenze', - 'Security' => 'Sicurezza', - 'Two factor authentication disabled' => 'Two factor authentication disabilitata', - 'Two factor authentication enabled' => 'Two factor authentication abilitata', - 'Unable to update this user.' => 'Impossibile aggiornare questo utente.', - 'There is no user management for private projects.' => 'Non è prevista la gestione di utenti per i progetti privati.', - 'User that will receive the email' => 'Utente che riceverà l\'email', - 'Email subject' => 'Soggetto dell\'email', - 'Date' => 'Data', - 'Add a comment log when moving the task between columns' => 'Aggiungi un log quando si sposta un task tra colonne', - 'Move the task to another column when the category is changed' => 'Sposta il task in un\'altra colonna quando la categoria viene modificata', - 'Send a task by email to someone' => 'Invia un task via email a qualcuno', - 'Reopen a task' => 'Riapri un task', - 'Column change' => 'Cambio di colonna', - 'Position change' => 'Cambio di posizione', - 'Swimlane change' => 'Cambio di corsia', - 'Assignee change' => 'Cambio assegnatario', - '[%s] Overdue tasks' => '[%s] Task scaduti', - 'Notification' => 'Notifica', - '%s moved the task #%d to the first swimlane' => '%s ha spostato il task #%d nella prima corsia', - '%s moved the task #%d to the swimlane "%s"' => '%s ha spostato il task #%d nella corsia "%s"', - 'Swimlane' => 'Corsia', - // 'Gravatar' => '', - '%s moved the task %s to the first swimlane' => '%s ha spostato il task %s nella prima corsia', - '%s moved the task %s to the swimlane "%s"' => '%s ha spostato il task %s nella corsia %s', - 'This report contains all subtasks information for the given date range.' => 'Questo report contiente tutte le informazioni sui sotto-task nell\'arco temporale indicato.', - 'This report contains all tasks information for the given date range.' => 'Questo report contiente tutte le informazioni sui task nell\'arco temporale indicato.', - 'Project activities for %s' => 'Attività di progetto per %s', - 'view the board on Kanboard' => 'guarda la bacheca su Kanboard', - 'The task have been moved to the first swimlane' => 'Il task è stato spostato nella prima corsia', - 'The task have been moved to another swimlane:' => 'Il task è stato spostato in un\'altra corsia:', - 'New title: %s' => 'Nuovo titolo: %s', - 'The task is not assigned anymore' => 'Il task non è più assegnato a nessuno', - 'New assignee: %s' => 'Nuovo assegnatario: %s', - 'There is no category now' => 'Non è presente più nessuna categoria', - 'New category: %s' => 'Nuova categoria: %s', - 'New color: %s' => 'Nuovo colorei: %s', - 'New complexity: %d' => 'Nuova complessità: %d', - 'The due date have been removed' => 'La data di scadenza è stata rimossa', - 'There is no description anymore' => 'Non è presente più alcuna descrizione.', - 'Recurrence settings have been modified' => 'Le impostazioni di ricorrenza sono state modificate', - 'Time spent changed: %sh' => 'Tempo trascorso modificato: %sh', - 'Time estimated changed: %sh' => 'Tempo stimato modificato: %sh', - 'The field "%s" have been updated' => 'Il campo %s è stato aggiornato', - 'The description has been modified:' => 'La descrizione è stata modificata', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Vuoi veramente chiudere il task "%s" e i relativi sotto-task?', - 'I want to receive notifications for:' => 'Voglio ricevere le notifiche per:', - 'All tasks' => 'Tutti i task', - 'Only for tasks assigned to me' => 'Solo per i task assegnati a me', - 'Only for tasks created by me' => 'Solo per i task creati da me', - 'Only for tasks created by me and assigned to me' => 'Solo per i task creati da me e assegnati a me', - // '%%Y-%%m-%%d' => '', - 'Total for all columns' => 'Totale per tutte le colonne', - 'You need at least 2 days of data to show the chart.' => 'Hai bisogno di almeno 2 giorni di dati per mostrare il grafico.', - // '<15m' => '', - // '<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', - 'Reset filters' => 'Annulla filtri', - 'My tasks due tomorrow' => 'I miei task da completare per domani', - 'Tasks due today' => 'Task da completare oggi', - 'Tasks due tomorrow' => 'Task da completare per domani', - 'Tasks due yesterday' => 'Task da completare ieri', - 'Closed tasks' => 'Task chiusi', - 'Open tasks' => 'Task aperti', - 'Not assigned' => 'Non assegnato', - 'View advanced search syntax' => 'Visualizza la sintassi di ricerca avanzata', - 'Overview' => 'Panoramica', - 'Board/Calendar/List view' => 'Vista Bacheca/Calendario/Lista', - 'Switch to the board view' => 'Passa alla vista "bacheca"', - 'Switch to the calendar view' => 'Passa alla vista "calendario"', - 'Switch to the list view' => 'Passa alla vista "elenco"', - 'Go to the search/filter box' => 'Vai alla casella di ricerca/filtro', - 'There is no activity yet.' => 'Non è presente ancora nessuna attività.', - 'No tasks found.' => 'Nessun task trovato.', - 'Keyboard shortcut: "%s"' => 'Scorciatoia da tastiera: "%s"', - 'List' => 'Lista', - 'Filter' => 'Filtro', - 'Advanced search' => 'Ricerca avanzata', - 'Example of query: ' => 'Esempio di query: ', - 'Search by project: ' => 'Ricerca per progetto: ', - 'Search by column: ' => 'Ricerca per colonna: ', - 'Search by assignee: ' => 'Ricerca per assegnatario: ', - 'Search by color: ' => 'Ricerca per colore: ', - 'Search by category: ' => 'Ricerca per categoria: ', - 'Search by description: ' => 'Ricerca per descrizione: ', - 'Search by due date: ' => 'Ricerca per data di scadenza: ', - 'Lead and Cycle time for "%s"' => 'Tempo di consegna (Lead Time) e lavorazione (Cycle Time) per "%s"', - 'Average time spent into each column for "%s"' => 'Tempo medio trascorso in ogni colonna per "%s"', - 'Average time spent into each column' => 'Tempo medio trascorso in ogni colonna', - 'Average time spent' => 'Tempo medio trascorso', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Questo grafico mostra il tempo medio trascorso in ogni colonna per gli ultimi %d task.', - 'Average Lead and Cycle time' => 'Tempo medio di consegna (Lead Time) e lavorazione (Cycle Time)', - 'Average lead time: ' => 'Tempo medio di consegna (Lead Time): ', - 'Average cycle time: ' => 'Tempo medio di lavorazione (Cycle Time): ', - 'Cycle Time' => 'Tempo di lavorazione (Cycle Time)', - 'Lead Time' => 'Tempo di consegna (Lead Time)', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Questo grafico mostra i tempi medi di consegna (Lead Time) e lavorazione (Cycle Time) per gli ultimi %d task.', - 'Average time into each column' => 'Tempo medio in ogni colonna', - 'Lead and cycle time' => 'Tempo di consegna e lavorazione', - 'Lead time: ' => 'Tempo di consegna (Lead Time): ', - '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.', - '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', - '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.', - 'Trigger automatically subtask time tracking' => 'Attiva automaticamente il time-tracking per i sotto-task', - 'Include closed tasks in the cumulative flow diagram' => 'Includi i task chiusi nel diagramma di flusso cumulativo', - 'Current swimlane: %s' => 'Corsia attuale: %s', - 'Current column: %s' => 'Colonna attuale: %s', - 'Current category: %s' => 'Categoria attuale: %s', - 'no category' => 'nessuna categoria', - 'Current assignee: %s' => 'Assegnatario attuale: %s', - 'not assigned' => 'non assegnato', - 'Author:' => 'Autore', - 'contributors' => 'contributori', - 'License:' => 'Licenza:', - 'License' => 'Licenza', - 'Enter the text below' => 'Inserisci il testo qui sotto', - 'Gantt chart for %s' => 'Grafico Gantt per %s', - 'Sort by position' => 'Ordina per posizione', - 'Sort by date' => 'Ordina per data', - '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 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', - 'People who are project members' => 'Persone che sono membri di progetto', - 'NOK - Norwegian Krone' => 'NOK - Corone norvegesi', - 'Show this column' => 'Mostra questa colonna', - 'Hide this column' => 'Nascondi questa colonna', - 'open file' => 'apri file', - 'End date' => 'Data di fine', - 'Users overview' => 'Panoramica utenti', - 'Members' => 'Membri', - 'Shared project' => 'Progetto condiviso', - 'Project managers' => 'Manager di progetto', - 'Gantt chart for all projects' => 'Grafico Gantt per tutti i progetti', - 'Projects list' => 'Elenco progetti', - '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.', - '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', - // 'Milestone' => '', - 'Documentation: %s' => 'Documentazione: %s', - 'Switch to the Gantt chart view' => 'Passa alla vista Grafico Gantt', - 'Reset the search/filter box' => 'Resetta la riceca/filtro', - 'Documentation' => 'Documentazione', - 'Table of contents' => 'Indice dei contenuti', - 'Gantt' => 'Gantt', - 'Author' => 'Autore', - 'Version' => 'Versione', - 'Plugins' => 'Plugin', - 'There is no plugin loaded.' => 'Nessun plugin è stato caricato.', - 'Set maximum column height' => 'Imposta l\'altezza massima della colonna', - 'Remove maximum column height' => 'Rimuovi l\'altezza massima della colonna', - 'My notifications' => 'Le mie notifiche', - 'Custom filters' => 'Filtri personalizzati', - 'Your custom filter have been created successfully.' => 'Il filtro personalizzato è stato creato con successo.', - 'Unable to create your custom filter.' => 'Impossibile creare il filtro personalizzato.', - 'Custom filter removed successfully.' => 'Filtro personalizzato rimosso con successo.', - 'Unable to remove this custom filter.' => 'Impossibile rimuovere questo filtro personalizzato', - 'Edit custom filter' => 'Modifica il filtro personalizzato', - 'Your custom filter have been updated successfully.' => 'Il filtro personalizzato è stato aggiornato con successo.', - 'Unable to update custom filter.' => 'Impossibile aggiornare il filtro personalizzato.', - // 'Web' => '', - 'New attachment on task #%d: %s' => 'Nuovo allegato nel task #%d: %s', - 'New comment on task #%d' => 'Nuovo commento nel task #%d', - 'Comment updated on task #%d' => 'Commento aggiornato nel task #%d', - 'New subtask on task #%d' => 'Nuovo sotto-task nel task #%d', - 'Subtask updated on task #%d' => 'Sotto-task aggiornato nel task #%d', - 'New task #%d: %s' => 'Nuovo task #%d: %s', - 'Task updated #%d' => 'Task #%d aggiornato', - 'Task #%d closed' => 'Task #%d chiuso', - 'Task #%d opened' => 'Task #%d aperto', - 'Column changed for task #%d' => 'Colonna modificata per il task #%d', - 'New position for task #%d' => 'Nuova posizione per il task #%d', - 'Swimlane changed for task #%d' => 'Corsia modificata per il task #%d', - 'Assignee changed on task #%d' => 'Assegnatario modificato per il task #%d', - '%d overdue tasks' => '%d task scaduti', - 'Task #%d is overdue' => 'Il task #%d è scaduto', - 'No new notifications.' => 'Nessuna nuova notifica.', - 'Mark all as read' => 'Segna tutti come letti', - 'Mark as read' => 'Segna come letto', - 'Total number of tasks in this column across all swimlanes' => 'Numero totale di task in questa colonna per tutte le corsie', - 'Collapse swimlane' => 'Minimizza corsia', - 'Expand swimlane' => 'Espandi corsia', - 'Add a new filter' => 'Aggiungi un nuovo filtro', - 'Share with all project members' => 'Condividi con tutti i membri del progetto', - 'Shared' => 'Condiviso', - '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!', - 'Import users from CSV file' => 'Importa utenti da file CSV', - '%d user(s) have been imported successfully.' => '%d utenti importati con successo.', - 'Comma' => 'Virgola', - 'Semi-colon' => 'Punto e virgola', - 'Tab' => 'Tabulazione', - 'Vertical bar' => 'Barra verticale', - 'Double Quote' => 'Apice singolo', - 'Single Quote' => 'Doppio apice', - '%s attached a file to the task #%d' => '%s ha allegato un file al task #%d', - 'There is no column or swimlane activated in your project!' => 'Non ci sono colonne o corsie attive all\'interno del tuo progetto!', - 'Append filter (instead of replacement)' => 'Aggiungi filtro (anzichè sostituirlo)', - 'Append/Replace' => 'Aggiungi/Sostituisci', - 'Append' => 'Aggiungi', - 'Replace' => 'Sostituisci', - 'Import' => 'Importa', - 'change sorting' => 'cambia ordinamento', - 'Tasks Importation' => 'Importazione task', - 'Delimiter' => 'Delimitatore', - // 'Enclosure' => '', - 'CSV File' => 'File CSV', - 'Instructions' => 'Istruzioni', - 'Your file must use the predefined CSV format' => 'Il file deve rispettare il formato CSV predefinito', - 'Your file must be encoded in UTF-8' => 'Il file deve essere codificato in formato UTF-8', - 'The first row must be the header' => 'La prima riga deve contenere l\'intestazione', - 'Duplicates are not verified for you' => 'Le righe duplicate non verranno controllate', - 'The due date must use the ISO format: YYYY-MM-DD' => 'La data di scadenza deve usare il formato ISO: YYYY-MM-DD', - 'Download CSV template' => 'Scarica il template CSV', - 'No external integration registered.' => 'Nessuna integrazione esterna presente.', - 'Duplicates are not imported' => 'I duplicati non veranno importati', - 'Usernames must be lowercase and unique' => 'I nomi utente devono essere in minuscolo e univoci', - 'Passwords will be encrypted if present' => 'Se presenti, le password verranno criptate', - '%s attached a new file to the task %s' => '%s ha allegato un nuovo file al task %s', - 'Link type' => 'Tipo di link', - 'Assign automatically a category based on a link' => 'Assegna automaticamente una categoria sulla base di una relazione', - 'BAM - Konvertible Mark' => 'BAM - Marco bosniaco', - 'Assignee Username' => 'Nome utente dell\'assegnatario', - 'Assignee Name' => 'Nome dell\'assegnatario', - 'Groups' => 'Gruppi', - 'Members of %s' => 'Membri di %s', - 'New group' => 'Nuovo gruppo', - 'Group created successfully.' => 'Gruppo creato con successo', - 'Unable to create your group.' => 'Impossibile creare il gruppo', - 'Edit group' => 'Modifica gruppo', - 'Group updated successfully.' => 'Gruppo aggiornato con successo.', - 'Unable to update your group.' => 'Impossibile aggiornare il gruppo', - 'Add group member to "%s"' => 'Aggiungi un membro al gruppo "%s"', - 'Group member added successfully.' => 'Membro del gruppo aggiunto con successo.', - 'Unable to add group member.' => 'Impossibile aggiungere un membro del gruppo', - 'Remove user from group "%s"' => 'Rimuovi utente dal gruppo "%s"', - 'User removed successfully from this group.' => 'Utente rimosso dal gruppo con successo.', - 'Unable to remove this user from the group.' => 'Impossibile rimuovere l\'utentei dal gruppo.', - 'Remove group' => 'Rimuovi gruppo', - 'Group removed successfully.' => 'Gruppo rimosso con successo.', - 'Unable to remove this group.' => 'Impossibile rimuovere questo gruppo.', - 'Project Permissions' => 'Permessi del progetto', - // 'Manager' => '', - 'Project Manager' => 'Manager del progetto', - 'Project Member' => 'Membro del progetto', - 'Project Viewer' => 'Osservatore del progetto', - 'Your account is locked for %d minutes' => 'Il tuo account è bloccato per %d minuti', - 'Invalid captcha' => 'Captcha non valido', - 'The name must be unique' => 'Il nome deve essere univoco', - 'View all groups' => 'Visualiza tutti i gruppi', - 'View group members' => 'Visualizza i membri del gruppo', - 'There is no user available.' => 'Nessun utente disponibile.', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Vuoi davvero rimuovere l\'utente "%s" dal gruppo "%s"?', - 'There is no group.' => 'Nessun gruppo presente', - 'External Id' => 'Id esterno', - 'Add group member' => 'Aggiungi un membro del gruppo', - 'Do you really want to remove this group: "%s"?' => 'Vuoi davvero rimuovere questo gruppo: "%s"?', - 'There is no user in this group.' => 'Nessun utente in questo gruppo.', - 'Remove this user' => 'Rimuovi questo utente', - 'Permissions' => 'Permessi', - 'Allowed Users' => 'Utenti autorizzati', - 'No user have been allowed specifically.' => 'Nessun utente è stato esplicitamente autorizzato.', - 'Role' => 'Ruolo', - 'Enter user name...' => 'Inserisci il nome utente...', - 'Allowed Groups' => 'Gruppi autorizzati', - 'No group have been allowed specifically.' => 'Nessun gruppo è stato esplicitamente autorizzato.', - 'Group' => 'Gruppo', - 'Group Name' => 'Nome del gruppo', - 'Enter group name...' => 'Inserisci il nome del gruppo...', - 'Role:' => 'Ruolo:', - 'Project members' => 'Membri di progetto', - 'Compare hours for "%s"' => 'Confronta le ore per "%s"', - '%s mentioned you in the task #%d' => '%s ti ha menzionato nel task #%d', - '%s mentioned you in a comment on the task #%d' => '%s ti ha menzionato in un commento del task #%d', - 'You were mentioned in the task #%d' => 'Sei stato menzionato nel task #%d', - 'You were mentioned in a comment on the task #%d' => 'Sei stato menzionato in un commento del task #%d', - 'Mentioned' => 'Menzionato', - 'Compare Estimated Time vs Actual Time' => 'Confronta il Tempo Stimato vs Tempo Effettivo', - 'Estimated hours: ' => 'Ore stimate: ', - 'Actual hours: ' => 'Ore effettive: ', - 'Hours Spent' => 'Ore impiegate', - 'Hours Estimated' => 'Ore stimate', - 'Estimated Time' => 'Tempo stimato', - 'Actual Time' => 'Tempo effettivo', - 'Estimated vs actual time' => 'Tempo stimato vs Tempo effettivo', - 'RUB - Russian Ruble' => 'RUB - Rublo russo', - 'Assign the task to the person who does the action when the column is changed' => 'Assegna il task alla persona che esegue l\'azione quando la colonna viene modificata', - 'Close a task in a specific column' => 'Chiudi un task in una specifica colonna', - 'Time-based One-time Password Algorithm' => 'Algoritmo per la Time-based One-time Password', - // 'Two-Factor Provider: ' => '', - 'Disable two-factor authentication' => 'Disabilita l\'autenticazione "two-factor"', - 'Enable two-factor authentication' => 'Abilita l\'autenticazione "two-factor"', - 'There is no integration registered at the moment.' => 'Nessuna integrazione disponibile al momento.', - 'Password Reset for Kanboard' => 'Reimposta password per Kanboard', - 'Forgot password?' => 'Password dimenticata?', - 'Enable "Forget Password"' => 'Abilita funzione "Password dimenticata"', - 'Password Reset' => 'Reimposta password', - 'New password' => 'Nuova password', - 'Change Password' => 'Cambia password', - 'To reset your password click on this link:' => 'Per reimpostare la tua password clicca su questo link:', - 'Last Password Reset' => 'Ultimo cambio password', - 'The password has never been reinitialized.' => 'La password non è mai stata reimpostata.', - 'Creation' => 'Creazione', - 'Expiration' => 'Scadenza', - 'Password reset history' => 'Storico cambio password', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Tutti i task della colonna "%s" e della corsia "%s" sono stati chiusi con successo.', - 'Do you really want to close all tasks of this column?' => 'Vuoi davvero chiudere tutti i task di questa colonna?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d task della colonna "%s" e della corsia "%s" saranno chiusi.', - 'Close all tasks of this column' => 'Chiudi tutti i task di questa colonna', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nessun plugin ha caricato un metodo di notifica di progetto. Puoi tuttavia configurare le notifiche personali dal tuo profilo utente.', - 'My dashboard' => 'La mia bacheca', - 'My profile' => 'Il mio profilo', - '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à', - 'Task priority' => 'Priorità del task', - 'General' => 'Generale', - 'Dates' => 'Date', - 'Default priority' => 'Priorità predefinita', - 'Lowest priority' => 'Priorità minima', - 'Highest priority' => 'Priorità massima', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Se imposti a zero la priorità massima e minima, questa funzionalità sarà disabilitata.', - 'Close a task when there is no activity' => 'Chiudi un task quando non c\'è nessuna attività', - 'Duration in days' => 'Durata in giorni', - 'Send email when there is no activity on a task' => 'Invia un\'email quando non c\'è attività sul task', - 'Unable to fetch link information.' => 'Impossibile recuperare informazioni sul link.', - 'Daily background job for tasks' => 'Job giornaliero in background per i task', - // 'Auto' => '', - 'Related' => 'Correlato', - 'Attachment' => 'Allegato', - 'Title not found' => 'Titolo non trovato', - 'Web Link' => 'Link Web', - 'External links' => 'Link esterni', - 'Add external link' => 'Aggiungi link esterno', - 'Type' => 'Tipo', - 'Dependency' => 'Dipendenza', - 'Add internal link' => 'Aggiungi link interno', - 'Add a new external link' => 'Aggiungi un nuovo link esterno', - 'Edit external link' => 'Modifica link esterno', - 'External link' => 'Link esterno', - 'Copy and paste your link here...' => 'Copia e incolla il tuo link qui...', - // 'URL' => '', - 'Internal links' => 'Link interni', - 'Assign to me' => 'Assegna a me', - 'Me' => 'Me stesso', - 'Do not duplicate anything' => 'Non duplicare nulla', - 'Projects management' => 'Gestione progetti', - 'Users management' => 'Gestione utenti', - 'Groups management' => 'Gestione gruppi', - 'Create from another project' => 'Crea da un\'altro progetto', - 'open' => 'aperto', - 'closed' => 'chiuso', - 'Priority:' => 'Priorità:', - 'Reference:' => 'Riferimento:', - 'Complexity:' => 'Complessità:', - 'Swimlane:' => 'Corsia:', - 'Column:' => 'Colonna:', - 'Position:' => 'Posizione:', - 'Creator:' => 'Creatore:', - 'Time estimated:' => 'Tempo stimato:', - '%s hours' => '%s ore', - 'Time spent:' => 'Tempo trascorso:', - 'Created:' => 'Creato:', - 'Modified:' => 'Modificato:', - 'Completed:' => 'Completato:', - 'Started:' => 'Iniziato:', - 'Moved:' => 'Spostato:', - // 'Task #%d' => '', - 'Date and time format' => 'Formato data e ora', - 'Time format' => 'Formato ora', - 'Start date: ' => 'Data di inizio: ', - 'End date: ' => 'Data di fine: ', - 'New due date: ' => 'Nuova data di scadenza: ', - 'Start date changed: ' => 'Data di inizio cambiata: ', - 'Disable private projects' => 'Disabilita progetti privati', - 'Do you really want to remove this custom filter: "%s"?' => 'Vuoi davvero rimuovere questo filtro personalizato: "%s"?', - 'Remove a custom filter' => 'Rimuovi un filtro personalizzato', - 'User activated successfully.' => 'Utente attivato con successo.', - 'Unable to enable this user.' => 'Impossibile abilitare questo utente.', - 'User disabled successfully.' => 'Utente disabilitato con successo.', - 'Unable to disable this user.' => 'Impossibile disabilitare questo utente.', - 'All files have been uploaded successfully.' => 'Tutti i file sono stati caricati con successo.', - 'View uploaded files' => 'Visualizza i file caricati', - 'The maximum allowed file size is %sB.' => 'La dimensione massima consentita del file è %sB.', - 'Choose files again' => 'Seleziona nuovamente i file', - 'Drag and drop your files here' => 'Trascina i tuoi file qui', - 'choose files' => 'seleziona i file', - 'View profile' => 'Guarda il profilo', - // 'Two Factor' => '', - 'Disable user' => 'Disabilita utente', - 'Do you really want to disable this user: "%s"?' => 'Vuoi davvero disabilitare questo utente: "%s"?', - 'Enable user' => 'Abilita utente', - 'Do you really want to enable this user: "%s"?' => 'Vuoi davvero abilitare questo utente: "%s"?', - 'Download' => 'Scarica', - 'Uploaded: %s' => 'Caricato: %s', - 'Size: %s' => 'Dimensione: %s', - 'Uploaded by %s' => 'Caricato da %s', - 'Filename' => 'Nome del file', - 'Size' => 'Dimensione', - 'Column created successfully.' => 'Colonna creata con successo.', - 'Another column with the same name exists in the project' => 'Un\'altra colonna con lo stesso nome è già esistente in questo progetto', - 'Default filters' => 'Filtri predefiniti', - 'Your board doesn\'t have any columns!' => 'La tua bacheca non ha nessuna colonna!', - 'Change column position' => 'Modifica la posizione della colonna', - 'Switch to the project overview' => 'Passa alla panoramica di progetto', - 'User filters' => 'Filtri utente', - 'Category filters' => 'Filtri di categorie', - 'Upload a file' => 'Carica un file', - 'View file' => 'Visualizza file', - 'Last activity' => 'Attività recente', - 'Change subtask position' => 'Cambia la posizione del sotto-task', - 'This value must be greater than %d' => 'Questo valore deve essere magiore di %d', - 'Another swimlane with the same name exists in the project' => 'Un\'altra corsia con lo stesso nome è già esistente in questo progetto', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Esempio: http://example.kanboard.net/ (usato per generare URL assolute)', - 'Actions duplicated successfully.' => 'Azioni duplicate con successo.', - 'Unable to duplicate actions.' => 'Impossibile duplicare le azioni.', - 'Add a new action' => 'Aggiungi una nuova azione', - 'Import from another project' => 'Importa da un altro progetto', - 'There is no action at the moment.' => 'Nessuna azione disponibile al momento.', - 'Import actions from another project' => 'Importa azioni da un altro progetto', - 'There is no available project.' => 'Nessun progetto disponibile.', - 'Local File' => 'File locale', - 'Configuration' => 'Configurazione', - 'PHP version:' => 'Versione PHP:', - // 'PHP SAPI:' => '', - 'OS version:' => 'Versione OS:', - 'Database version:' => 'Versione database:', - // 'Browser:' => '', - 'Task view' => 'Vista dei task', - 'Edit task' => 'Modifica task', - 'Edit description' => 'Modifica descrizione', - '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', - // 'Avatar' => '', - 'Upload my avatar image' => 'Carica l\'immagine del mio avatar', - 'Remove my image' => 'Rimuovi la mia immagine', - 'The OAuth2 state parameter is invalid' => 'Il parametro di stato OAuth2 non è valido.', - 'User not found.' => 'Utente non trovato.', - 'Search in activity stream' => 'Ricerca nel mio flusso attività', - 'My activities' => 'Le mie attività', - 'Activity until yesterday' => 'Attività ad oggi', - 'Activity until today' => 'Attività fino a ieri', - 'Search by creator: ' => 'Ricerca per creatore: ', - 'Search by creation date: ' => 'Ricerca per data di creazione: ', - 'Search by task status: ' => 'Ricerca per stato del task: ', - 'Search by task title: ' => 'Ricerca per titolo del task: ', - 'Activity stream search' => 'Ricerca nel flusso attività', - 'Projects where "%s" is manager' => 'Progetti all\'interno dei quali "%s" è manager', - 'Projects where "%s" is member' => 'Progetti all\'interno dei quali "%s" è membro', - 'Open tasks assigned to "%s"' => 'Task aperti assegnati a "%s"', - 'Closed tasks assigned to "%s"' => 'Task chiusi assegnati a "%s"', - 'Assign automatically a color based on a priority' => 'Assegna automaticamente un colore in base alla priorità', - 'Overdue tasks for the project(s) "%s"' => 'Task scaduti per il progetto "%s"', - 'Upload files' => 'Carica file', - 'Installed Plugins' => 'Plugin installati', - 'Plugin Directory' => 'Directory dei plugin', - 'Plugin installed successfully.' => 'Plugin installato con successo.', - 'Plugin updated successfully.' => 'Plugin aggiornato con successo.', - 'Plugin removed successfully.' => 'Plugin rimosso con successo.', - 'Subtask converted to task successfully.' => 'Sotto-task converito in task con successo.', - 'Unable to convert the subtask.' => 'Impossibile convertire il sotto-task.', - 'Unable to extract plugin archive.' => 'Impossibile estrarre l\' archivio del plugin.', - 'Plugin not found.' => 'Plugin non trovato.', - 'You don\'t have the permission to remove this plugin.' => 'Non hai i permessi per rimuovere questo plugin.', - 'Unable to download plugin archive.' => 'Impossibile scaricare l\'archivo del plugin', - 'Unable to write temporary file for plugin.' => 'Impossibile scrivere il file temporaneo per il plugin.', - 'Unable to open plugin archive.' => 'Impossibile aprire l\'archivio del plugin.', - 'There is no file in the plugin archive.' => 'Non ci sono file nell\' archivio del plugin.', - 'Create tasks in bulk' => 'Creazione massiva di task', - 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'La tua installazione Kanboard non è configurata per installare plugin tramite l\'interfaccia utente.', - 'There is no plugin available.' => 'Non ci sono plugin disponibili.', - 'Install' => 'Installa', - 'Update' => 'Aggiorna', - 'Up to date' => 'Aggiornato', - 'Not available' => 'Non disponibile', - 'Remove plugin' => 'Disinstalla plugin', - 'Do you really want to remove this plugin: "%s"?' => 'Vuoi davvero rimuovere questo plugin: "%s"?', - 'Uninstall' => 'Disinstalla', - 'Listing' => 'Elenco', - 'Metadata' => 'Metadati', - 'Manage projects' => 'Gestione progetti', - 'Convert to task' => 'Converti in task', - 'Convert sub-task to task' => 'Converti il sotto-task in task', - 'Do you really want to convert this sub-task to a task?' => 'Vuoi davvero convertire questo sotto-task in un task?', - 'My task title' => 'Titolo del mio task', - 'Enter one task by line.' => 'Inserisci un task per ogni riga.', - 'Number of failed login:' => 'Numero di login falliti:', - 'Account locked until:' => 'Account bloccato fino al:', - 'Email settings' => 'Impostazioni Email', - 'Email sender address' => 'Indirizzo Email mittente', - 'Email transport' => 'Trasporto Email', - // 'Webhook token' => '', - 'Imports' => 'Importa', - // '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' => '', -); diff --git a/sources/app/Locale/ja_JP/translations.php b/sources/app/Locale/ja_JP/translations.php deleted file mode 100644 index 692afb7..0000000 --- a/sources/app/Locale/ja_JP/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => 'なし', - 'edit' => '変更', - 'Edit' => '変更', - 'remove' => '削除する', - 'Remove' => '削除する', - 'Yes' => 'はい', - 'No' => 'いいえ', - 'cancel' => 'キャンセル', - 'or' => 'または', - 'Yellow' => 'イエロー', - 'Blue' => 'ブルー', - 'Green' => 'グリーン', - 'Purple' => 'パープル', - 'Red' => 'レッド', - 'Orange' => 'オレンジ', - 'Grey' => 'グレー', - // 'Brown' => '', - // 'Deep Orange' => '', - // 'Dark Grey' => '', - // 'Pink' => '', - // 'Teal' => '', - // 'Cyan' => '', - // 'Lime' => '', - // 'Light Green' => '', - // 'Amber' => '', - 'Save' => '保存', - 'Login' => 'ログイン', - 'Official website:' => '公式 Web サイト:', - 'Unassigned' => '担当なし', - 'View this task' => 'このタクスを見る', - 'Remove user' => 'ユーザの削除', - 'Do you really want to remove this user: "%s"?' => 'ユーザ「%s」を本当に削除しますか?', - 'All users' => 'すべてのユーザ', - 'Username' => 'ユーザ名', - 'Password' => 'パスワード', - 'Administrator' => '管理者', - 'Sign in' => 'ログイン', - 'Users' => 'ユーザ', - 'No user' => 'ユーザがいません', - 'Forbidden' => 'アクセス拒否', - 'Access Forbidden' => 'アクセスが拒否されました', - 'Edit user' => 'ユーザを変更する', - 'Logout' => 'ログアウト', - 'Bad username or password' => 'ユーザ名またはパスワードが違います。', - 'Edit project' => 'プロジェクトを変更する', - 'Name' => '名前', - 'Projects' => 'プロジェクト', - 'No project' => 'プロジェクトがありません', - 'Project' => 'プロジェクト', - 'Status' => 'ステータス', - 'Tasks' => 'タスク', - 'Board' => 'ボード', - 'Actions' => 'アクション', - 'Inactive' => '無効', - 'Active' => '有効', - '%d tasks on the board' => '%d 個のタスク', - '%d tasks in total' => '合計 %d 個のタスク', - 'Unable to update this board.' => 'ボードを更新できませんでした', - 'Edit board' => 'ボードを変更する', - 'Disable' => '無効にする', - 'Enable' => '有効にする', - 'New project' => 'プロジェクトを作る', - 'Do you really want to remove this project: "%s"?' => 'プロジェクト「%s」を本当に削除しますか?', - 'Remove project' => 'プロジェクトの削除', - 'Edit the board for "%s"' => 'ボード「%s」を変更する', - 'All projects' => 'すべてのプロジェクト', - 'Add a new column' => 'カラムの追加', - 'Title' => 'タイトル', - 'Assigned to %s' => '%sが担当', - 'Remove a column' => 'カラムの削除', - 'Remove a column from a board' => 'ボードからカラムの削除', - 'Unable to remove this column.' => 'カラムを削除できませんでした。', - 'Do you really want to remove this column: "%s"?' => 'カラム「%s」を削除しますか?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'この操作はこのカラムに割当てられた『全てのタスクを削除』します!', - 'Settings' => '設定', - 'Application settings' => 'アプリケーションの設定', - 'Language' => '言語', - 'Webhook token:' => 'Webhook トークン:', - 'API token:' => 'API トークン:', - 'Database size:' => 'データベースのサイズ:', - 'Download the database' => 'データベースのダウンロード', - 'Optimize the database' => 'データベースの最適化', - '(VACUUM command)' => '(VACUUM コマンド)', - '(Gzip compressed Sqlite file)' => '(GZip コマンドで圧縮された Sqlite ファイル)', - 'Close a task' => 'タスクをクロースする', - 'Edit a task' => 'タスクを変更する', - 'Column' => 'カラム', - 'Color' => '色', - 'Assignee' => '担当', - 'Create another task' => '続けて別のタスクを追加する', - 'New task' => 'タスクを追加する', - 'Open a task' => 'タスクをオープンする', - 'Do you really want to open this task: "%s"?' => 'タスク「%s」をオープンしますか?', - 'Back to the board' => 'ボードに戻る', - 'There is nobody assigned' => '担当者がいません', - 'Column on the board:' => 'カラム: ', - 'Close this task' => 'タスクをクローズする', - 'Open this task' => 'タスクをオープンする', - 'There is no description.' => '説明がありません', - 'Add a new task' => 'タスクを追加する', - 'The username is required' => 'ユーザ名が必要です', - 'The maximum length is %d characters' => '最大 %d 文字です', - 'The minimum length is %d characters' => '最小 %d 文字必要です', - 'The password is required' => 'パスワードが必要です', - 'This value must be an integer' => '整数で入力してください', - 'The username must be unique' => 'ユーザ名がすでに使用されています', - 'The user id is required' => 'ユーザ ID が必要です', - 'Passwords don\'t match' => 'パスワードが一致しません', - 'The confirmation is required' => '確認用のパスワードを入力してください', - 'The project is required' => 'プロジェクトが必要です', - 'The id is required' => 'ID が必要です', - 'The project id is required' => 'プロジェクト ID が必要です', - 'The project name is required' => 'プロジェクト名が必要です', - 'The title is required' => 'タイトルが必要です', - 'Settings saved successfully.' => '設定を保存しました。', - 'Unable to save your settings.' => '設定の保存に失敗しました。', - 'Database optimization done.' => 'データベースの最適化が終わりました。', - 'Your project have been created successfully.' => 'プロジェクトを作成しました。', - 'Unable to create your project.' => 'プロジェクトの作成に失敗しました。', - 'Project updated successfully.' => 'プロジェクトを更新しました。', - 'Unable to update this project.' => 'プロジェクトの更新に失敗しました。', - 'Unable to remove this project.' => 'プロジェクトの削除に失敗しました。', - 'Project removed successfully.' => 'プロジェクトを削除しました。', - 'Project activated successfully.' => 'プロジェクトを有効にしました。', - 'Unable to activate this project.' => 'プロジェクトの有効にできませんでした。', - 'Project disabled successfully.' => 'プロジェクトを無効にしました。', - 'Unable to disable this project.' => 'プロジェクトの無効にできませんでした。', - 'Unable to open this task.' => 'タスクのオープンに失敗しました。', - 'Task opened successfully.' => 'タスクをオープンしました。', - 'Unable to close this task.' => 'タスクのクローズに失敗しました。', - 'Task closed successfully.' => 'タスクをクローズしました。', - 'Unable to update your task.' => 'タスクの更新に失敗しました。', - 'Task updated successfully.' => 'タスクを更新しました。', - 'Unable to create your task.' => 'タスクの追加に失敗しました。', - 'Task created successfully.' => 'タスクを追加しました。', - 'User created successfully.' => 'ユーザを追加しました。', - 'Unable to create your user.' => 'ユーザの追加に失敗しました。', - 'User updated successfully.' => 'ユーザを更新しました。', - 'Unable to update your user.' => 'ユーザの更新に失敗しました。', - 'User removed successfully.' => 'ユーザを削除しました。', - 'Unable to remove this user.' => 'ユーザの削除に失敗しました。', - 'Board updated successfully.' => 'ボードを更新しました。', - 'Ready' => 'Ready', - 'Backlog' => 'Backlog', - 'Work in progress' => 'Work in progress', - 'Done' => 'Done', - 'Application version:' => 'アプリケーションのバージョン:', - 'Id' => 'ID', - '%d closed tasks' => '%d 個のクローズしたタスク', - 'No task for this project' => 'このプロジェクトにタスクがありません', - 'Public link' => '公開アクセス用リンク', - 'Timezone' => 'タイムゾーン', - 'Sorry, I didn\'t find this information in my database!' => 'データベース上で情報が見つかりませんでした!', - 'Page not found' => 'ページが見つかりません', - 'Complexity' => '複雑さ', - 'Task limit' => 'タスク数制限', - 'Task count' => 'タスク数', - 'User' => 'ユーザ', - 'Comments' => 'コメント', - 'Leave a comment' => 'コメントを書く', - 'Comment is required' => 'コメントを入力してください', - 'Leave a description' => '説明を書く', - 'Comment added successfully.' => 'コメントを追加しました。', - 'Unable to create your comment.' => 'コメントの追加に失敗しました。', - 'Due Date' => '期限', - 'Invalid date' => '日付が無効です', - 'Automatic actions' => '自動アクションを管理する', - 'Your automatic action have been created successfully.' => '自動アクションを作成しました。', - 'Unable to create your automatic action.' => '自動アクションの作成に失敗しました。', - 'Remove an action' => '自動アクションの削除', - 'Unable to remove this action.' => '自動アクションの削除に失敗しました。', - 'Action removed successfully.' => '自動アクションの削除に成功しました。', - 'Automatic actions for the project "%s"' => 'プロジェクト「%s」の自動アクション', - 'Add an action' => '自動アクションの追加', - 'Event name' => 'イベント名', - 'Action name' => 'アクション名', - 'Action parameters' => 'アクションのパラメーター', - 'Action' => 'アクション', - 'Event' => 'イベント', - 'When the selected event occurs execute the corresponding action.' => '選択されたイベントが発生した時、対応するアクションを実行する。', - 'Next step' => '次のステップ', - 'Define action parameters' => 'アクションのパラメーター', - 'Do you really want to remove this action: "%s"?' => '自動アクション「%s」を削除しますか?', - 'Remove an automatic action' => '自動アクションの削除', - 'Assign the task to a specific user' => 'タスクの担当者を割り当てる', - 'Assign the task to the person who does the action' => 'アクションを起こしたユーザを担当者にする', - 'Duplicate the task to another project' => '別のプロジェクトにタスクを複製する', - 'Move a task to another column' => 'タスクを別のカラムに移動する', - 'Task modification' => 'タスクの変更', - 'Task creation' => 'タスクを作る', - 'Closing a task' => 'タスクをクローズする', - 'Assign a color to a specific user' => '色をユーザに割り当てる', - 'Column title' => 'カラムのタイトル', - 'Position' => '位置', - 'Duplicate to another project' => '別のプロジェクトに複製する', - 'Duplicate' => '複製する', - 'link' => 'リンク', - 'Comment updated successfully.' => 'コメントを更新しました。', - 'Unable to update your comment.' => 'コメントの更新に失敗しました。', - 'Remove a comment' => 'コメントを削除する', - 'Comment removed successfully.' => 'コメントを削除しました。', - 'Unable to remove this comment.' => 'コメントの削除に失敗しました。', - 'Do you really want to remove this comment?' => 'コメントを削除しますか?', - 'Current password for the user "%s"' => 'ユーザ「%s」の現在のパスワード', - 'The current password is required' => '現在のパスワードを入力してください', - 'Wrong password' => 'パスワードが違います', - 'Unknown' => '不明', - 'Last logins' => 'ログインの一覧', - 'Login date' => 'ログイン日時', - 'Authentication method' => '認証方法', - 'IP address' => 'IP アドレス', - 'User agent' => 'ユーザエージェント', - 'Persistent connections' => '既存のコネクション', - 'No session.' => 'セッションなし。', - 'Expiration date' => '有効期限', - 'Remember Me' => '次回から自動的にログインする', - 'Creation date' => '作成日', - 'Everybody' => '全員', - 'Open' => 'オープン', - 'Closed' => 'クローズ', - 'Search' => '検索', - 'Nothing found.' => '結果なし。', - 'Due date' => '期限', - 'Others formats accepted: %s and %s' => '他の書式: %s または %s', - 'Description' => '説明', - '%d comments' => '%d 個のコメント', - '%d comment' => '%d 個のコメント', - 'Email address invalid' => 'メールアドレスが正しくありません', - // 'Your external account is not linked anymore to your profile.' => '', - // 'Unable to unlink your external account.' => '', - // 'External authentication failed' => '', - // 'Your external account is linked to your profile successfully.' => '', - 'Email' => 'Email', - 'Task removed successfully.' => 'タスクを削除しました。', - 'Unable to remove this task.' => 'タスクの削除に失敗しました。', - 'Remove a task' => 'タスクの削除', - 'Do you really want to remove this task: "%s"?' => 'タスク「%s」を削除しますか?', - 'Assign automatically a color based on a category' => 'カテゴリに基いて色を変える', - 'Assign automatically a category based on a color' => '色に基いてカテゴリを変える', - 'Task creation or modification' => 'タスクの作成または変更', - 'Category' => 'カテゴリ', - 'Category:' => 'カテゴリ:', - 'Categories' => 'カテゴリ', - 'Your category have been created successfully.' => 'カテゴリを作成しました。', - 'Unable to create your category.' => 'カテゴリの作成に失敗しました。', - 'Your category have been updated successfully.' => 'カテゴリを更新しました。', - 'Unable to update your category.' => 'カテゴリの更新に失敗しました。', - 'Remove a category' => 'カテゴリの削除', - 'Category removed successfully.' => 'カテゴリを削除しました。', - 'Unable to remove this category.' => 'カテゴリを削除できませんでした。', - 'Category modification for the project "%s"' => 'プロジェクト「%s」のカテゴリの変更', - 'Category Name' => 'カテゴリ名', - 'Add a new category' => 'カテゴリの追加', - 'Do you really want to remove this category: "%s"?' => 'カテゴリ「%s」を削除しますか?', - 'All categories' => 'すべてのカテゴリ', - 'No category' => 'カテゴリなし', - 'The name is required' => '名前を入力してください', - 'Remove a file' => 'ファイルの削除', - 'Unable to remove this file.' => 'ファイルの削除に失敗しました。', - 'File removed successfully.' => 'ファイルを削除しました。', - 'Attach a document' => 'ドキュメントを添付する', - 'Do you really want to remove this file: "%s"?' => 'ファイル「%s」を削除しますか?', - 'Attachments' => '添付', - 'Edit the task' => 'タスクを変更する', - 'Add a comment' => 'コメントの追加', - 'Edit a comment' => 'コメントを変更する', - 'Summary' => '概要', - 'Time tracking' => '時間の計測', - 'Estimate:' => '予測:', - 'Spent:' => '経過:', - 'Do you really want to remove this sub-task?' => 'サブタスクを削除しますか?', - 'Remaining:' => '残り:', - 'hours' => '時間', - 'spent' => '経過', - 'estimated' => '予測', - 'Sub-Tasks' => 'サブタスク', - 'Add a sub-task' => 'サブタスクを追加する', - 'Original estimate' => '初期の予測', - 'Create another sub-task' => '続けて別のサブタスクを追加する', - 'Time spent' => '経過時間', - 'Edit a sub-task' => 'サブタスクを変更する', - 'Remove a sub-task' => 'サブタスクを削除する', - 'The time must be a numeric value' => '時間は数字で入力してください', - 'Todo' => '作業予定', - 'In progress' => '作業中', - 'Sub-task removed successfully.' => 'サブタスクを削除しました。', - 'Unable to remove this sub-task.' => 'サブタスクの削除に失敗しました。', - 'Sub-task updated successfully.' => 'サブタスクを更新しました。', - 'Unable to update your sub-task.' => 'サブタスクの更新に失敗しました。', - 'Unable to create your sub-task.' => 'サブタスクの追加に失敗しました。', - 'Sub-task added successfully.' => 'サブタスクを追加しました。', - 'Maximum size: ' => '最大: ', - 'Unable to upload the file.' => 'ファイルのアップロードに失敗しました。', - 'Display another project' => '別のプロジェクトを表示', - 'Created by %s' => '%s が作成', - 'Tasks Export' => 'タスクの出力', - 'Tasks exportation for "%s"' => '「%s」のタスク出力', - 'Start Date' => '開始日', - 'End Date' => '終了日', - 'Execute' => '実行', - 'Task Id' => 'タスク ID', - 'Creator' => '作成者', - 'Modification date' => '変更日', - 'Completion date' => '完了日', - 'Clone' => '複製', - 'Project cloned successfully.' => 'プロジェクトを複製しました。', - 'Unable to clone this project.' => 'プロジェクトの複製に失敗しました。', - 'Enable email notifications' => 'メール通知を設定', - 'Task position:' => 'タスクの位置:', - 'The task #%d have been opened.' => 'タスク #%d をオープンしました。', - 'The task #%d have been closed.' => 'タスク #%d をクローズしました。', - 'Sub-task updated' => 'サブタスクの更新', - 'Title:' => 'タイトル:', - 'Status:' => 'ステータス:', - 'Assignee:' => '担当:', - 'Time tracking:' => '時間計測:', - 'New sub-task' => '新しいサブタスク', - 'New attachment added "%s"' => '添付ファイル「%s」が追加されました', - 'New comment posted by %s' => '「%s」の新しいコメントが追加されました', - 'New attachment' => '新しい添付ファイル', - 'New comment' => '新しいコメント', - 'Comment updated' => 'コメントが更新されました', - 'New subtask' => '新しいサブタスク', - 'Subtask updated' => 'サブタスクの更新', - 'Task updated' => 'タスクの更新', - 'Task closed' => 'タスクのクローズ', - 'Task opened' => 'タスクのオープン', - 'I want to receive notifications only for those projects:' => '以下のプロジェクトにのみ通知を受け取る:', - 'view the task on Kanboard' => 'Kanboard でタスクを見る', - 'Public access' => '公開アクセス設定', - 'Active tasks' => 'アクティブなタスク', - 'Disable public access' => '公開アクセスを無効にする', - 'Enable public access' => '公開アクセスを有効にする', - 'Public access disabled' => '公開アクセスは無効化されています', - 'Do you really want to disable this project: "%s"?' => '「%s」を無効にしますか?', - 'Do you really want to enable this project: "%s"?' => '「%s」を有効にしますか?', - 'Project activation' => 'プロジェクトのアクティベーション', - 'Move the task to another project' => 'タスクを別プロジェクトに移す', - 'Move to another project' => '別プロジェクトに移す', - 'Do you really want to duplicate this task?' => 'タスクを複製しますか?', - 'Duplicate a task' => 'タスクの複製', - 'External accounts' => '外部アカウント', - 'Account type' => 'アカウントの種類', - 'Local' => 'ローカル', - 'Remote' => 'リモート', - 'Enabled' => '有効', - 'Disabled' => '無効', - 'Username:' => 'ユーザ名:', - 'Name:' => '名前:', - 'Email:' => 'Email:', - 'Notifications:' => '通知:', - 'Notifications' => '通知', - 'Account type:' => 'アカウントの種類:', - 'Edit profile' => 'プロフィールの変更', - 'Change password' => 'パスワードの変更', - 'Password modification' => 'パスワードの変更', - 'External authentications' => '外部認証', - 'Never connected.' => '未接続。', - 'No external authentication enabled.' => '外部認証が設定されていません。', - 'Password modified successfully.' => 'パスワードを変更しました。', - 'Unable to change the password.' => 'パスワードが変更できませんでした。', - 'Change category' => 'カテゴリの変更', - '%s updated the task %s' => '%s がタスク %s をアップデートしました', - '%s opened the task %s' => '%s がタスク %s をオープンしました', - '%s moved the task %s to the position #%d in the column "%s"' => '%s がタスク %s をポジション #%d カラム %s に移動しました', - '%s moved the task %s to the column "%s"' => '%s がタスク %s をカラム「%s」に移動しました', - '%s created the task %s' => '%s がタスク %s を作成しました', - '%s closed the task %s' => '%s がタスク %s をクローズしました', - '%s created a subtask for the task %s' => '%s がタスク %s のサブタスクを追加しました', - '%s updated a subtask for the task %s' => '%s がタスク %s のサブタスクを更新しました', - 'Assigned to %s with an estimate of %s/%sh' => '担当者 %s に予想 %s/%sh に変更されました', - 'Not assigned, estimate of %sh' => '担当者無しで予想 %sh に変更されました', - '%s updated a comment on the task %s' => '%s がタスク %s のコメントを更新しました', - '%s commented the task %s' => '%s がタスク %s にコメントしました', - '%s\'s activity' => '%s のアクティビティ', - 'RSS feed' => 'RSS フィード', - '%s updated a comment on the task #%d' => '%s がタスク #%d のコメントを更新しました', - '%s commented on the task #%d' => '%s がタスク #%d にコメントしました', - '%s updated a subtask for the task #%d' => '%s がタスク #%d のサブタスクを更新しました', - '%s created a subtask for the task #%d' => '%s がタスク #%d のサブタスクを追加しました', - '%s updated the task #%d' => '%s がタスク #%d を更新しました', - '%s created the task #%d' => '%s がタスク #%d を追加しました', - '%s closed the task #%d' => '%s がタスク #%d をクローズしました', - '%s open the task #%d' => '%s がタスク #%d をオープンしました', - '%s moved the task #%d to the column "%s"' => '%s がタスク #%d をカラム「%s」に移動しました', - '%s moved the task #%d to the position %d in the column "%s"' => '%s がタスク #%d を位置 %d カラム「%s」移動しました', - 'Activity' => 'アクティビティ', - 'Default values are "%s"' => 'デフォルト値は「%s」', - 'Default columns for new projects (Comma-separated)' => '新規プロジェクトのデフォルトカラム (コンマで区切って入力)', - 'Task assignee change' => '担当者の変更', - '%s change the assignee of the task #%d to %s' => '%s がタスク #%d の担当を %s に変更しました', - '%s changed the assignee of the task %s to %s' => '%s がタスク %s の担当を %s に変更しました', - 'New password for the user "%s"' => 'ユーザ「%s」の新しいパスワード', - 'Choose an event' => 'イベントの選択', - 'Create a task from an external provider' => 'タスクを外部サービスから作成する', - 'Change the assignee based on an external username' => '担当者を外部サービスに基いて変更する', - 'Change the category based on an external label' => 'カテゴリを外部サービスに基いて変更する', - 'Reference' => '参照', - 'Label' => 'ラベル', - 'Database' => 'データベース', - 'About' => '情報', - 'Database driver:' => 'データベースドライバ:', - 'Board settings' => '基本設定', - 'Webhook settings' => 'Webhook の設定', - 'Reset token' => 'トークンのリセット', - 'API endpoint:' => 'API エンドポイント:', - 'Refresh interval for private board' => '非公開ボードの更新頻度', - 'Refresh interval for public board' => '公開ボードの更新頻度', - 'Task highlight period' => 'タスクのハイライト期間', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'タスクが最近更新されたとみなす期間(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' => 'データのフォーマット', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO フォーマットが入力できます(例: %s または %s)', - 'New private project' => '非公開プロジェクトを作る', - 'This project is private' => 'このプロジェクトは非公開です', - 'Add' => '追加', - 'Start date' => '開始時間', - 'Time estimated' => '予想時間', - 'There is nothing assigned to you.' => '何もアサインされていません。', - 'My tasks' => '自分のタスク', - 'Activity stream' => 'アクティビティストリーム', - 'Dashboard' => 'ダッシュボード', - 'Confirmation' => '確認', - 'Allow everybody to access to this project' => '全員にプロジェクトへのアクセスを許す', - 'Everybody have access to this project.' => '誰でもこのプロジェクトにアクセスできます。', - 'Webhooks' => 'Webhook', - 'API' => 'API', - 'Create a comment from an external provider' => '外部サービスからコメントを作成する', - 'Project management' => 'プロジェクト・マネジメント', - 'My projects' => '自分のプロジェクト', - 'Columns' => 'カラム', - 'Task' => 'タスク', - 'Your are not member of any project.' => 'どのプロジェクトにも属していません。', - 'Percentage' => '割合', - 'Number of tasks' => 'タスク数', - 'Task distribution' => 'タスク分布', - 'Reportings' => 'レポート', - 'Task repartition for "%s"' => '「%s」のタスク分布', - 'Analytics' => '分析', - 'Subtask' => 'サブタスク', - 'My subtasks' => '自分のサブタスク', - 'User repartition' => '担当者分布', - 'User repartition for "%s"' => '「%s」の担当者分布', - 'Clone this project' => 'このプロジェクトを複製する', - 'Column removed successfully.' => 'カラムを削除しました', - 'Not enough data to show the graph.' => 'グラフを描画するには出たが足りません', - 'Previous' => '戻る', - 'The id must be an integer' => 'id は数字でなければなりません', - 'The project id must be an integer' => 'project id は数字でなければなりません', - 'The status must be an integer' => 'status は数字でなければなりません', - 'The subtask id is required' => 'subtask id が必要です', - 'The subtask id must be an integer' => 'subtask id は数字でなければなりません', - 'The task id is required' => 'task id が必要です', - 'The task id must be an integer' => 'task id は数字でなければなりません', - 'The user id must be an integer' => 'user id は数字でなければなりません', - 'This value is required' => 'この値が必要です', - 'This value must be numeric' => 'この値は数字でなければなりません', - 'Unable to create this task.' => 'このタスクを作成できませんでした', - 'Cumulative flow diagram' => '蓄積フロー図', - 'Cumulative flow diagram for "%s"' => '「%s」の蓄積フロー図', - 'Daily project summary' => '日時プロジェクトサマリー', - 'Daily project summary export' => '日時プロジェクトサマリーの出力', - 'Daily project summary export for "%s"' => '「%s」の日時プロジェクトサマリーの出力', - 'Exports' => '出力', - 'This export contains the number of tasks per column grouped per day.' => 'この出力は日時のカラムごとのタスク数を集計したものです', - 'Active swimlanes' => 'アクティブなスイムレーン', - 'Add a new swimlane' => '新しいスイムレーン', - 'Change default swimlane' => 'デフォルトスイムレーンの変更', - 'Default swimlane' => 'デフォルトスイムレーン', - 'Do you really want to remove this swimlane: "%s"?' => 'このスイムレーン「%s」を本当に削除しますか?', - 'Inactive swimlanes' => 'インタラクティブなスイムレーン', - 'Remove a swimlane' => 'スイムレーンの削除', - 'Show default swimlane' => 'デフォルトスイムレーンの表示', - 'Swimlane modification for the project "%s"' => '「%s」に対するスイムレーン変更', - 'Swimlane removed successfully.' => 'スイムレーンを削除しました。', - 'Swimlanes' => 'スイムレーン', - 'Swimlane updated successfully.' => 'スイムレーンを更新しました。', - 'The default swimlane have been updated successfully.' => 'デフォルトスイムレーンを更新しました。', - 'Unable to remove this swimlane.' => 'スイムレーンを削除できませんでした。', - 'Unable to update this swimlane.' => 'スイムレーンを更新できませんでした。', - 'Your swimlane have been created successfully.' => 'スイムレーンが作成されました。', - 'Example: "Bug, Feature Request, Improvement"' => '例: バグ, 機能, 改善', - 'Default categories for new projects (Comma-separated)' => '新しいプロジェクトのデフォルトカテゴリー (コンマ区切り)', - 'Integrations' => '連携', - 'Integration with third-party services' => 'サードパーティサービスとの連携', - 'Subtask Id' => 'サブタスク Id', - 'Subtasks' => 'サブタスク', - 'Subtasks Export' => 'サブタスクの出力', - 'Subtasks exportation for "%s"' => '「%s」のサブタスク出力', - 'Task Title' => 'タスクタイトル', - 'Untitled' => 'タイトル無し', - 'Application default' => 'アプリケーションデフォルト', - 'Language:' => '言語:', - 'Timezone:' => 'タイムゾーン:', - 'All columns' => '全てのカラム', - 'Calendar' => 'カレンダー', - 'Next' => '次へ', - '#%d' => '#%d', - 'All swimlanes' => '全てのスイムレーン', - 'All colors' => '全ての色', - 'Moved to column %s' => 'カラム %s へ移動しました', - '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」のステータスを選択', - 'Subtask timesheet' => 'サブタスクタイムシート', - 'There is nothing to show.' => '何も表示するものがありません。', - 'Time Tracking' => 'タイムトラッキング', - 'You already have one subtask in progress' => 'すでに進行中のサブタスクがあります。', - 'Which parts of the project do you want to duplicate?' => 'プロジェクトの何を複製しますか?', - // 'Disallow login form' => '', - 'Start' => '開始', - 'End' => '終了', - 'Task age in days' => 'タスクの経過日数', - 'Days in this column' => 'カラムでの経過日数', - '%dd' => '%d 日', - 'Add a new link' => '新しいリンクの追加', - 'Do you really want to remove this link: "%s"?' => 'リンク「%s」を本当に削除しますか?', - 'Do you really want to remove this link with task #%d?' => 'このリンクとタスク#%dを削除しますか?', - 'Field required' => 'フィールドが必要です', - 'Link added successfully.' => 'リンクを追加しました。', - 'Link updated successfully.' => 'リンクを更新しました。', - 'Link removed successfully.' => 'リンクを削除しました。', - 'Link labels' => 'リンクラベル', - 'Link modification' => 'リンクの変更', - 'Links' => 'リンク', - 'Link settings' => 'リンク設定', - 'Opposite label' => '反対のラベル', - 'Remove a link' => 'ラベルの削除', - 'Task\'s links' => 'タスクのラベル', - 'The labels must be different' => '異なるラベルを指定してください', - 'There is no link.' => 'リンクがありません', - 'This label must be unique' => 'ラベルはユニークである必要があります', - 'Unable to create your link.' => 'リンクを作成できませんでした。', - 'Unable to update your link.' => 'リンクを更新できませんでした。', - 'Unable to remove this link.' => 'リンクを削除できませんでした。', - 'relates to' => '次に関連します', - 'blocks' => '次をブロックしています', - 'is blocked by' => '次にブロックされています', - 'duplicates' => '次に重複しています', - 'is duplicated by' => '次に重複しています', - 'is a child of' => '次の子タスクです ', - 'is a parent of' => '次の親タスクです', - 'targets milestone' => '次のマイルストーンを目標とします', - 'is a milestone of' => '次のタスクのマイルストーンです', - 'fixes' => '次を修正します', - 'is fixed by' => '次に修正されます', - 'This task' => 'このタスクは', - '<1h' => '<1時間', - '%dh' => '%d 時間', - 'Expand tasks' => 'タスクを展開する', - 'Collapse tasks' => 'タスクを閉じる', - 'Expand/collapse tasks' => 'タスクの展開/閉じる', - 'Close dialog box' => 'ダイアログボックスを閉じる', - 'Submit a form' => 'フォームを送信する', - 'Board view' => 'ボードビュー', - 'Keyboard shortcuts' => 'キーボードショートカット', - 'Open board switcher' => 'ボード切り替えを開く', - 'Application' => 'アプリケーション', - 'Compact view' => 'コンパクトビュー', - 'Horizontal scrolling' => '縦スクロール', - 'Compact/wide view' => 'コンパクト/ワイドビュー', - 'No results match:' => '結果が一致しませんでした', - 'Currency' => '通貨', - 'Private project' => 'プライベートプロジェクト', - 'AUD - Australian Dollar' => 'AUD - 豪ドル', - 'CAD - Canadian Dollar' => 'CAD - 加ドル', - 'CHF - Swiss Francs' => 'CHF - スイスフラン', - 'Custom Stylesheet' => 'カスタムスタイルシート', - 'download' => 'ダウンロード', - 'EUR - Euro' => 'EUR - ユーロ', - 'GBP - British Pound' => 'GBP - 独ポンド', - 'INR - Indian Rupee' => 'INR - 伊ルピー', - 'JPY - Japanese Yen' => 'JPY - 日本円', - 'NZD - New Zealand Dollar' => 'NZD - NZ ドル', - 'RSD - Serbian dinar' => 'RSD - セルビアデナール', - 'USD - US Dollar' => 'USD - 米ドル', - 'Destination column' => '移動先のカラム', - 'Move the task to another column when assigned to a user' => 'ユーザの割り当てをしたらタスクを他のカラムに移動', - 'Move the task to another column when assignee is cleared' => 'ユーザの割り当てがなくなったらタスクを他のカラムに移動', - 'Source column' => '移動元のカラム', - 'Transitions' => '履歴', - 'Executer' => '実行者', - 'Time spent in the column' => 'カラムでの時間消費', - 'Task transitions' => 'タスクの遷移', - 'Task transitions export' => 'タスクの遷移を出力', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'このレポートはタスクのカラム間における移動を時間、ユーザー、経過時間と共に記録した物です。', - 'Currency rates' => '為替レート', - 'Rate' => 'レート', - 'Change reference currency' => '現在の基軸通貨', - 'Add a new currency rate' => '新しい通貨レートを追加', - 'Reference currency' => '基軸通貨', - // 'The currency rate have been added successfully.' => '', - 'Unable to add this currency rate.' => 'この通貨レートを追加できません。', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s がタスク「%s」の担当を解除しました。', - 'Enable Gravatar images' => 'Gravatar イメージを有効化', - 'Information' => '情報 ', - 'Check two factor authentication code' => '2 段認証をチェックする', - 'The two factor authentication code is not valid.' => '2 段認証コードは無効です。', - 'The two factor authentication code is valid.' => '2 段認証コードは有効です。', - 'Code' => 'コード', - 'Two factor authentication' => '2 段認証', - 'This QR code contains the key URI: ' => 'この QR コードが URI キーを含んでいます: ', - 'Check my code' => '自分のコードをチェック', - 'Secret key: ' => '秘密鍵: ', - 'Test your device' => 'デバイスをテストする', - // 'Assign a color when the task is moved to a specific column' => '', - // '%s via Kanboard' => '', - // 'Burndown chart for "%s"' => '', - // 'Burndown chart' => '', - // 'This chart show the task complexity over the time (Work Remaining).' => '', - // 'Screenshot taken %s' => '', - // 'Add a screenshot' => '', - // 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '', - // 'Screenshot uploaded successfully.' => '', - // 'SEK - Swedish Krona' => '', - // 'Identifier' => '', - // 'Disable two factor authentication' => '', - // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', - // 'Edit link' => '', - // 'Start to type task title...' => '', - // 'A task cannot be linked to itself' => '', - // 'The exact same link already exists' => '', - // 'Recurrent task is scheduled to be generated' => '', - // 'Score' => '', - // 'The identifier must be unique' => '', - // 'This linked task id doesn\'t exists' => '', - // 'This value must be alphanumeric' => '', - // 'Edit recurrence' => '', - // 'Generate recurrent task' => '', - // 'Trigger to generate recurrent task' => '', - // 'Factor to calculate new due date' => '', - // 'Timeframe to calculate new due date' => '', - // 'Base date to calculate new due date' => '', - // 'Action date' => '', - // 'Base date to calculate new due date: ' => '', - // 'This task has created this child task: ' => '', - // 'Day(s)' => '', - // 'Existing due date' => '', - // 'Factor to calculate new due date: ' => '', - // 'Month(s)' => '', - // 'Recurrence' => '', - // 'This task has been created by: ' => '', - // 'Recurrent task has been generated:' => '', - // 'Timeframe to calculate new due date: ' => '', - // 'Trigger to generate recurrent task: ' => '', - // 'When task is closed' => '', - // 'When task is moved from first column' => '', - // 'When task is moved to last column' => '', - // 'Year(s)' => '', - // 'Calendar settings' => '', - // 'Project calendar view' => '', - // 'Project settings' => '', - // 'Show subtasks based on the time tracking' => '', - // 'Show tasks based on the creation date' => '', - // 'Show tasks based on the start date' => '', - // 'Subtasks time tracking' => '', - // 'User calendar view' => '', - // 'Automatically update the start date' => '', - // 'iCal feed' => '', - // 'Preferences' => '', - // 'Security' => '', - // 'Two factor authentication disabled' => '', - // 'Two factor authentication enabled' => '', - // 'Unable to update this user.' => '', - // 'There is no user management for private projects.' => '', - // 'User that will receive the email' => '', - // 'Email subject' => '', - // 'Date' => '', - // 'Add a comment log when moving the task between columns' => '', - // 'Move the task to another column when the category is changed' => '', - // 'Send a task by email to someone' => '', - // 'Reopen a task' => '', - // 'Column change' => '', - // 'Position change' => '', - // 'Swimlane change' => '', - // 'Assignee change' => '', - // '[%s] Overdue tasks' => '', - // 'Notification' => '', - // '%s moved the task #%d to the first swimlane' => '', - // '%s moved the task #%d to the swimlane "%s"' => '', - // 'Swimlane' => '', - // 'Gravatar' => '', - // '%s moved the task %s to the first swimlane' => '', - // '%s moved the task %s to the swimlane "%s"' => '', - // 'This report contains all subtasks information for the given date range.' => '', - // 'This report contains all tasks information for the given date range.' => '', - // 'Project activities for %s' => '', - // 'view the board on Kanboard' => '', - // 'The task have been moved to the first swimlane' => '', - // 'The task have been moved to another swimlane:' => '', - // 'New title: %s' => '', - // 'The task is not assigned anymore' => '', - // 'New assignee: %s' => '', - // 'There is no category now' => '', - // 'New category: %s' => '', - // 'New color: %s' => '', - // 'New complexity: %d' => '', - // 'The due date have been removed' => '', - // 'There is no description anymore' => '', - // 'Recurrence settings have been modified' => '', - // 'Time spent changed: %sh' => '', - // 'Time estimated changed: %sh' => '', - // 'The field "%s" have been updated' => '', - // 'The description has been modified:' => '', - // 'Do you really want to close the task "%s" as well as all subtasks?' => '', - // 'I want to receive notifications for:' => '', - // 'All tasks' => '', - // 'Only for tasks assigned to me' => '', - // 'Only for tasks created by me' => '', - // 'Only for tasks created by me and assigned to me' => '', - // '%%Y-%%m-%%d' => '', - // 'Total for all columns' => '', - // 'You need at least 2 days of data to show the chart.' => '', - // '<15m' => '', - // '<30m' => '', - // 'Stop timer' => '', - // 'Start timer' => '', - // 'Add project member' => '', - // 'My activity stream' => '', - // 'My calendar' => '', - // 'Search tasks' => '', - // 'Reset filters' => '', - // 'My tasks due tomorrow' => '', - // 'Tasks due today' => '', - // 'Tasks due tomorrow' => '', - // 'Tasks due yesterday' => '', - // 'Closed tasks' => '', - // 'Open tasks' => '', - // 'Not assigned' => '', - // 'View advanced search syntax' => '', - // 'Overview' => '', - // 'Board/Calendar/List view' => '', - // 'Switch to the board view' => '', - // 'Switch to the calendar view' => '', - // 'Switch to the list view' => '', - // 'Go to the search/filter box' => '', - // 'There is no activity yet.' => '', - // 'No tasks found.' => '', - // 'Keyboard shortcut: "%s"' => '', - // 'List' => '', - // 'Filter' => '', - // 'Advanced search' => '', - // 'Example of query: ' => '', - // 'Search by project: ' => '', - // 'Search by column: ' => '', - // 'Search by assignee: ' => '', - // 'Search by color: ' => '', - // 'Search by category: ' => '', - // 'Search by description: ' => '', - // 'Search by due date: ' => '', - // 'Lead and Cycle time for "%s"' => '', - // 'Average time spent into each column for "%s"' => '', - // 'Average time spent into each column' => '', - // 'Average time spent' => '', - // 'This chart show the average time spent into each column for the last %d tasks.' => '', - // 'Average Lead and Cycle time' => '', - // 'Average lead time: ' => '', - // 'Average cycle time: ' => '', - // 'Cycle Time' => '', - // 'Lead Time' => '', - // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', - // 'Average time into each column' => '', - // 'Lead and cycle time' => '', - // 'Lead time: ' => '', - // 'Cycle time: ' => '', - // 'Time spent into each column' => '', - // 'The lead time is the duration between the task creation and the completion.' => '', - // 'The cycle time is the duration between the start date and the completion.' => '', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - // 'Set automatically the start date' => '', - // 'Edit Authentication' => '', - // 'Remote user' => '', - // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', - // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - // 'New remote user' => '', - // 'New local user' => '', - // 'Default task color' => '', - // 'This feature does not work with all browsers.' => '', - // 'There is no destination project available.' => '', - // 'Trigger automatically subtask time tracking' => '', - // 'Include closed tasks in the cumulative flow diagram' => '', - // 'Current swimlane: %s' => '', - // 'Current column: %s' => '', - // 'Current category: %s' => '', - // 'no category' => '', - // 'Current assignee: %s' => '', - // 'not assigned' => '', - // 'Author:' => '', - // 'contributors' => '', - // 'License:' => '', - // 'License' => '', - // 'Enter the text below' => '', - // 'Gantt chart for %s' => '', - // 'Sort by position' => '', - // 'Sort by date' => '', - // 'Add task' => '', - // 'Start date:' => '', - // 'Due date:' => '', - // 'There is no start date or due date for this task.' => '', - // 'Moving or resizing a task will change the start and due date of the task.' => '', - // 'There is no task in your project.' => '', - // 'Gantt chart' => '', - // 'People who are project managers' => '', - // 'People who are project members' => '', - // 'NOK - Norwegian Krone' => '', - // 'Show this column' => '', - // 'Hide this column' => '', - // 'open file' => '', - // 'End date' => '', - // 'Users overview' => '', - // 'Members' => '', - // 'Shared project' => '', - // 'Project managers' => '', - // 'Gantt chart for all projects' => '', - // 'Projects list' => '', - // 'Gantt chart for this project' => '', - // 'Project board' => '', - // 'End date:' => '', - // 'There is no start date or end date for this project.' => '', - // 'Projects Gantt chart' => '', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - // 'Milestone' => '', - // 'Documentation: %s' => '', - // 'Switch to the Gantt chart view' => '', - // 'Reset the search/filter box' => '', - // 'Documentation' => '', - // 'Table of contents' => '', - // 'Gantt' => '', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - // 'Link type' => '', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - // 'Project members' => '', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/ko_KR/translations.php b/sources/app/Locale/ko_KR/translations.php deleted file mode 100644 index 75d6be4..0000000 --- a/sources/app/Locale/ko_KR/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => '없음', - 'edit' => '수정', - 'Edit' => '수정', - 'remove' => '삭제', - 'Remove' => '삭제', - 'Yes' => '예', - 'No' => '아니오', - 'cancel' => '취소', - 'or' => '또는', - 'Yellow' => '노랑', - 'Blue' => '파랑', - 'Green' => '초록', - 'Purple' => '보라', - 'Red' => '빨강', - 'Orange' => '주황', - 'Grey' => '회색', - 'Brown' => '브라운', - 'Deep Orange' => '진홍', - 'Dark Grey' => '암회', - 'Pink' => '핑크', - 'Teal' => '암녹', - 'Cyan' => '청녹', - 'Lime' => '라임', - 'Light Green' => '연회', - 'Amber' => '호박', - 'Save' => '저장', - 'Login' => '로그인', - 'Official website:' => '공식 웹사이트:', - 'Unassigned' => '담당자 없음', - 'View this task' => '이 할일 보기', - 'Remove user' => '사용자 삭제', - 'Do you really want to remove this user: "%s"?' => '사용자 "%s"를 정말로 삭제하시겠습니까?', - 'All users' => '모든 사용자', - 'Username' => '사용자 이름', - 'Password' => '패스워드', - 'Administrator' => '관리자', - 'Sign in' => '로그인', - 'Users' => '사용자', - 'No user' => '사용자가 없습니다', - 'Forbidden' => '접근 거부', - 'Access Forbidden' => '접속이 거부되었습니다', - 'Edit user' => '사용자를 변경하는 ', - 'Logout' => '로그아웃', - 'Bad username or password' => '사용자 이름 또는 패스워드가 다릅니다.', - 'Edit project' => '프로젝트 수정', - 'Name' => '이름', - 'Projects' => '프로젝트', - 'No project' => '프로젝트가 없습니다', - 'Project' => '프로젝트', - 'Status' => '상태', - 'Tasks' => '할일', - 'Board' => '보드', - 'Actions' => 'Actions', - 'Inactive' => '무효', - 'Active' => '유효', - '%d tasks on the board' => '%d개의 할일', - '%d tasks in total' => '총 %d개의 할일', - 'Unable to update this board.' => '보드를 갱신할 수 없었습니다', - 'Edit board' => '보드를 변경하는 ', - 'Disable' => '비활성화', - 'Enable' => '유효하게 한다', - 'New project' => '새 프로젝트', - 'Do you really want to remove this project: "%s"?' => '프로젝트를 삭제하시겠습니까: "%s"?', - 'Remove project' => '프로젝트의 삭제', - 'Edit the board for "%s"' => '"%s"를 위한 보드 수정', - 'All projects' => '모든 프로젝트', - 'Add a new column' => '칼럼의 추가', - 'Title' => '제목', - 'Assigned to %s' => '담당자 %s', - 'Remove a column' => '칼럼 삭제', - 'Remove a column from a board' => '보드에서 칼럼 삭제', - 'Unable to remove this column.' => '(※)컬럼을 삭제할 수 없었습니다.', - 'Do you really want to remove this column: "%s"?' => '칼럼을 삭제하시겠습니까: "%s"?', - 'This action will REMOVE ALL TASKS associated to this column!' => '이 조작은 이 컬럼에 할당된 『 모든 할일을 삭제 』합니다!', - 'Settings' => '설정', - 'Application settings' => '애플리케이션의 설정', - 'Language' => '언어', - 'Webhook token:' => 'Webhook토큰:', - 'API token:' => 'API토큰:', - 'Database size:' => '데이터베이스의 사이즈:', - 'Download the database' => '데이터베이스의 다운로드', - 'Optimize the database' => '데이터베이스 최적화', - '(VACUUM command)' => '(VACUUM명령)', - '(Gzip compressed Sqlite file)' => '(GZip명령으로 압축된 Sqlite파일)', - 'Close a task' => '할일 마치기', - 'Edit a task' => '할일 수정', - 'Column' => '칼럼', - 'Color' => '색', - 'Assignee' => '담당자', - 'Create another task' => '다른 할일 추가', - 'New task' => '새로운 할일', - 'Open a task' => '할일 열기', - 'Do you really want to open this task: "%s"?' => '할일은 시작 하시겠습니까: "%s"?', - 'Back to the board' => '보드로 돌아가기', - 'There is nobody assigned' => '담당자가 없습니다', - 'Column on the board:' => '칼럼:', - 'Close this task' => '할일 마치기', - 'Open this task' => '할일 열기', - 'There is no description.' => '설명이 없습니다', - 'Add a new task' => '할일 추가 ', - 'The username is required' => '사용자 이름이 필요합니다', - 'The maximum length is %d characters' => '최대 길이는 "%d" 글자 입니다', - 'The minimum length is %d characters' => '최소 길이는 "%d" 글자 입니다', - 'The password is required' => '패스워드가 필요합니다', - 'This value must be an integer' => '정수로 입력하세요', - 'The username must be unique' => '사용자 이름이 이미 사용되고 있습니다', - 'The user id is required' => '사용자 ID가 필요합니다', - 'Passwords don\'t match' => '패스워드가 일치하지 않습니다', - 'The confirmation is required' => '확인용 패스워드를 입력하세요', - 'The project is required' => '프로젝트가 필요합니다', - 'The id is required' => 'ID가 필요합니다', - 'The project id is required' => '프로젝트 ID가 필요합니다', - 'The project name is required' => '프로젝트 이름이 필요합니다', - 'The title is required' => '제목이 필요합니다', - 'Settings saved successfully.' => '설정을 저장하였습니다', - 'Unable to save your settings.' => '설정의 보존에 실패했습니다.', - 'Database optimization done.' => '데이터베이스 최적화가 끝났습니다.', - 'Your project have been created successfully.' => '프로젝트를 작성했습니다.', - 'Unable to create your project.' => '프로젝트의 작성에 실패했습니다.', - 'Project updated successfully.' => '프로젝트를 갱신했습니다.', - 'Unable to update this project.' => '프로젝트의 갱신에 실패했습니다.', - 'Unable to remove this project.' => '프로젝트의 삭제에 실패했습니다.', - 'Project removed successfully.' => '프로젝트를 삭제했습니다.', - 'Project activated successfully.' => '프로젝트를 유효로 했습니다.', - 'Unable to activate this project.' => '프로젝트의 유효하게 못했어요.', - 'Project disabled successfully.' => '프로젝트를 무효로 했습니다.', - 'Unable to disable this project.' => '프로젝트의 무효화할 수 없었습니다.', - 'Unable to open this task.' => '할일의 오픈에 실패했습니다.', - 'Task opened successfully.' => '할일을 오픈했습니다.', - 'Unable to close this task.' => '할일의 클로즈에 실패했습니다.', - 'Task closed successfully.' => '할일을 마쳤습니다.', - 'Unable to update your task.' => '할일의 갱신에 실패했습니다.', - 'Task updated successfully.' => '할일을 갱신했습니다.', - 'Unable to create your task.' => '할일의 추가에 실패했습니다.', - 'Task created successfully.' => '할일을 추가했습니다.', - 'User created successfully.' => '사용자를 추가했습니다.', - 'Unable to create your user.' => '사용자의 추가에 실패했습니다.', - 'User updated successfully.' => '사용자를 갱신했습니다.', - 'Unable to update your user.' => '사용자의 갱신에 실패했습니다.', - 'User removed successfully.' => '사용자를 삭제했습니다.', - 'Unable to remove this user.' => '사용자 삭제에 실패했습니다.', - 'Board updated successfully.' => '보드를 갱신했습니다.', - 'Ready' => '준비완료', - 'Backlog' => '요구사항', - 'Work in progress' => '진행중', - 'Done' => '완료', - 'Application version:' => '애플리케이션의 버전:', - 'Id' => 'ID', - '%d closed tasks' => '%d개의 마친 할일', - 'No task for this project' => '이 프로젝트에 할일이 없습니다', - 'Public link' => '공개 접속 링크', - 'Timezone' => '시간대', - 'Sorry, I didn\'t find this information in my database!' => '데이터베이스에서 정보가 발견되지 않았습니다!', - 'Page not found' => '페이지가 발견되지 않는다', - 'Complexity' => '복잡도', - 'Task limit' => '할일 수 제한', - 'Task count' => '할일 수', - 'User' => '사용자', - 'Comments' => '댓글', - 'Leave a comment' => '댓글 남기기', - 'Comment is required' => '댓글을 입력하세요', - 'Leave a description' => '설명을 입력하세요', - 'Comment added successfully.' => '의견을 추가했습니다.', - 'Unable to create your comment.' => '댓글의 추가에 실패했습니다.', - 'Due Date' => '마감일', - 'Invalid date' => '날짜가 무효입니다', - 'Automatic actions' => '자동액션 관리', - 'Your automatic action have been created successfully.' => '자동 액션을 작성했습니다.', - 'Unable to create your automatic action.' => '자동 액션의 작성에 실패했습니다.', - 'Remove an action' => '자동 액션의 삭제', - 'Unable to remove this action.' => '자동 액션의 삭제에 실패했습니다.', - 'Action removed successfully.' => '자동 액션의 삭제에 성공했어요.', - 'Automatic actions for the project "%s"' => '"%s" 프로젝트를 위한 자동 액션', - 'Add an action' => '자동 액션 추가', - 'Event name' => '이벤트 이름', - 'Action name' => '액션 이름', - 'Action parameters' => '액션의 바로미터', - 'Action' => '액션', - 'Event' => '이벤트', - 'When the selected event occurs execute the corresponding action.' => '선택된 이벤트가 발생했을 때 대응하는 액션을 실행한다.', - 'Next step' => '다음 단계', - 'Define action parameters' => '액션의 바로미터', - 'Do you really want to remove this action: "%s"?' => '액션을 삭제하시겠습니까: "%s"?', - 'Remove an automatic action' => '자동 액션의 삭제', - 'Assign the task to a specific user' => '할일 담당자를 할당', - 'Assign the task to the person who does the action' => '액션을 일으킨 사용자를 담당자이자', - 'Duplicate the task to another project' => '할일을 다른 프로젝트로 복사', - 'Move a task to another column' => '할일을 다른 칼럼으로 이동', - 'Task modification' => '할일 변경', - 'Task creation' => '할일 만들기', - 'Closing a task' => '할일 종료', - 'Assign a color to a specific user' => '사용자 색 할당', - 'Column title' => '칼럼의 제목', - 'Position' => '위치', - 'Duplicate to another project' => '다른 프로젝트로 복사', - 'Duplicate' => '복사', - 'link' => '링크', - 'Comment updated successfully.' => '댓글을 갱신했습니다.', - 'Unable to update your comment.' => '댓글의 갱신에 실패했습니다.', - 'Remove a comment' => '댓글 삭제', - 'Comment removed successfully.' => '댓글을 삭제했습니다.', - 'Unable to remove this comment.' => '댓글의 삭제에 실패했습니다.', - 'Do you really want to remove this comment?' => '댓글을 삭제합니까?', - 'Current password for the user "%s"' => '사용자 "%s"의 현재 패스워드', - 'The current password is required' => '현재의 패스워드를 입력하세요', - 'Wrong password' => '패스워드가 다릅니다', - 'Unknown' => '불명', - 'Last logins' => '마지막 로그인', - 'Login date' => '로그인 일시', - 'Authentication method' => '인증 방법', - 'IP address' => 'IP 주소', - 'User agent' => '사용자 에이전트', - 'Persistent connections' => '세션', - 'No session.' => '세션 없음', - 'Expiration date' => '유효기간', - 'Remember Me' => '자동 로그인', - 'Creation date' => '작성일', - 'Everybody' => '모두', - 'Open' => '열림', - 'Closed' => '닫힘', - 'Search' => '검색', - 'Nothing found.' => '결과가 없습니다', - 'Due date' => '마감일', - 'Others formats accepted: %s and %s' => ' 다른 서식: %s 또는 %s', - 'Description' => '설명', - '%d comments' => '%d개의 댓글', - '%d comment' => '%d개의 댓글', - 'Email address invalid' => '메일 주소가 올바르지 않습니다.', - 'Your external account is not linked anymore to your profile.' => '외부 계정과 프로필이 더이상 연결되지 않습니다', - 'Unable to unlink your external account.' => '외부 계정과 연결 해제에 실패하였습니다', - 'External authentication failed' => '외부 인증 실패', - 'Your external account is linked to your profile successfully.' => '외부 계정과 프로필이 성공적으로 연결되었습니다', - 'Email' => '이메일', - 'Task removed successfully.' => '할일을 삭제했습니다.', - 'Unable to remove this task.' => '할일 삭제에 실패하였습니다', - 'Remove a task' => '할일 삭제', - 'Do you really want to remove this task: "%s"?' => '할일을 삭제하시겠습니까: "%s"?', - 'Assign automatically a color based on a category' => '카테고리에 바탕을 두고 색을 바꾸고', - 'Assign automatically a category based on a color' => '색에 바탕을 두고 카테고리를 바꾸었다', - 'Task creation or modification' => '할일의 작성 또는 변경', - 'Category' => '카테고리', - 'Category:' => '카테고리:', - 'Categories' => '카테고리', - 'Your category have been created successfully.' => '카테고리를 작성했습니다.', - 'Unable to create your category.' => '카테고리의 작성에 실패했습니다.', - 'Your category have been updated successfully.' => '카테고리를 갱신했습니다.', - 'Unable to update your category.' => '카테고리의 갱신에 실패했습니다.', - 'Remove a category' => '카테고리의 삭제', - 'Category removed successfully.' => '카테고리를 삭제했습니다.', - 'Unable to remove this category.' => '카테고리를 삭제할 수 없었습니다.', - 'Category modification for the project "%s"' => '"%s" 프로젝트 카테고리 수정', - 'Category Name' => '카테고리 이름', - 'Add a new category' => '카테고리의 추가', - 'Do you really want to remove this category: "%s"?' => '카테고리를 삭제하시겠습니까: "%s"?', - 'All categories' => '모든 카테고리', - 'No category' => '카테고리 없음', - 'The name is required' => '이름을 입력하십시오', - 'Remove a file' => '파일 삭제', - 'Unable to remove this file.' => '파일 삭제에 실패했습니다.', - 'File removed successfully.' => '파일을 삭제했습니다.', - 'Attach a document' => '문서 첨부', - 'Do you really want to remove this file: "%s"?' => '파일 "%s" 을 삭제할까요?', - 'Attachments' => '첨부', - 'Edit the task' => '할일 수정', - 'Add a comment' => '댓글 추가', - 'Edit a comment' => '댓글 수정', - 'Summary' => '개요', - 'Time tracking' => '시간 추적', - 'Estimate:' => '예측:', - 'Spent:' => '경과:', - 'Do you really want to remove this sub-task?' => '서브 할일을 삭제합니까?', - 'Remaining:' => '나머지:', - 'hours' => '시간', - 'spent' => '경과', - 'estimated' => '예측', - 'Sub-Tasks' => '서브 할일', - 'Add a sub-task' => '서브 할일 추가', - 'Original estimate' => '최초 예측시간', - 'Create another sub-task' => '다음 서브 할일 추가', - 'Time spent' => '경과시간', - 'Edit a sub-task' => '서브 할일을 변경하는 ', - 'Remove a sub-task' => '서브 할일을 삭제하는 ', - 'The time must be a numeric value' => '시간은 숫자로 입력하세요', - 'Todo' => '할일 예정', - 'In progress' => '할일 중', - 'Sub-task removed successfully.' => '서브 할일을 삭제했습니다.', - 'Unable to remove this sub-task.' => '서브 할일의 삭제가 실패했습니다.', - 'Sub-task updated successfully.' => '서브 할일을 갱신했습니다.', - 'Unable to update your sub-task.' => '서브 할일의 경신에 실패했습니다.', - 'Unable to create your sub-task.' => '서브 할일의 추가에 실패했습니다.', - 'Sub-task added successfully.' => '서브 할일을 추가했습니다.', - 'Maximum size: ' => '최대: ', - 'Unable to upload the file.' => '파일 업로드에 실패했습니다.', - 'Display another project' => '프로젝트 보기', - 'Created by %s' => '작성자 %s', - 'Tasks Export' => '할일 내보내기', - 'Tasks exportation for "%s"' => '"%s" 할일 내보내기', - 'Start Date' => '시작일', - 'End Date' => '종료일', - 'Execute' => '실행', - 'Task Id' => '할일 ID', - 'Creator' => '작성자', - 'Modification date' => '변경 일', - 'Completion date' => '완료일', - 'Clone' => '복사', - 'Project cloned successfully.' => '프로젝트를 복제했습니다.', - 'Unable to clone this project.' => '프로젝트의 복제에 실패했습니다.', - 'Enable email notifications' => '이메일 알림 설정', - 'Task position:' => '할일 위치:', - 'The task #%d have been opened.' => '할일 #%d가 시작되었습니다', - 'The task #%d have been closed.' => '할일 #%d가 종료되었습니다', - 'Sub-task updated' => '서브 할일 갱신', - 'Title:' => '제목:', - 'Status:' => '상태:', - 'Assignee:' => '담당:', - 'Time tracking:' => '시간 계측:', - 'New sub-task' => '새로운 서브 할일', - 'New attachment added "%s"' => '"%s"의 새로운 첨부 파일', - 'New comment posted by %s' => '"%s"님이 댓글을 추가하였습니다', - 'New attachment' => ' 새로운 첨부 파일', - 'New comment' => ' 새로운 댓글', - 'Comment updated' => '댓글가 갱신되었습니다', - 'New subtask' => ' 새로운 서브 할일', - 'Subtask updated' => '서브 할일 갱신', - 'Task updated' => '할일 업데이트', - 'Task closed' => '할일 마침', - 'Task opened' => '할일 시작', - 'I want to receive notifications only for those projects:' => '다음 프로젝트의 알림만 받겠습니다:', - 'view the task on Kanboard' => 'Kanboard에서 할일을 본다', - 'Public access' => '공개 접속 설정', - 'Active tasks' => '활성화된 할일', - 'Disable public access' => '공개 접속 비활성화', - 'Enable public access' => '공개 접속 활성화', - 'Public access disabled' => '공개 접속 불가', - 'Do you really want to disable this project: "%s"?' => '프로젝트를 비활성화하시겠습니까: "%s"?', - 'Do you really want to enable this project: "%s"?' => '프로젝트를 활성화하시겠습니까: "%s"?', - 'Project activation' => '프로젝트의 액티베ー션', - 'Move the task to another project' => '할일별 프로젝트에 옮기', - 'Move to another project' => '다른 프로젝트로 이동', - 'Do you really want to duplicate this task?' => '할일을 복제합니까?', - 'Duplicate a task' => '할일 복사', - 'External accounts' => '외부 계정', - 'Account type' => '계정종류', - 'Local' => '로컬', - 'Remote' => '원격', - 'Enabled' => '활성화', - 'Disabled' => '비활성화', - 'Username:' => '사용자명', - 'Name:' => '이름:', - 'Email:' => '이메일:', - 'Notifications:' => '알림:', - 'Notifications' => '알림', - 'Account type:' => '계정종류:', - 'Edit profile' => '프로필 변경', - 'Change password' => '패스워드 변경', - 'Password modification' => '패스워드 변경', - 'External authentications' => '외부 인증', - 'Never connected.' => '접속기록없음', - 'No external authentication enabled.' => '외부 인증이 설정되어 있지 않습니다.', - 'Password modified successfully.' => '패스워드를 변경했습니다.', - 'Unable to change the password.' => '비밀 번호가 변경할 수 없었습니다.', - 'Change category' => '카테고리 수정', - '%s updated the task %s' => '%s이 할일 %s을 업데이트했습니다', - '%s opened the task %s' => '%s이 할일 %s을 시작시켰습니다', - '%s moved the task %s to the position #%d in the column "%s"' => '%s이 할일%s을 위치#%d컬럼%s로 옮겼습니다', - '%s moved the task %s to the column "%s"' => '%s이 할일 %s을 칼럼 "%s" 로 옮겼습니다', - '%s created the task %s' => '%s이 할일%s을 추가했습니다', - '%s closed the task %s' => '%s이 할일%s을 마쳤습니다', - '%s created a subtask for the task %s' => '%s이 할일%s의 서브 할일을 추가했습니다', - '%s updated a subtask for the task %s' => '%s이 할일%s의 서브 할일을 갱신했습니다', - 'Assigned to %s with an estimate of %s/%sh' => '담당자 %s에게 예상 %s/%sh을 할당했습니다', - 'Not assigned, estimate of %sh' => '예상 %sh가 할당되지 않았습니다', - '%s updated a comment on the task %s' => '%s이 할일%s의 댓글을 수정했습니다', - '%s commented the task %s' => '%s이 할일%s에 댓글을 남겼습니다', - '%s\'s activity' => '%s의 활동', - 'RSS feed' => 'RSS피드', - '%s updated a comment on the task #%d' => '%s이 할일#%d의 댓글을 수정했습니다', - '%s commented on the task #%d' => '%s이 할일#%d을 언급하였습니다', - '%s updated a subtask for the task #%d' => '%s이 할일#%d의 서브 할일을 수정했습니다', - '%s created a subtask for the task #%d' => '%s이 할일#%d의 서브 할일을 수정했습니다', - '%s updated the task #%d' => '%s이 할일#%d을 갱신했습니다', - '%s created the task #%d' => '%s이 할일#%d을 추가했습니다', - '%s closed the task #%d' => '%s이 할일#%d을 닫혔습니다', - '%s open the task #%d' => '%s이 할일#%d를 오픈했습니다', - '%s moved the task #%d to the column "%s"' => '%s이 할일#%d을 칼럼"%s"로 옮겼습니다', - '%s moved the task #%d to the position %d in the column "%s"' => '%s이 할일#%d을 칼럼 "%s"의 %d 위치로 이동시켰습니다', - 'Activity' => '활동', - 'Default values are "%s"' => '기본 값은 "%s" 입니다', - 'Default columns for new projects (Comma-separated)' => '새로운 프로젝트의 기본 칼럼 (콤마(,)로 분리됨)', - 'Task assignee change' => '담당자의 변경', - '%s change the assignee of the task #%d to %s' => '%s이 할일 #%d의 담당을 %s로 변경합니다', - '%s changed the assignee of the task %s to %s' => '%s이 할일 %s의 담당을 %s로 변경했습니다', - 'New password for the user "%s"' => '사용자 "%s"의 새로운 패스워드', - 'Choose an event' => '행사의 선택', - 'Create a task from an external provider' => '할일을 외부 서비스로부터 작성하는 ', - 'Change the assignee based on an external username' => '담당자를 외부 서비스에 바탕을 두고 변경하는 ', - 'Change the category based on an external label' => '카테고리를 외부 서비스에 바탕을 두고 변경하는 ', - 'Reference' => '참조', - 'Label' => '라벨', - 'Database' => '데이터베이스', - 'About' => '정보', - 'Database driver:' => '데이터베이스 드라이버:', - 'Board settings' => '기본 설정', - 'Webhook settings' => 'Webhook의 설정', - 'Reset token' => '토큰 리셋', - 'API endpoint:' => 'API엔드 포인트:', - 'Refresh interval for private board' => '비공개 보드의 갱신 빈도', - 'Refresh interval for public board' => '공개 보드의 갱신 빈도', - 'Task highlight period' => '할일의 하이라이트 기간', - // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '', - // 'Frequency in second (60 seconds by default)' => '', - // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '', - 'Application URL' => '애플리케이션의 URL', - 'Token regenerated.' => '토큰이 다시 생성되었습니다.', - 'Date format' => '데이터 포멧', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO 포멧은 항상 가능합니다. 예를 들어: "%s" 와 "%s"', - 'New private project' => '새 비공개 프로젝트', - 'This project is private' => '이 프로젝트는 비공개입니다', - 'Add' => '추가', - 'Start date' => '시작시간', - 'Time estimated' => '예상시간', - 'There is nothing assigned to you.' => '할일이 없습니다. 옆사람의 일을 도와주면 어떨까요?', - 'My tasks' => '내 할일', - 'Activity stream' => '활동기록', - 'Dashboard' => '대시보드', - 'Confirmation' => '확인', - 'Allow everybody to access to this project' => '모든 사람이 이 프로젝트에 접근할 수 있도록 합니다', - 'Everybody have access to this project.' => '누구나 이 프로젝트에 액세스 할 수 있습니다', - 'Webhooks' => 'Webhook', - 'API' => 'API', - 'Create a comment from an external provider' => '외부 서비스로부터 의견을 작성한다', - 'Project management' => '프로젝트 관리', - 'My projects' => '내 프로젝트', - 'Columns' => '칼럼', - 'Task' => '할일', - 'Your are not member of any project.' => '어떤 프로젝트에도 속하지 않습니다.', - 'Percentage' => '비중', - 'Number of tasks' => '할일 수', - 'Task distribution' => '할일 분포', - 'Reportings' => '리포트', - 'Task repartition for "%s"' => '"%s"의 할일 분포', - 'Analytics' => '분석', - 'Subtask' => '서브 할일', - 'My subtasks' => '내 서브 할일', - 'User repartition' => '담당자 분포', - 'User repartition for "%s"' => '"%s"의 담당자 분포', - 'Clone this project' => '이 프로젝트를 복제하는 ', - 'Column removed successfully.' => '(※)컬럼을 삭제했습니다', - 'Not enough data to show the graph.' => '그래프를 선묘화하려면 나왔지만 부족합니다', - 'Previous' => ' 돌아가', - 'The id must be an integer' => 'id은 숫자가 아니면 안 됩니다', - 'The project id must be an integer' => 'project id은 숫자가 아니면 안 됩니다', - 'The status must be an integer' => 'status는 숫자지 않으면 안 됩니다', - 'The subtask id is required' => 'subtask id가 필요합니다', - 'The subtask id must be an integer' => 'subtask id은 숫자가 아니면 안 됩니다', - 'The task id is required' => 'task id가 필요합니다', - 'The task id must be an integer' => 'task id은 숫자가 아니면 안 됩니다', - 'The user id must be an integer' => 'user id은 숫자가 아니면 안 됩니다', - 'This value is required' => '이 값이 필요합니다', - 'This value must be numeric' => '이 값은 숫자가 아니면 안 됩니다', - 'Unable to create this task.' => '이 할일을 작성할 수 없었습니다', - 'Cumulative flow diagram' => '축적 흐름', - 'Cumulative flow diagram for "%s"' => '"%s"의 축적 흐름', - 'Daily project summary' => '하루 프로젝트 개요', - 'Daily project summary export' => '하루 프로젝트 개요의 출력', - 'Daily project summary export for "%s"' => '"%s" 하루 프로젝트 개요의 출력', - 'Exports' => '출력', - 'This export contains the number of tasks per column grouped per day.' => '이 출력은 날짜의 칼람별 할일 수를 집계한 것입니다', - 'Active swimlanes' => '액티브한 스윔레인', - 'Add a new swimlane' => ' 새로운 스윔레인', - 'Change default swimlane' => '기본 스윔레인의 변경', - 'Default swimlane' => '기본 스윔레인', - 'Do you really want to remove this swimlane: "%s"?' => '스웜레인을 삭제하시겠습니까: "%s"?', - 'Inactive swimlanes' => '인터랙티브한 스윔레인', - 'Remove a swimlane' => '스윔레인의 삭제', - 'Show default swimlane' => '기본 스윔레인의 표시', - 'Swimlane modification for the project "%s"' => '"%s" 프로젝트의 스웜레인 수정', - 'Swimlane removed successfully.' => '스윔레인을 삭제했습니다.', - 'Swimlanes' => '스윔레인', - 'Swimlane updated successfully.' => '스윔레인을 갱신했습니다.', - 'The default swimlane have been updated successfully.' => '기본 스윔레인을 갱신했습니다.', - 'Unable to remove this swimlane.' => '스윔레인을 삭제할 수 없었습니다.', - 'Unable to update this swimlane.' => '스윔레인을 갱신할 수 없었습니다.', - 'Your swimlane have been created successfully.' => '스윔레인이 작성되었습니다.', - 'Example: "Bug, Feature Request, Improvement"' => '예: "버그, 특성 요청, 향상"', - 'Default categories for new projects (Comma-separated)' => '새로운 프로젝트의 기본 카테고리 (콤마(,)로 구분)', - 'Integrations' => '연계', - 'Integration with third-party services' => '외부 서비스 연계', - 'Subtask Id' => '서브 할일 Id', - 'Subtasks' => '서브 할일', - 'Subtasks Export' => '서브 할일 출력', - 'Subtasks exportation for "%s"' => '"%s"의 서브 할일 출력', - 'Task Title' => '할일 제목', - 'Untitled' => '제목 없음', - 'Application default' => '애플리케이션 기본', - 'Language:' => '언어:', - 'Timezone:' => '시간대:', - 'All columns' => '모든 칼럼', - 'Calendar' => '달력', - 'Next' => '다음에 ', - '#%d' => '#%d', - 'All swimlanes' => '모든 스윔레인', - 'All colors' => '모든 색', - 'Moved to column %s' => '"%s" 칼럼으로 이동', - '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"', - 'Subtask timesheet' => '서브 할일 타임시트', - 'There is nothing to show.' => '기록이 없습니다', - 'Time Tracking' => '시간 트레킹', - 'You already have one subtask in progress' => '이미 진행 중인 서브 할일가 있습니다.', - 'Which parts of the project do you want to duplicate?' => '프로젝트의 무엇을 복제합니까?', - 'Disallow login form' => '허가되지 않은 로그인 양식', - 'Start' => '시작', - 'End' => '종료', - 'Task age in days' => '할일이 생긴 시간', - 'Days in this column' => '이 칼럼에 있는 시간', - '%dd' => '%d일', - 'Add a new link' => ' 새로운 링크 추가', - 'Do you really want to remove this link: "%s"?' => '링크를 삭제하시겠습니까: "%s"?', - 'Do you really want to remove this link with task #%d?' => '#%d 할일의 링크를 삭제하시겠습니까?', - 'Field required' => '필드가 필요합니다', - 'Link added successfully.' => '링크를 추가했습니다.', - 'Link updated successfully.' => '링크를 갱신했습니다.', - 'Link removed successfully.' => '링크를 삭제했습니다.', - 'Link labels' => '링크 라벨', - 'Link modification' => '링크의 변경', - 'Links' => '링크', - 'Link settings' => '링크 설정', - 'Opposite label' => '반대의 라벨', - 'Remove a link' => '라벨의 삭제', - 'Task\'s links' => '할일의 라벨', - 'The labels must be different' => ' 다른 라벨을 지정하세요', - 'There is no link.' => '링크가 없습니다', - 'This label must be unique' => '라벨은 독특할 필요가 있습니다', - 'Unable to create your link.' => '링크를 작성할 수 없었습니다.', - 'Unable to update your link.' => '링크를 갱신할 수 없었습니다.', - 'Unable to remove this link.' => '링크를 삭제할 수 없었습니다.', - 'relates to' => '연관 링크', - 'blocks' => '다음을 딜레이하는', - 'is blocked by' => '다음 때문에 딜레이되는', - 'duplicates' => '다음과 중복하는', - 'is duplicated by' => '다음에 중복되는', - 'is a child of' => '다음의 하위 할일', - 'is a parent of' => '다음의 상위 할일', - 'targets milestone' => '다음의 이정표를 목표로 하는', - 'is a milestone of' => '다음의 이정표인', - 'fixes' => '다음을 수정하는', - 'is fixed by' => '다음에 의해 수정되는', - 'This task' => '이 할일의 ', - '<1h' => '<1시간', - '%dh' => '%d시간', - 'Expand tasks' => '할일 크게', - 'Collapse tasks' => '할일 작게', - 'Expand/collapse tasks' => '할일 크게/작게', - 'Close dialog box' => '다이얼로그를 닫습니다', - 'Submit a form' => '제출', - 'Board view' => '보드 뷰', - 'Keyboard shortcuts' => '키보드 숏 컷', - 'Open board switcher' => '보드 전환을 열', - 'Application' => '애플리케이션', - 'Compact view' => '컴팩트 뷰', - 'Horizontal scrolling' => '세로 스크롤', - 'Compact/wide view' => '컴팩트/와이드 뷰', - 'No results match:' => '결과가 일치하지 않았습니다', - 'Currency' => '통화', - 'Private project' => '개인 프로젝트', - // 'AUD - Australian Dollar' => '', - // 'CAD - Canadian Dollar' => '', - // 'CHF - Swiss Francs' => '', - 'Custom Stylesheet' => '커스텀 스타일 시트', - 'download' => '다운로드', - // 'EUR - Euro' => '', - // 'GBP - British Pound' => '', - // 'INR - Indian Rupee' => '', - // 'JPY - Japanese Yen' => '', - // 'NZD - New Zealand Dollar' => '', - // 'RSD - Serbian dinar' => '', - // 'USD - US Dollar' => '', - 'Destination column' => '이동 후 칼럼', - 'Move the task to another column when assigned to a user' => '사용자의 할당을 하면 할일을 다른 칼럼에 이동', - 'Move the task to another column when assignee is cleared' => '사용자의 할당이 없어지면 할일을 다른 칼럼에 이동', - 'Source column' => '이동 전 칼럼', - 'Transitions' => '이력', - 'Executer' => '실행자', - 'Time spent in the column' => '칼럼에 있던 시간', - 'Task transitions' => '할일 천이', - 'Task transitions export' => '할일 천이를 출력', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '이 리포트는 할일의 칼럼 간 이동을 시간, 유저, 경과 시간과 함께 기록한 것입니다.', - 'Currency rates' => '환율', - 'Rate' => '레이트', - 'Change reference currency' => '현재의 기축 통화', - 'Add a new currency rate' => ' 새로운 통화 환율을 추가', - 'Reference currency' => '기축 통화', - 'The currency rate have been added successfully.' => '통화가 성공적으로 추가되었습니다', - 'Unable to add this currency rate.' => '이 통화 환율을 추가할 수 없습니다.', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s이 할일 %s의 담당을 삭제했습니다', - 'Enable Gravatar images' => 'Gravatar이미지를 활성화', - 'Information' => '정보', - 'Check two factor authentication code' => '2단 인증을 체크한다', - 'The two factor authentication code is not valid.' => '2단 인증 코드는 무효입니다.', - 'The two factor authentication code is valid.' => '2단 인증 코드는 유효합니다.', - 'Code' => '코드', - 'Two factor authentication' => '2단 인증', - 'This QR code contains the key URI: ' => 'QR 코드는 키 URI를 포함합니다: ', - 'Check my code' => '코드 체크', - 'Secret key: ' => '비밀키: ', - 'Test your device' => '디바이스 테스트', - 'Assign a color when the task is moved to a specific column' => '상세 칼럼으로 이동할 할일의 색깔을 지정하세요', - '%s via Kanboard' => '%s via E-board', - 'Burndown chart for "%s"' => '"%s" 번다운 차트', - 'Burndown chart' => '번다운 차트', - // 'This chart show the task complexity over the time (Work Remaining).' => '', - 'Screenshot taken %s' => '스크린샷_%s', - 'Add a screenshot' => '스크린샷 추가', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '스크린샷을 CTRL+V 혹은 ⌘+V를 눌러 붙여넣기', - 'Screenshot uploaded successfully.' => '스크린샷을 업로드하였습니다', - // 'SEK - Swedish Krona' => '', - 'Identifier' => '식별자', - 'Disable two factor authentication' => '이중 인증 비활성화', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => '"%s" 담당자의 이중 인증을 비활성화 하시겠습니까?', - 'Edit link' => '링크 수정', - 'Start to type task title...' => '할일 제목을 입력하세요', - 'A task cannot be linked to itself' => '할일을 자기자신에게 연결할 수 없습니다', - 'The exact same link already exists' => '동일한 링크가 이미 존재합니다', - // 'Recurrent task is scheduled to be generated' => '', - 'Score' => '점수', - 'The identifier must be unique' => '식별자는 유일해야 합니다', - 'This linked task id doesn\'t exists' => '연결된 할일 ID가 존재하지 않습니다', - 'This value must be alphanumeric' => '글자와 숫자만 가능합니다', - 'Edit recurrence' => '반복 수정', - 'Generate recurrent task' => '반복 할일 생성', - 'Trigger to generate recurrent task' => '반복 할일 생성 트리거', - 'Factor to calculate new due date' => '새로운 종료날짜 계산', - 'Timeframe to calculate new due date' => '종료날짜 계산 단위', - 'Base date to calculate new due date' => '새로운 기본 종료날짜 계산', - 'Action date' => '시작날짜', - 'Base date to calculate new due date: ' => '새로운 기본 종료날짜 계산: ', - // 'This task has created this child task: ' => '', - 'Day(s)' => '일', - 'Existing due date' => '기존 종료날짜', - 'Factor to calculate new due date: ' => '새로운 종료날짜 계산: ', - 'Month(s)' => '월', - 'Recurrence' => '반복', - 'This task has been created by: ' => '할일을 만들었습니다: ', - 'Recurrent task has been generated:' => '반복 할일이 생성되었습니다', - 'Timeframe to calculate new due date: ' => '종료날짜 계산 단위', - // 'Trigger to generate recurrent task: ' => '', - 'When task is closed' => '할일을 마쳤을때', - 'When task is moved from first column' => '할일이 첫번째 칼럼으로 옮겨졌을때', - 'When task is moved to last column' => '할일이 마지막 칼럼으로 옮겨졌을때', - 'Year(s)' => '년', - 'Calendar settings' => '달력 설정', - 'Project calendar view' => '프로젝트 달력 보기', - 'Project settings' => '프로젝트 설정', - 'Show subtasks based on the time tracking' => '시간 트래킹의 서브 할일 보기', - 'Show tasks based on the creation date' => '생성 날짜로 할일 보기', - 'Show tasks based on the start date' => '시작 날짜로 할일 보기', - 'Subtasks time tracking' => '서브 할일 시간 트래킹', - 'User calendar view' => '담당자 달력 보기', - 'Automatically update the start date' => '시작일에 자동 업데이트', - // 'iCal feed' => '', - 'Preferences' => '우선권', - 'Security' => '보안', - 'Two factor authentication disabled' => '이중 인증이 비활성화 되었습니다', - 'Two factor authentication enabled' => '이중 인증이 활성화 되었습니다', - 'Unable to update this user.' => '담당자의 업데이트가 가능합니다', - 'There is no user management for private projects.' => '비밀 프로젝트의 관리 담당자가 없습니다', - 'User that will receive the email' => '그 담당자가 이메일을 수신할 것입니다', - 'Email subject' => '이메일 제목', - 'Date' => '날짜', - 'Add a comment log when moving the task between columns' => '칼럼 중간의 할일이 이동할 때 의견 달기', - 'Move the task to another column when the category is changed' => '카테고리 변경시 할일을 다른 칼럼으로 이동', - 'Send a task by email to someone' => '할일을 이메일로 보내기', - 'Reopen a task' => '할일 다시 시작', - 'Column change' => '칼럼 이동', - 'Position change' => '위치 이동', - 'Swimlane change' => '스윔레인 변경', - 'Assignee change' => '담당자 변경', - '[%s] Overdue tasks' => '[%s] 마감시간 지남', - 'Notification' => '알림', - '%s moved the task #%d to the first swimlane' => '%s가 할일 #%d를 첫번째 스웜레인으로 이동시켰습니다', - '%s moved the task #%d to the swimlane "%s"' => '%s가 할일 #%d를 "%s" 스웜레인으로 이동시켰습니다', - 'Swimlane' => '스윔레인', - // 'Gravatar' => '', - '%s moved the task %s to the first swimlane' => '%s가 할일 %s를 첫번째 스웜레인으로 이동시켰습니다', - '%s moved the task %s to the swimlane "%s"' => '%s가 할일 %s를 %s 스웜레인으로 이동시켰습니다', - 'This report contains all subtasks information for the given date range.' => '해당 기간의 모든 서브 할일 정보가 보고서에 포함됩니다', - 'This report contains all tasks information for the given date range.' => '해당 기간의 모든 할일 정보가 보고서에 포함됩니다', - 'Project activities for %s' => '%s의 프로젝트 활성화', - 'view the board on Kanboard' => 'kanboard로 보드 보기', - 'The task have been moved to the first swimlane' => '할일이 첫번째 스웜라인으로 이동되어 있습니다', - 'The task have been moved to another swimlane:' => '할일이 다른 스웜라인으로 이동되어 있습니다', - 'New title: %s' => '제목 변경: %s', - 'The task is not assigned anymore' => '담당자 없음', - 'New assignee: %s' => '담당자 변경: %s', - 'There is no category now' => '카테고리 없음', - 'New category: %s' => '카테고리 변경: %s', - 'New color: %s' => '색깔 변경: %s', - 'New complexity: %d' => '복잡도 변경: %d', - 'The due date have been removed' => '마감날짜 삭제', - 'There is no description anymore' => '설명 없음', - 'Recurrence settings have been modified' => '반복할일 설정 수정', - 'Time spent changed: %sh' => '경과시간 변경: %s시간', - 'Time estimated changed: %sh' => '%s시간으로 예상시간 변경', - 'The field "%s" have been updated' => '%s 필드가 업데이트 되어있습니다', - 'The description has been modified:' => '설명이 수정되어 있습니다: ', - 'Do you really want to close the task "%s" as well as all subtasks?' => '할일 "%s"과 서브 할일을 모두 마치시겠습니까?', - 'I want to receive notifications for:' => '다음의 알림을 받기를 원합니다:', - 'All tasks' => '모든 할일', - 'Only for tasks assigned to me' => '내가 담당자인 일', - 'Only for tasks created by me' => '내가 만든 일', - 'Only for tasks created by me and assigned to me' => '내가 만들었거나 내가 담당자인 일', - // '%%Y-%%m-%%d' => '', - 'Total for all columns' => '모든 칼럼', - 'You need at least 2 days of data to show the chart.' => '차트를 보기 위하여 최소 2일의 데이터가 필요합니다', - '<15m' => '<15분', - '<30m' => '<30분', - 'Stop timer' => '타이머 정지', - 'Start timer' => '타이머 시작', - 'Add project member' => '프로젝트 맴버 추가', - 'My activity stream' => '내 활동기록', - 'My calendar' => '내 캘린더', - 'Search tasks' => '할일 찾기', - 'Reset filters' => '필터 리셋', - 'My tasks due tomorrow' => '내일까지 내 할일', - 'Tasks due today' => '오늘까지 할일', - 'Tasks due tomorrow' => '내일까지 할일', - 'Tasks due yesterday' => '어제까지 할일', - 'Closed tasks' => '닫힌 할일', - 'Open tasks' => '열린 할일', - 'Not assigned' => '담당자가 없는 일', - 'View advanced search syntax' => '추가 검색 문법보기', - 'Overview' => '개요', - 'Board/Calendar/List view' => '보드/달력/리스트 보기', - 'Switch to the board view' => '보드 보기로 전환', - 'Switch to the calendar view' => '달력 보기로 전환', - 'Switch to the list view' => '리스트 보기로 전환', - 'Go to the search/filter box' => '검색/필터 박스로 이동', - 'There is no activity yet.' => '활동이 없습니다', - 'No tasks found.' => '할일을 찾을 수 없습니다', - 'Keyboard shortcut: "%s"' => '쉬운 키보드: "%s"', - 'List' => '목록', - 'Filter' => '필터', - 'Advanced search' => '검색 문법', - 'Example of query: ' => '문법 예제 ', - 'Search by project: ' => '프로젝트로 찾기 ', - 'Search by column: ' => '칼럼으로 찾기 ', - 'Search by assignee: ' => '담당자로 찾기 ', - 'Search by color: ' => '색깔로 찾기 ', - 'Search by category: ' => '카테고리로 찾기 ', - 'Search by description: ' => '설명으로 찾기 ', - 'Search by due date: ' => '마감날짜로 찾기 ', - 'Lead and Cycle time for "%s"' => '"%s"의 리드와 사이클 시간', - 'Average time spent into each column for "%s"' => '"%s"의 각 칼럼 평균 소요시간', - 'Average time spent into each column' => '각 칼럼의 평균 소요시간', - 'Average time spent' => '평균 소요시간', - 'This chart show the average time spent into each column for the last %d tasks.' => '마지막 %d 할일의 칼럼 평균 소요시간을 차트에 표시합니다', - 'Average Lead and Cycle time' => '평균 Lead and Cycle 시간', - 'Average lead time: ' => '평균 lead 시간', - 'Average cycle time: ' => '평균 cycle 시간', - 'Cycle Time' => '사이클 시간', - 'Lead Time' => '리드 시간', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '마지막 %d 할일의 평균 리드와 사이클 시간을 차트에 표시합니다', - 'Average time into each column' => '각 칼럼의 평균 시간', - 'Lead and cycle time' => '리드와 사이클 시간', - 'Lead time: ' => '리드 시간: ', - 'Cycle time: ' => '사이클 시간: ', - 'Time spent into each column' => '각 칼럼에서 걸린 시간', - 'The lead time is the duration between the task creation and the completion.' => '리드 시간은 할일의 생성부터 완료까지의 기간입니다', - 'The cycle time is the duration between the start date and the completion.' => '사이클 시간은 할일의 시작일부터 완료까지의 기간입니다', - 'If the task is not closed the current time is used instead of the completion date.' => '할일이 종료되지 않았다면, 완료 시간 대신 현재 시간이 사용됩니다', - 'Set automatically the start date' => '자동으로 시작 날짜를 설정합니다', - 'Edit Authentication' => '계정 수정', - 'Remote user' => '원격 담당자', - '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.' => '가능한 목적 프로젝트가 없습니다', - 'Trigger automatically subtask time tracking' => '자동 서브 할일 시간 트래킹 트리거', - 'Include closed tasks in the cumulative flow diagram' => '누적 플로우 다이어그램에 종료된 할일을 포함합니다', - 'Current swimlane: %s' => '현재 스웜라인: %s', - 'Current column: %s' => '현재 칼럼: %s', - 'Current category: %s' => '현재 카테고리: %s', - 'no category' => '카테고리 아님', - 'Current assignee: %s' => '현재 할당자: %s', - 'not assigned' => '할당되지 않음', - 'Author:' => '글쓴이:', - 'contributors' => '기여자', - 'License:' => '라이센스:', - 'License' => '라이센스', - 'Enter the text below' => '아랫글로 들어가기', - 'Gantt chart for %s' => '%s의 간트 차트', - 'Sort by position' => '위치별 정렬', - 'Sort by date' => '날짜별 정렬', - 'Add task' => '할일 추가', - 'Start date:' => '시작일:', - 'Due date:' => '만기일:', - 'There is no start date or due date for this task.' => '할일의 시작일 또는 만기일이 없습니다', - // 'Moving or resizing a task will change the start and due date of the task.' => '', - // 'There is no task in your project.' => '', - 'Gantt chart' => '간트 차트', - 'People who are project managers' => '프로젝트 매니저', - 'People who are project members' => '프로젝트 멤버', - // 'NOK - Norwegian Krone' => '', - 'Show this column' => '칼럼 보이기', - 'Hide this column' => '칼럼 숨기기', - 'open file' => '열기', - 'End date' => '종료 날짜', - 'Users overview' => '유저 전체보기', - 'Members' => '멤버', - 'Shared project' => '프로젝트 공유', - 'Project managers' => '프로젝트 매니저', - 'Gantt chart for all projects' => '모든 프로젝트의 간트 차트', - 'Projects list' => '프로젝트 리스트', - 'Gantt chart for this project' => '이 프로젝트 간트차트', - 'Project board' => '프로젝트 보드', - 'End date:' => '날짜 수정', - 'There is no start date or end date for this project.' => '이 프로젝트에는 시작날짜와 종료날짜가 없습니다', - 'Projects Gantt chart' => '프로젝트 간트차트', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - 'Milestone' => '마일스톤', - 'Documentation: %s' => '문서: %s', - 'Switch to the Gantt chart view' => '간트 차트 보기로 변경', - // 'Reset the search/filter box' => '', - 'Documentation' => '문서', - // 'Table of contents' => '', - 'Gantt' => '간트', - 'Author' => '글쓴이', - 'Version' => '버전', - 'Plugins' => '플러그인', - 'There is no plugin loaded.' => '플러그인이 로드되지 않았습니다', - 'Set maximum column height' => '최대 칼럼 높이 제한하기', - 'Remove maximum column height' => '최대 칼럼 높이 없애기', - 'My notifications' => '내 알림', - 'Custom filters' => '사용자 정의 필터', - 'Your custom filter have been created successfully.' => '사용자 정의 필터가 성공적으로 생성되었습니다', - 'Unable to create your custom filter.' => '사용자 정의 필터 생성 비활성화', - 'Custom filter removed successfully.' => '사용자 정의 필터가 성공적으로 삭제되었습니다', - 'Unable to remove this custom filter.' => '정의 필터 삭제 비활성화', - 'Edit custom filter' => '정의 필터 수정', - 'Your custom filter have been updated successfully.' => '사용자 정의 필터가 성공적으로 수정되었습니다', - 'Unable to update custom filter.' => '정의 필터 수정 비활성화', - 'Web' => '웹', - // 'New attachment on task #%d: %s' => '', - 'New comment on task #%d' => '할일 #%d에 새로운 댓글이 달렸습니다', - 'Comment updated on task #%d' => '할일 #%d에 댓글이 업데이트되었습니다', - 'New subtask on task #%d' => '서브 할일 #%d이 업데이트되었습니다', - 'Subtask updated on task #%d' => '서브 할일 #%d가 업데이트되었습니다', - 'New task #%d: %s' => '할일 #%d: %s이 추가되었습니다', - 'Task updated #%d' => '할일 #%d이 업데이트되었습니다', - 'Task #%d closed' => '할일 #%d를 마쳤습니다', - 'Task #%d opened' => '할일 #%d가 시작되었습니다', - 'Column changed for task #%d' => '할일 #%d의 칼럼이 변경되었습니다', - 'New position for task #%d' => '할일 #%d이 새로운 위치에 등록되었습니다', - 'Swimlane changed for task #%d' => '#%d 할일의 스웜라인이 변경됩니다', - 'Assignee changed on task #%d' => '#%d 할일의 담당자가 변경됩니다', - '%d overdue tasks' => '할일의 기한이 %d일 지났습니다', - 'Task #%d is overdue' => '#%d 할일의 기한이 지났습니다', - 'No new notifications.' => '알림이 없습니다', - 'Mark all as read' => '모두 읽음', - 'Mark as read' => '읽음', - // 'Total number of tasks in this column across all swimlanes' => '', - 'Collapse swimlane' => '스웜라인 붕괴', - 'Expand swimlane' => '스웜라인 확장', - 'Add a new filter' => '새로운 필터 추가', - 'Share with all project members' => '모든 프로젝트 맴버 공유', - 'Shared' => '공유', - 'Owner' => '소유자', - 'Unread notifications' => '읽지않은 알림', - 'Notification methods:' => '알림 방법', - 'Import tasks from CSV file' => 'CSV 파일에서 할일 가져오기', - 'Unable to read your file' => '파일을 읽을 수 없습니다', - '%d task(s) have been imported successfully.' => '%d 할일이 성공적으로 추가되었습니다', - 'Nothing have been imported!' => '추가가 되지 않았습니다!', - 'Import users from CSV file' => 'CSV 파일에서 사용자 가져오기', - '%d user(s) have been imported successfully.' => '%d 사용자가 성공적으로 추가되었습니다', - 'Comma' => '콤마', - 'Semi-colon' => '세미콜론', - 'Tab' => '탭', - 'Vertical bar' => '세로줄', - 'Double Quote' => '이중 따옴표', - 'Single Quote' => '따옴표', - '%s attached a file to the task #%d' => '%s가 할일 #%d에 파일을 추가하였습니다', - 'There is no column or swimlane activated in your project!' => '프로젝트에 활성화된 칼럼이나 스웜라인이 없습니다', - // 'Append filter (instead of replacement)' => '', - 'Append/Replace' => '추가/변경', - 'Append' => '추가', - 'Replace' => '변경', - 'Import' => '가져오기', - 'change sorting' => '정렬 변경', - 'Tasks Importation' => '할일 가져오기', - 'Delimiter' => '구분자', - 'Enclosure' => '동봉', - 'CSV File' => 'CSV 파일', - 'Instructions' => '명령', - 'Your file must use the predefined CSV format' => '파일은 미리 정의된 CVS 형식이어야 합니다', - 'Your file must be encoded in UTF-8' => '파일은 UTF-8로 인코딩되어야 합니다', - 'The first row must be the header' => '첫 줄은 헤더이어야 합니다', - 'Duplicates are not verified for you' => '사본이 허락되지 않습니다', - 'The due date must use the ISO format: YYYY-MM-DD' => '만기일은 ISO 형식이어야 합니다: YYYY-MM-DD', - 'Download CSV template' => 'CVS 탬플릿 내려받기', - 'No external integration registered.' => '설정이 되어있지 않습니다', - 'Duplicates are not imported' => '사본을 가져올 수 없습니다', - 'Usernames must be lowercase and unique' => '사용자 이름은 소문자이며 유일해야 합니다', - 'Passwords will be encrypted if present' => '비밀번호는 암호화됩니다', - '%s attached a new file to the task %s' => '%s이 새로운 파일을 할일 %s에 추가했습니다', - 'Link type' => '링크 형식', - 'Assign automatically a category based on a link' => '링크 기반 자동 카테고리 할당', - // 'BAM - Konvertible Mark' => '', - 'Assignee Username' => '담당자의 사용자이름', - 'Assignee Name' => '당장자 이름', - 'Groups' => '그룹', - 'Members of %s' => '%s의 맴버', - 'New group' => '새로운 그룹', - 'Group created successfully.' => '그룹이 성공적으로 생성되었습니다', - 'Unable to create your group.' => '그룹 생성 비활성화', - 'Edit group' => '그룹 편집', - 'Group updated successfully.' => '그룹이 성공적으로 수정되었습니다', - 'Unable to update your group.' => '그룹 수정 비활성화', - 'Add group member to "%s"' => '%s 그룹 맴버 추가', - 'Group member added successfully.' => '그룹 맴버가 성공적으로 추가되었습니다', - 'Unable to add group member.' => '그룹 맴버 추가 비활성화', - 'Remove user from group "%s"' => '%s 그룹 사용자 삭제', - 'User removed successfully from this group.' => '그룹 사용자가 성공적으로 삭제되었습니다', - 'Unable to remove this user from the group.' => '그룹 사용자 삭제 비활성화', - 'Remove group' => '그룹 삭제', - 'Group removed successfully.' => '그룹이 성공적으로 삭제되었습니다', - 'Unable to remove this group.' => '그룹 삭제 비활성화', - 'Project Permissions' => '프로젝트 권한', - 'Manager' => '매니저', - 'Project Manager' => '프로젝트 매니저', - 'Project Member' => '프로젝트 멤버', - 'Project Viewer' => '프로젝트 뷰어', - 'Your account is locked for %d minutes' => '%d분 동안 계정이 잠깁니다', - // 'Invalid captcha' => '', - 'The name must be unique' => '이름은 유일해야 합니다', - 'View all groups' => '모든그룹보기', - 'View group members' => '그룹맴버 보기', - 'There is no user available.' => '가능한 사용자가 없습니다', - 'Do you really want to remove the user "%s" from the group "%s"?' => '"%s" 사용자를 "%s" 에서 삭제하시겠습니까?', - 'There is no group.' => '그룹이 없습니다', - 'External Id' => '외부 아이디', - 'Add group member' => '멤버추가', - 'Do you really want to remove this group: "%s"?' => '그룹을 삭제하시겠습니까: "%s"?', - 'There is no user in this group.' => '이 그룹에는 사용자가 없습니다', - 'Remove this user' => '사용자 삭제', - 'Permissions' => '권한', - 'Allowed Users' => '사용자 승인', - 'No user have been allowed specifically.' => '구체적으로 승인된 사용자가 없습니다', - 'Role' => '역할', - 'Enter user name...' => '사용자 이름을 입력합니다...', - 'Allowed Groups' => '승인된 그룹', - 'No group have been allowed specifically.' => '구체적으로 승인된 그룹이 없습니다', - 'Group' => '그룹', - 'Group Name' => '그룹명', - 'Enter group name...' => '그룹명을 입력합니다...', - 'Role:' => '역할: ', - 'Project members' => '프로젝트 멤버', - 'Compare hours for "%s"' => '"%s" 시간동안 비교', - '%s mentioned you in the task #%d' => '#%d 할일에서 %s가 당신을 언급하였습니다', - '%s mentioned you in a comment on the task #%d' => '#%d 할일에서 %s가 당신의 댓글을 언급하였습니다', - 'You were mentioned in the task #%d' => '#%d 할일에서 당신이 언급되었습니다', - 'You were mentioned in a comment on the task #%d' => '할일 #%d의 댓글에서 언급되었습니다', - 'Mentioned' => '언급된', - 'Compare Estimated Time vs Actual Time' => '예상 시간과 실제 시간 비교', - 'Estimated hours: ' => '예상 시간: ', - 'Actual hours: ' => '실제 시간: ', - 'Hours Spent' => '소요 시간', - 'Hours Estimated' => '예상 시간', - 'Estimated Time' => '예상 시간', - 'Actual Time' => '실제 시간', - 'Estimated vs actual time' => '예상 vs 실제 시간', - // 'RUB - Russian Ruble' => '', - 'Assign the task to the person who does the action when the column is changed' => '칼럼이 변경되면 액션하지 않는 사람에게 할일을 할당합니다', - 'Close a task in a specific column' => '상세 칼럼의 할일을 종료합니다', - 'Time-based One-time Password Algorithm' => '시간에 기반한 1회용 패스워드 알고리즘', - 'Two-Factor Provider: ' => '이중 인증: ', - 'Disable two-factor authentication' => '이중 인증 비활성화', - 'Enable two-factor authentication' => '이중 인증 활성화', - // 'There is no integration registered at the moment.' => '', - 'Password Reset for Kanboard' => 'Kanboard의 비밀번호 초기화', - 'Forgot password?' => '비밀번호 찾기', - 'Enable "Forget Password"' => '"비밀번호 분실" 활성화', - 'Password Reset' => '비밀번호 초기화', - 'New password' => '새로운 비밀번호', - 'Change Password' => '비밀번호 변경', - 'To reset your password click on this link:' => '비밀번호를 초기화 하시려면 링크를 눌러주세요:', - 'Last Password Reset' => '마지막 비밀번호 초기화', - 'The password has never been reinitialized.' => '비밀번호가 초기화되지 않았습니다', - 'Creation' => '생성', - 'Expiration' => '만료', - 'Password reset history' => '비밀번호 초기화 기록', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '칼럼 "%s"와 스웜라인 "%s"의 모든 할일이 성공적으로 종료되었습니다', - 'Do you really want to close all tasks of this column?' => '이 칼럼의 모든 할일을 종료 하시겠습니까?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '칼럼 "%s"와 스웜라인 "%s"의 할일 %d가 종료될 것입니다', - 'Close all tasks of this column' => '칼럼의 모든 할일 마치기', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '프로젝트 알림 방법으로 플러그인이 등록되지 않았습니다. 각각의 알림을 프로파일에서 설정하실 수 있습니다', - 'My dashboard' => '대시보드', - 'My profile' => '프로필', - 'Project owner: ' => '프로젝트 소유자', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '프로젝트 구분자는 선택사항이며, 숫자와 문자만 가능합니다. 예: MYPROJECT.', - // 'Project owner' => '', - 'Those dates are useful for the project Gantt chart.' => '이 날짜는 프로젝트 간트 차트에 사용됩니다', - 'Private projects do not have users and groups management.' => '비밀 프로젝트는 사용자나 관리 그룹이 소유하지 않습니다', - 'There is no project member.' => '프로젝트 맴버가 없습니다', - 'Priority' => '우선순위', - 'Task priority' => '할일의 우선순위', - 'General' => '일반적인', - 'Dates' => '날짜', - 'Default priority' => '기본 우선순위', - 'Lowest priority' => '낮은 우선순위', - 'Highest priority' => '높은 우선순위', - 'If you put zero to the low and high priority, this feature will be disabled.' => '만약 낮은/높은 우선순위에 0을 입력하면 이 특성은 비활성화됩니다', - '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' => '%s 시간', - 'Time spent:' => '소요 시간:', - 'Created:' => '생성:', - 'Modified:' => '수정;', - 'Completed:' => '완료:', - 'Started:' => '시작:', - 'Moved:' => '이동:', - 'Task #%d' => '할일 #%d', - 'Date and time format' => '날짜와 시간 형식', - 'Time format' => '시간 형식', - 'Start date: ' => '시작일: ', - 'End date: ' => '종료일: ', - 'New due date: ' => '새로운 만기일: ', - 'Start date changed: ' => '변경된 시작일: ', - 'Disable private projects' => '비밀 프로젝트 비활성화', - 'Do you really want to remove this custom filter: "%s"?' => '정의 필터를 삭제하시겠습니까: "%s"?', - 'Remove a custom filter' => '정의 필터 삭제', - 'User activated successfully.' => '사용자가 성공적으로 활성화되었습니다', - // 'Unable to enable this user.' => '', - 'User disabled successfully.' => '사용자가 성공적으로 비활성화되었습니다', - // 'Unable to disable this user.' => '', - 'All files have been uploaded successfully.' => '모든 파일이 성공적으로 업로드되었습니다', - 'View uploaded files' => '업로드 파일 보기', - 'The maximum allowed file size is %sB.' => '업로드 파일의 최대 크기는 %sB 입니다', - 'Choose files again' => '파일 다시 선택', - 'Drag and drop your files here' => '파일을 이곳으로 끌고오기', - 'choose files' => '파일 선택', - 'View profile' => '프로파일 보기', - 'Two Factor' => '이중', - 'Disable user' => '사용자 비활성화', - 'Do you really want to disable this user: "%s"?' => '사용자를 비활성화 시키겠습니까: "%s"?', - 'Enable user' => '사용자 활성화', - 'Do you really want to enable this user: "%s"?' => '사용자를 활성화 시키겠습니까: "%s"?', - 'Download' => '내려받기', - 'Uploaded: %s' => '올리기: %s', - 'Size: %s' => '크기: %s', - 'Uploaded by %s' => '%s로 올리기', - 'Filename' => '파일 이름', - 'Size' => '크기', - 'Column created successfully.' => '칼럼이 성공적으로 생성되었습니다', - 'Another column with the same name exists in the project' => '프로젝트에 동일한 이름의 칼럼이 있습니다', - 'Default filters' => '기본 필터', - 'Your board doesn\'t have any 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' => '이 값은 %d보다 커야 합니다', - 'Another swimlane with the same name exists in the project' => '프로젝트에 같은 이름의 스웜라인이 존재합니다', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '예: http://example.kanboard.net/ (절대적 URLs을 생성하는데 사용됨)', - 'Actions duplicated successfully.' => '행동이 성공적으로 복제되었습니다', - 'Unable to duplicate actions.' => '행동 복제 비활성화', - 'Add a new action' => '새로운 행동 추가', - 'Import from another project' => '다른 프로젝트에서 가져오기', - 'There is no action at the moment.' => '현재 행동이 없습니다', - 'Import actions from another project' => '다른 프로젝트에서 행동 가져오기', - 'There is no available project.' => '사용 가능한 프로젝트가 없습니다', - 'Local File' => '로컬 파일', - 'Configuration' => '구성', - 'PHP version:' => 'PHP 버전:', - // 'PHP SAPI:' => '', - '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' => '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.' => '', - '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' => '', - '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' => '', -); diff --git a/sources/app/Locale/my_MY/translations.php b/sources/app/Locale/my_MY/translations.php deleted file mode 100644 index 94e9478..0000000 --- a/sources/app/Locale/my_MY/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => '.', - 'number.thousands_separator' => ',', - 'None' => 'Tiada', - 'edit' => 'sunting', - 'Edit' => 'Sunting', - 'remove' => 'hapus', - 'Remove' => 'Hapus', - 'Yes' => 'Ya', - 'No' => 'Tidak', - 'cancel' => 'batal', - 'or' => 'atau', - 'Yellow' => 'Kuning', - 'Blue' => 'Biru', - 'Green' => 'Hijau', - 'Purple' => 'Ungu', - 'Red' => 'Merah', - 'Orange' => 'Oren', - 'Grey' => 'Kelabu', - 'Brown' => 'Coklat', - 'Deep Orange' => 'Oren Gelap', - 'Dark Grey' => 'Kelabu Malap', - 'Pink' => 'Merah Jambu', - 'Teal' => 'Teal', - 'Cyan' => 'Sian', - 'Lime' => 'Lime', - 'Light Green' => 'Hijau Muda', - 'Amber' => 'Amber', - 'Save' => 'Simpan', - 'Login' => 'Masuk', - 'Official website:' => 'Laman rasmi :', - 'Unassigned' => 'Belum ditugaskan', - 'View this task' => 'Lihat tugas ini', - 'Remove user' => 'Hapus pengguna', - 'Do you really want to remove this user: "%s"?' => 'Anda yakin mahu menghapus pengguna ini : « %s » ?', - 'All users' => 'Semua pengguna', - 'Username' => 'Nama pengguna', - 'Password' => 'Kata laluan', - 'Administrator' => 'Pentadbir', - 'Sign in' => 'Masuk', - 'Users' => 'Para Pengguna', - 'No user' => 'Tiada pengguna', - 'Forbidden' => 'Larangan', - 'Access Forbidden' => 'Akses Dilarang', - 'Edit user' => 'Ubah Pengguna', - 'Logout' => 'Keluar', - 'Bad username or password' => 'Nama pengguna atau kata laluan tidak sepadan', - 'Edit project' => 'Ubah projek', - 'Name' => 'Nama', - 'Projects' => 'Projek', - 'No project' => 'Tiada projek', - 'Project' => 'Projek', - 'Status' => 'Status', - 'Tasks' => 'Tugasan', - 'Board' => 'Papan', - 'Actions' => 'Tindakan', - 'Inactive' => 'Tidak Aktif', - 'Active' => 'Aktif', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Anda yakin mahu menghapus projek ini : « %s » ?', - 'Remove project' => 'Hapus projek', - 'Edit the board for "%s"' => 'Ubah papan untuk « %s »', - 'All projects' => 'Semua projek', - 'Add a new column' => 'Tambah kolom baru', - '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!', - 'Settings' => 'Penetapan', - 'Application settings' => 'Penetapan aplikasi', - 'Language' => 'Bahasa', - 'Webhook token:' => 'Token webhook :', - 'API token:' => 'Token API :', - 'Database size:' => 'Saiz pengkalan data:', - 'Download the database' => 'Muat turun pengkalan data', - 'Optimize the database' => 'Optimakan pengkalan data', - '(VACUUM command)' => '(perintah VACUUM)', - '(Gzip compressed Sqlite file)' => '(File Sqlite yang termampat Gzip)', - 'Close a task' => 'Tutup tugas', - 'Edit a task' => 'Sunting tugas', - 'Column' => 'Kolom', - 'Color' => 'Warna', - 'Assignee' => 'Orang yang ditugaskan', - 'Create another task' => 'Buat tugas lain', - 'New task' => 'Tugasan baru', - 'Open a task' => 'Buka tugas', - 'Do you really want to open this task: "%s"?' => 'Anda yakin untuk buka 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 : ', - 'Close this task' => 'Tutup tugas ini', - 'Open this task' => 'Buka tugas ini', - 'There is no description.' => 'Tidak ada keterangan.', - 'Add a new task' => 'Tambah tugas baru', - 'The username is required' => 'Nama pengguna adalah wajib', - '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 laluan adalah wajib', - 'This value must be an integer' => 'Nilai ini harus integer', - 'The username must be unique' => 'Nama pengguna semestinya unik', - 'The user id is required' => 'Id Pengguna adalah wajib', - 'Passwords don\'t match' => 'Kata laluan tidak sepadan', - 'The confirmation is required' => 'Pengesahan diperlukan', - 'The project is required' => 'Projek diperlukan', - 'The id is required' => 'Id diperlukan', - 'The project id is required' => 'Id projek diperlukan', - 'The project name is required' => 'Nama projek diperlukan', - 'The title is required' => 'Judul diperlukan', - 'Settings saved successfully.' => 'Penetapan berjaya disimpan.', - 'Unable to save your settings.' => 'Tidak dapat menyimpan penetapan anda.', - 'Database optimization done.' => 'Optimasi pengkalan data selesai.', - 'Your project have been created successfully.' => 'Projek anda berhasil dibuat.', - 'Unable to create your project.' => 'Tidak dapat membuat projek anda.', - 'Project updated successfully.' => 'projek berhasil diperbaharui.', - 'Unable to update this project.' => 'Tidak dapat memperbaharui projek ini.', - 'Unable to remove this project.' => 'Tidak dapat menghapus projek ini.', - 'Project removed successfully.' => 'projek berhasil dihapus.', - 'Project activated successfully.' => 'projek berhasil diaktivasi.', - 'Unable to activate this project.' => 'Tidak dapat mengaktifkan projek ini.', - 'Project disabled successfully.' => 'projek berhasil dinonaktifkan.', - 'Unable to disable this project.' => 'Tidak dapat menonaktifkan projek ini.', - 'Unable to open this task.' => 'Tidak dapat membuka tugas ini.', - '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 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 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.', - '%d closed tasks' => '%d tugas yang ditutup', - 'No task for this project' => 'Tidak ada tugas dalam projek ini', - 'Public link' => 'Pautan publik', - 'Timezone' => 'Zona waktu', - 'Sorry, I didn\'t find this information in my database!' => 'Maaf, saya tidak menemukan informasi ini dalam basis data saya !', - 'Page not found' => 'Halaman tidak ditemukan', - 'Complexity' => 'Kompleksitas', - '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 added successfully.' => 'Komentar berhasil ditambahkan.', - 'Unable to create your comment.' => 'Tidak dapat menambahkan komentar anda.', - 'Due Date' => 'Batas Tanggal Terakhir', - 'Invalid date' => 'Tanggal tidak valid', - '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.', - 'Remove an action' => 'Hapus tindakan', - 'Unable to remove this action.' => 'Tidak dapat menghapus tindakan ini', - 'Action removed successfully.' => 'Tindakan berhasil dihapus.', - 'Automatic actions for the project "%s"' => 'Tindakan otomatis untuk projek ini « %s »', - '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.', - '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 » ?', - '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', - 'Duplicate the task to another project' => 'Duplikasi tugas ke projek lain', - 'Move a task to another column' => 'Pindahkan tugas ke kolom lain', - 'Task modification' => 'Modifikasi tugas', - 'Task creation' => 'Membuat tugas', - 'Closing a task' => 'Menutup tugas', - 'Assign a color to a specific user' => 'Menetapkan warna untuk pengguna tertentu', - 'Column title' => 'Judul kolom', - 'Position' => 'Posisi', - 'Duplicate to another project' => 'Duplikasi ke projek lain', - 'Duplicate' => 'Duplikasi', - 'link' => 'Pautan', - 'Comment updated successfully.' => 'Komentar berhasil diperbaharui.', - 'Unable to update your comment.' => 'Tidak dapat memperbaharui 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 laluan saat ini untuk pengguna « %s »', - 'The current password is required' => 'Kata laluan saat ini diperlukan', - 'Wrong password' => 'Kata laluan 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', - 'No session.' => 'Tidak ada sesi.', - 'Expiration date' => 'Tanggal kadaluarsa', - 'Remember Me' => 'Ingat Saya', - 'Creation date' => 'Tanggal dibuat', - '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.' => 'Akaun eksternal anda tidak lagi terhubung ke profil anda.', - 'Unable to unlink your external account.' => 'Tidak dapat memutuskan Akaun eksternal anda.', - 'External authentication failed' => 'Otentifikasi eksternal gagal', - 'Your external account is linked to your profile successfully.' => 'Akaun eksternal anda berhasil dihubungkan ke profil anda.', - 'Email' => 'Email', - '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 » ?', - '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', - '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.', - '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 projek « %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 » ?', - 'All categories' => 'Semua kategori', - 'No category' => 'Tidak ada kategori', - 'The name is required' => 'Nama diperlukan', - 'Remove a file' => 'Hapus berkas', - '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 » ?', - 'Attachments' => 'Lampiran', - 'Edit the task' => 'Modifikasi tugas', - 'Add a comment' => 'Tambahkan komentar', - 'Edit a comment' => 'Modifikasi komentar', - 'Summary' => 'Ringkasan', - 'Time tracking' => 'Pelacakan waktu', - 'Estimate:' => 'Estimasi :', - 'Spent:' => 'Menghabiskan:', - 'Do you really want to remove this sub-task?' => 'Apakah anda yakin akan menghapus sub-tugas ini ?', - 'Remaining:' => 'Tersisa:', - 'hours' => 'jam', - 'spent' => 'menghabiskan', - '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', - 'Remove a sub-task' => 'Hapus sub-tugas', - 'The time must be a numeric value' => 'Waktu harus berisikan numerik', - 'Todo' => 'Yang harus dilakukan', - 'In progress' => 'Sedang 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 added successfully.' => 'Sub-tugas berhasil dibuat.', - 'Maximum size: ' => 'Ukuran maksimum: ', - 'Unable to upload the file.' => 'Tidak dapat mengunggah berkas.', - 'Display another project' => 'Lihat projek lain', - 'Created by %s' => 'Dibuat oleh %s', - 'Tasks Export' => 'Ekspor Tugas', - 'Tasks exportation for "%s"' => 'Tugas di ekspor untuk « %s »', - 'Start Date' => 'Tanggal Mulai', - 'End Date' => 'Tanggal Berakhir', - 'Execute' => 'Eksekusi', - 'Task Id' => 'Id Tugas', - 'Creator' => 'Pembuat', - 'Modification date' => 'Tanggal modifikasi', - 'Completion date' => 'Tanggal penyelesaian', - 'Clone' => 'Klon', - 'Project cloned successfully.' => 'Kloning projek berhasil.', - 'Unable to clone this project.' => 'Tidak dapat mengkloning projek.', - 'Enable email notifications' => 'Aktifkan pemberitahuan dari email', - '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 :', - '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' => 'Lampirkan baru', - 'New comment' => 'Komentar baru', - 'Comment updated' => 'Komentar diperbaharui', - 'New subtask' => 'Sub-tugas baru', - 'Subtask updated' => 'Sub-tugas diperbaharui', - 'Task updated' => 'Tugas diperbaharui', - 'Task closed' => 'Tugas ditutup', - 'Task opened' => 'Tugas dibuka', - 'I want to receive notifications only for those projects:' => 'Saya ingin menerima pemberitahuan hanya untuk projek-projek yang dipilih :', - 'view the task on Kanboard' => 'lihat tugas di Kanboard', - 'Public access' => 'Akses awam', - 'Active tasks' => 'Tugas aktif', - 'Disable public access' => 'Nyahaktifkan akses awam', - 'Enable public access' => 'Aktifkan akses awam', - 'Public access disabled' => 'Akses awam dinyahaktif', - 'Do you really want to disable this project: "%s"?' => 'Anda yakin menyah-aktifkan projek ini : « %s » ?', - 'Do you really want to enable this project: "%s"?' => 'Anda yakin untuk mengaktifkan projek ini : « %s » ?', - 'Project activation' => 'Aktifkan projek', - 'Move the task to another project' => 'Pindahkan tugas ke projek lain', - 'Move to another project' => 'Pindahkan ke projek lain', - 'Do you really want to duplicate this task?' => 'Anda yakin mengembarkan tugas ini ?', - 'Duplicate a task' => 'Kembarkan tugas', - 'External accounts' => 'Akaun luaran', - 'Account type' => 'Jenis Akaun', - 'Local' => 'Lokal', - 'Remote' => 'Jauh', - 'Enabled' => 'Aktif', - 'Disabled' => 'Tidak aktif', - 'Username:' => 'Nama pengguna :', - 'Name:' => 'Nama:', - 'Email:' => 'Emel:', - 'Notifications:' => 'Makluman:', - 'Notifications' => 'Makluman', - 'Account type:' => 'Jenis Akaun :', - 'Edit profile' => 'Sunting profil', - 'Change password' => 'Rubah kata sandri', - 'Password modification' => 'Modifikasi kata laluan', - 'External authentications' => 'Otentifikasi eksternal', - 'Never connected.' => 'Tidak pernah terhubung.', - 'No external authentication enabled.' => 'Tidak ada otentifikasi eksternal yang aktif.', - 'Password modified successfully.' => 'Kata laluan telah berjaya ditukar.', - 'Unable to change the password.' => 'Tidak dapat merubah kata laluanr.', - 'Change category' => 'Tukar kategori', - '%s updated the task %s' => '%s memperbaharui 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 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', - 'Not assigned, estimate of %sh' => 'Tiada yang ditugaskan, perkiraan %sh', - '%s updated a comment on the task %s' => '%s memperbaharui 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 open the task #%d' => '%s membuka tugas n°%d', - '%s moved the task #%d to the column "%s"' => '%s memindahkan tugas n°%d ke kolom « %s »', - '%s moved the task #%d to the position %d in the column "%s"' => '%s memindahkan tugas n°%d ke posisi n°%d dalam kolom « %s »', - 'Activity' => 'Aktifitas', - 'Default values are "%s"' => 'Standar nilai adalah« %s »', - 'Default columns for new projects (Comma-separated)' => 'Kolom default untuk projek baru (dipisahkan dengan koma)', - 'Task assignee change' => 'Mengubah orang ditugaskan untuk tugas', - '%s change 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 laluan baru untuk pengguna « %s »', - 'Choose an event' => 'Pilih sebuah 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', - 'Reference' => 'Referensi', - 'Label' => 'Label', - 'Database' => 'Pengkalan data', - 'About' => 'Tentang', - 'Database driver:' => 'Driver pengkalan data:', - 'Board settings' => 'Pengaturan papan', - 'Webhook settings' => 'Penetapan webhook', - 'Reset token' => 'Menetap semula 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 saat)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekuensi dalam detik (0 untuk menonaktifkan fitur ini, standar 10 detik)', - 'Application URL' => 'URL Aplikasi', - 'Token regenerated.' => 'Token diregenerasi.', - 'Date format' => 'Format tarikh', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO selalunya diterima, contoh: « %s » et « %s »', - 'New private project' => 'Projek peribadi baharu', - 'This project is private' => 'projek ini adalah peribadi', - 'Add' => 'Tambah', - 'Start date' => 'Tarikh mula', - 'Time estimated' => 'Anggaran masa', - 'There is nothing assigned to you.' => 'Tidak ada yang diberikan kepada 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 projek ini', - 'Everybody have access to this project.' => 'Semua orang mendapat akses untuk projek ini.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Buat komentar dari pemasok eksternal', - 'Project management' => 'Manajemen projek', - 'My projects' => 'projek saya', - 'Columns' => 'Kolom', - 'Task' => 'Tugas', - 'Your are not member of any project.' => 'Anda bukan anggota dari setiap projek.', - 'Percentage' => 'Persentasi', - 'Number of tasks' => 'Jumlah dari tugas', - 'Task distribution' => 'Pembagian tugas', - 'Reportings' => 'Pelaporan', - 'Task repartition for "%s"' => 'Pembagian tugas untuk « %s »', - 'Analytics' => 'Analitis', - 'Subtask' => 'Subtugas', - 'My subtasks' => 'Subtugas saya', - 'User repartition' => 'Partisi ulang pengguna', - 'User repartition for "%s"' => 'Partisi ulang pengguna untuk « %s »', - 'Clone this project' => 'Gandakan projek 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 projek 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', - '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', - 'Cumulative flow diagram' => 'Diagram alir kumulatif', - 'Cumulative flow diagram for "%s"' => 'Diagram alir kumulatif untuk « %s »', - 'Daily project summary' => 'Ringkasan projek harian', - 'Daily project summary export' => 'Ekspot ringkasan projek harian', - 'Daily project summary export for "%s"' => 'Ekspor ringkasan projek harian untuk « %s »', - 'Exports' => 'Ekspor', - 'This export contains the number of tasks per column grouped per day.' => 'Ekspor ini berisi jumlah dari tugas per kolom dikelompokan perhari.', - 'Active swimlanes' => 'Swimlanes aktif', - 'Add a new swimlane' => 'Tambah swimlane baharu', - 'Change default swimlane' => 'Tukar piawai swimlane', - 'Default swimlane' => 'Piawai swimlane', - 'Do you really want to remove this swimlane: "%s"?' => 'Anda yakin untuk menghapus swimlane ini : « %s » ?', - 'Inactive swimlanes' => 'Swimlanes tidak aktif', - 'Remove a swimlane' => 'Padam swimlane', - 'Show default swimlane' => 'Tampilkan piawai swimlane', - 'Swimlane modification for the project "%s"' => 'Modifikasi swimlane untuk projek « %s »', - 'Swimlane removed successfully.' => 'Swimlane telah dipadamkan.', - 'Swimlanes' => 'Swimlanes', - 'Swimlane updated successfully.' => 'Swimlane telah dikemaskini.', - 'The default swimlane have been updated successfully.' => 'Standar swimlane berhasil diperbaharui.', - '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 Ciri, Pembaikan »', - 'Default categories for new projects (Comma-separated)' => 'Piawaian kategori untuk projek baru (asingkan guna koma)', - 'Integrations' => 'Integrasi', - 'Integration with third-party services' => 'Integrasi dengan khidmat pihak ketiga', - 'Subtask Id' => 'Id Subtugas', - 'Subtasks' => 'Subtugas', - 'Subtasks Export' => 'Ekspot Subtugas', - 'Subtasks exportation for "%s"' => 'Ekspor subtugas untuk « %s »', - 'Task Title' => 'Judul Tugas', - 'Untitled' => 'Tanpa nama', - 'Application default' => 'Aplikasi Piawaian', - 'Language:' => 'Bahasa:', - 'Timezone:' => 'Zon masa:', - 'All columns' => 'Semua kolom', - 'Calendar' => 'Kalender', - 'Next' => 'Selanjutnya', - '#%d' => 'n°%d', - 'All swimlanes' => 'Semua swimlane', - 'All colors' => 'Semua warna', - 'Moved to column %s' => 'Pindah ke kolom %s', - 'User dashboard' => 'Papan Kenyataan 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 projek mana yang ingin anda duplikasi?', - 'Disallow login form' => 'Larang formulir masuk', - 'Start' => 'Mula', - 'End' => 'Selesai', - 'Task age in days' => 'Usia tugas dalam bentuk harian', - 'Days in this column' => 'Hari dalam kolom ini', - '%dd' => '%dj', - 'Add a new link' => 'Tambah Pautan baru', - 'Do you really want to remove this link: "%s"?' => 'Anda yakin akan menghapus Pautan ini : « %s » ?', - 'Do you really want to remove this link with task #%d?' => 'Anda yakin akan menghapus Pautan ini dengan tugas n°%d ?', - 'Field required' => 'Medan diperlukan', - 'Link added successfully.' => 'Pautan berhasil ditambahkan.', - 'Link updated successfully.' => 'Pautan berhasil diperbaharui.', - 'Link removed successfully.' => 'Pautan berhasil dihapus.', - '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', - 'Unable to create your link.' => 'Tidak dapat membuat Pautan anda.', - 'Unable to update your link.' => 'Tidak dapat memperbaharui Pautan anda.', - 'Unable to remove this link.' => 'Tidak dapat menghapus Pautan ini.', - 'relates to' => 'berhubungan dengan', - 'blocks' => 'blok', - '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', - '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', - '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', - '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 :', - 'Currency' => 'Mata uang', - 'Private project' => 'projek pribadi', - 'AUD - Australian Dollar' => 'AUD - Dollar Australia', - 'CAD - Canadian Dollar' => 'CAD - Dollar Kanada', - 'CHF - Swiss Francs' => 'CHF - Swiss Prancis', - 'Custom Stylesheet' => 'Kustomisasi Stylesheet', - 'download' => 'unduh', - 'EUR - Euro' => 'EUR - Euro', - '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', - 'RSD - Serbian dinar' => 'RSD - Dinar Serbia', - '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', - 'Move the task to another column when assignee is cleared' => 'Pindahkan tugas ke kolom lain ketika orang yang ditugaskan dibersihkan', - 'Source column' => 'Sumber kolom', - 'Transitions' => 'Transisi', - 'Executer' => 'Eksekusi', - 'Time spent in the column' => 'Waktu yang dihabiskan dalam kolom', - 'Task transitions' => 'Transisi tugas', - 'Task transitions export' => 'Ekspor transisi tugas', - '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', - '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', - '%s remove the assignee of the task %s' => '%s menghapus penugasan dari tugas %s', - 'Enable Gravatar images' => 'Mengaktifkan 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.', - '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', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Grafik Burndown untku « %s »', - '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.' => '', - '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 Pautan', - 'Start to type task title...' => 'Mulai mengetik judul tugas...', - 'A task cannot be linked to itself' => 'Sebuah tugas tidak dapat dikaitkan dengan dirinya sendiri', - 'The exact same link already exists' => 'Pautan yang sama persis sudah ada', - 'Recurrent task is scheduled to be generated' => 'Tugas berulang dijadwalkan akan dihasilkan', - 'Score' => 'Skor', - 'The identifier must be unique' => 'Identifier harus unik', - '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', - '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: ', - '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:', - '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', - 'Year(s)' => 'Tahun', - 'Calendar settings' => 'Pengaturan kalender', - 'Project calendar view' => 'Tampilan kalender projek', - 'Project settings' => 'Pengaturan projek', - 'Show subtasks based on the time tracking' => 'Tampilkan subtugas 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' => 'Otomatikkan pengemaskinian tanggal', - 'iCal feed' => 'iCal feed', - 'Preferences' => 'Keutamaan', - 'Security' => 'Keamanan', - 'Two factor authentication disabled' => 'Otentifikasi dua faktor dimatikan', - 'Two factor authentication enabled' => 'Otentifikasi dua faktor dihidupkan', - 'Unable to update this user.' => 'Tidak dapat memperbarui pengguna ini.', - 'There is no user management for private projects.' => 'Tidak ada manajemen pengguna untuk projek-projek pribadi.', - 'User that will receive the email' => 'Pengguna yang akan menerima email', - 'Email subject' => 'Subjek Emel', - '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', - 'Column change' => 'Kolom berubah', - 'Position change' => 'Posisi berubah', - 'Swimlane change' => 'Swimlane berubah', - 'Assignee change' => 'Penerima berubah', - '[%s] Overdue tasks' => '[%s] Tugas terlambat', - '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 swimlane "%s"' => '%s memindahkan tugas n°%d ke swimlane « %s »', - '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.', - '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 projek 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', - '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', - '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', - 'The description has been modified:' => 'Deskripsi telah dimodifikasi', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Apakah anda yakin akan menutup tugas « %s » beserta semua sub-tugasnya ?', - 'I want to receive notifications for:' => 'Saya ingin menerima pemberitahuan untuk :', - 'All tasks' => 'Semua tugas', - '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', - 'Only for tasks created by me and assigned to me' => 'Hanya untuk tugas yang dibuat oleh saya dan ditugaskan ke saya', - '%%Y-%%m-%%d' => '%%d/%%m/%%Y', - 'Total for all columns' => 'Total untuk semua kolom', - 'You need at least 2 days of data to show the chart.' => 'Anda memerlukan setidaknya 2 hari dari data yang menunjukkan grafik.', - '<15m' => '<15m', - '<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', - 'Reset filters' => 'Reset ulang filter', - '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', - 'Not assigned' => 'Tidak ditugaskan', - 'View advanced search syntax' => 'Lihat sintaks pencarian lanjutan', - 'Overview' => 'Ikhtisar', - '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.', - 'No tasks found.' => 'Tidak ada tugas yang ditemukan.', - 'Keyboard shortcut: "%s"' => 'Keyboard shortcut : « %s »', - 'List' => 'Daftar', - 'Filter' => 'Filter', - 'Advanced search' => 'Pencarian lanjutan', - 'Example of query: ' => 'Contoh dari query : ', - 'Search by project: ' => 'Pencarian berdasarkan projek : ', - '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 : ', - 'Lead and Cycle time for "%s"' => 'Memimpin dan Siklus waktu untuk « %s »', - 'Average time spent into each column for "%s"' => 'Rata-rata waktu yang dihabiskan dalam setiap kolom untuk « %s »', - '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', - '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.', - '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 : ', - '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.', - 'Set automatically the start date' => 'Secara otomatis mengatur tanggal mulai', - 'Edit Authentication' => 'Modifikasi 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 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.', - 'Trigger automatically subtask time tracking' => 'Picu pengesanan subtugas secara otomatik', - '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', - 'no category' => 'tiada kategori', - 'Current assignee: %s' => 'Saat ini ditugaskan pada: %s', - 'not assigned' => 'Belum ditugaskan', - 'Author:' => 'Penulis:', - 'contributors' => 'Penggiat', - 'License:' => 'Lesen:', - 'License' => 'Lesen', - 'Enter the text below' => 'Masukkan teks di bawah', - 'Gantt chart for %s' => 'Carta Gantt untuk %s', - 'Sort by position' => 'Urutkan berdasarkan posisi', - 'Sort by date' => 'Urutkan berdasarkan tanggal', - 'Add task' => 'Tambah tugas', - 'Start date:' => 'Tanggal mulai:', - 'Due date:' => 'Batas waktu:', - 'There is no start date or due date for this task.' => 'Tiada 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.' => 'Tiada tugas didalam projek anda.', - 'Gantt chart' => 'Carta Gantt', - 'People who are project managers' => 'Orang-orang yang menjadi pengurus projek', - 'People who are project members' => 'Orang-orang yang menjadi anggota projek', - 'NOK - Norwegian Krone' => 'NOK - Krone Norwegia', - 'Show this column' => 'Perlihatkan kolom ini', - 'Hide this column' => 'Sembunyikan kolom ini', - 'open file' => 'buka fail', - 'End date' => 'Waktu berakhir', - 'Users overview' => 'Ikhtisar pengguna', - 'Members' => 'Anggota', - 'Shared project' => 'projek bersama', - 'Project managers' => 'Pengurus projek', - 'Gantt chart for all projects' => 'Carta Gantt untuk kesemua projek', - 'Projects list' => 'Senarai projek', - 'Gantt chart for this project' => 'Carta Gantt untuk projek ini', - 'Project board' => 'Papan projek', - 'End date:' => 'Waktu berakhir :', - 'There is no start date or end date for this project.' => 'Tidak ada waktu mula atau waktu berakhir pada projek ini', - 'Projects Gantt chart' => 'projekkan carta Gantt', - 'Change task color when using a specific task link' => 'Rubah warna tugas ketika menggunakan Pautan tugas yang spesifik', - 'Task link creation or modification' => 'Pautan tugas pada penciptaan atau penyuntingan', - 'Milestone' => 'Batu Tanda', - 'Documentation: %s' => 'Dokumentasi : %s', - 'Switch to the Gantt chart view' => 'Beralih ke tampilan Carta Gantt', - 'Reset the search/filter box' => 'Tetap semula pencarian/saringan', - 'Documentation' => 'Dokumentasi', - 'Table of contents' => 'Isi kandungan', - 'Gantt' => 'Gantt', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - 'Link type' => 'Jenis pautan', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - 'Role:' => 'Peranan', - 'Project members' => 'Anggota projek', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - 'Creation' => 'Ciptaan', - 'Expiration' => 'Jangka hayat', - 'Password reset history' => 'Sirah tetap semula kata laluan', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // 'Unable to fetch link information.' => '', - // 'Daily background job for tasks' => '', - // 'Auto' => '', - // 'Related' => '', - // 'Attachment' => '', - // 'Title not found' => '', - // 'Web Link' => '', - // 'External links' => '', - // 'Add external link' => '', - // 'Type' => '', - // 'Dependency' => '', - // 'Add internal link' => '', - // 'Add a new external link' => '', - // 'Edit external link' => '', - // 'External link' => '', - // 'Copy and paste your link here...' => '', - // 'URL' => '', - // 'Internal links' => '', - // 'Assign to me' => '', - // 'Me' => '', - // 'Do not duplicate anything' => '', - // 'Projects management' => '', - // 'Users management' => '', - // 'Groups management' => '', - // 'Create from another project' => '', - // 'open' => '', - // 'closed' => '', - // 'Priority:' => '', - // 'Reference:' => '', - // 'Complexity:' => '', - // 'Swimlane:' => '', - // 'Column:' => '', - // 'Position:' => '', - // 'Creator:' => '', - // 'Time estimated:' => '', - // '%s hours' => '', - // 'Time spent:' => '', - // 'Created:' => '', - // 'Modified:' => '', - // 'Completed:' => '', - // 'Started:' => '', - // 'Moved:' => '', - // 'Task #%d' => '', - // 'Date and time format' => '', - // 'Time format' => '', - // 'Start date: ' => '', - // 'End date: ' => '', - // 'New due date: ' => '', - // 'Start date changed: ' => '', - // 'Disable private projects' => '', - // 'Do you really want to remove this custom filter: "%s"?' => '', - // 'Remove a custom filter' => '', - // 'User activated successfully.' => '', - // 'Unable to enable this user.' => '', - // 'User disabled successfully.' => '', - // 'Unable to disable this user.' => '', - // 'All files have been uploaded successfully.' => '', - // 'View uploaded files' => '', - // 'The maximum allowed file size is %sB.' => '', - // 'Choose files again' => '', - // 'Drag and drop your files here' => '', - // 'choose files' => '', - // 'View profile' => '', - // 'Two Factor' => '', - // 'Disable user' => '', - // 'Do you really want to disable this user: "%s"?' => '', - // 'Enable user' => '', - // 'Do you really want to enable this user: "%s"?' => '', - // 'Download' => '', - // 'Uploaded: %s' => '', - // 'Size: %s' => '', - // 'Uploaded by %s' => '', - // 'Filename' => '', - // 'Size' => '', - // 'Column created successfully.' => '', - // 'Another column with the same name exists in the project' => '', - // 'Default filters' => '', - // 'Your board doesn\'t have any 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"' => 'Tugas terlambat untuk projek « %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' => '', -); diff --git a/sources/app/Locale/nb_NO/translations.php b/sources/app/Locale/nb_NO/translations.php deleted file mode 100644 index cfd7ba1..0000000 --- a/sources/app/Locale/nb_NO/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'Ingen', - 'edit' => 'rediger', - 'Edit' => 'Rediger', - 'remove' => 'fjern', - 'Remove' => 'Fjern', - 'Yes' => 'Ja', - 'No' => 'Nei', - 'cancel' => 'avbryt', - 'or' => 'eller', - 'Yellow' => 'Gul', - 'Blue' => 'Blå', - 'Green' => 'Grønn', - 'Purple' => 'Lilla', - 'Red' => 'Rød', - 'Orange' => 'Orange', - 'Grey' => 'Grå', - // 'Brown' => '', - // 'Deep Orange' => '', - // 'Dark Grey' => '', - // 'Pink' => '', - // 'Teal' => '', - // 'Cyan' => '', - // 'Lime' => '', - // 'Light Green' => '', - // 'Amber' => '', - 'Save' => 'Lagre', - 'Login' => 'Logg inn', - 'Official website:' => 'Offisiell webside:', - 'Unassigned' => 'Ikke tildelt', - 'View this task' => 'Se denne oppgaven', - 'Remove user' => 'Fjern bruker', - 'Do you really want to remove this user: "%s"?' => 'Vil du fjerne denne brukeren: "%s"?', - 'All users' => 'Alle brukere', - 'Username' => 'Brukernavn', - 'Password' => 'Passord', - 'Administrator' => 'Administrator', - 'Sign in' => 'Logg inn', - 'Users' => 'Brukere', - 'No user' => 'Ingen bruker', - 'Forbidden' => 'Ikke tillatt', - 'Access Forbidden' => 'Adgang ikke tillatt', - 'Edit user' => 'Rediger bruker', - 'Logout' => 'Logg ut', - 'Bad username or password' => 'Feil brukernavn eller passord', - 'Edit project' => 'Endre prosjekt', - 'Name' => 'Navn', - 'Projects' => 'Prosjekter', - 'No project' => 'Ingen prosjekter', - 'Project' => 'Prosjekt', - 'Status' => 'Status', - 'Tasks' => 'Oppgaver', - 'Board' => 'Hovedside', - 'Actions' => 'Handlinger', - 'Inactive' => 'Inaktiv', - 'Active' => 'Aktiv', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Vil du fjerne dette prosjektet: "%s"?', - 'Remove project' => 'Fjern prosjekt', - 'Edit the board for "%s"' => 'Endre prosjektsiden for "%s"', - 'All projects' => 'Alle prosjekter', - 'Add a new column' => 'Legg til en ny kolonne', - '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', - 'Settings' => 'Innstillinger', - 'Application settings' => 'Applikasjonsinnstillinger', - 'Language' => 'Språk', - 'Webhook token:' => 'Webhook token:', - 'API token:' => 'API Token:', - 'Database size:' => 'Databasestørrelse:', - 'Download the database' => 'Last ned databasen', - 'Optimize the database' => 'Optimaliser databasen', - '(VACUUM command)' => '(VACUUM kommando)', - '(Gzip compressed Sqlite file)' => '(Gzip-komprimert Sqlite fil)', - 'Close a task' => 'Lukk en oppgave', - 'Edit a task' => 'Endre en oppgave', - 'Column' => 'Kolonne', - 'Color' => 'Farge', - 'Assignee' => 'Tildelt', - 'Create another task' => 'Opprett en annen oppgave', - 'New task' => 'Ny oppgave', - 'Open a task' => 'Åpne en oppgave', - 'Do you really want to open this task: "%s"?' => 'Vil du åpne denne oppgaven: "%s"?', - 'Back to the board' => 'Tilbake til prosjektsiden', - 'There is nobody assigned' => 'Mangler tildeling', - 'Column on the board:' => 'Kolonne:', - 'Close this task' => 'Lukk oppgaven', - 'Open this task' => 'Åpne denne oppgaven', - 'There is no description.' => 'Det er ingen beskrivelse.', - 'Add a new task' => 'Opprett ny oppgave', - 'The username is required' => 'Brukernavn er påkrevd', - 'The maximum length is %d characters' => 'Den maksimale lengden er %d tegn', - 'The minimum length is %d characters' => 'Den minimale lengden er %d tegn', - 'The password is required' => 'Passord er påkrevet', - 'This value must be an integer' => 'Denne verdien skal være et tall', - 'The username must be unique' => 'Brukernavnet skal være unikt', - 'The user id is required' => 'Bruker-id er påkrevet', - 'Passwords don\'t match' => 'Passordene stemmer ikke overens', - 'The confirmation is required' => 'Bekreftelse er nødvendig', - 'The project is required' => 'Prosjektet er påkrevet', - 'The id is required' => 'Id\'en er pøøkrevet', - 'The project id is required' => 'Prosjektet-id er påkrevet', - 'The project name is required' => 'Prosjektnavn er påkrevet', - 'The title is required' => 'Tittel er pårevet', - 'Settings saved successfully.' => 'Innstillinger lagret.', - 'Unable to save your settings.' => 'Innstillinger kunne ikke lagres.', - 'Database optimization done.' => 'Databaseoptimering er fullført.', - 'Your project have been created successfully.' => 'Ditt prosjekt er opprettet.', - 'Unable to create your project.' => 'Prosjektet kunne ikke opprettes', - 'Project updated successfully.' => 'Prosjektet er oppdatert.', - 'Unable to update this project.' => 'Prosjektet kunne ikke oppdateres.', - 'Unable to remove this project.' => 'Prosjektet kunne ikke slettes.', - 'Project removed successfully.' => 'Prosjektet er slettet.', - 'Project activated successfully.' => 'Prosjektet er aktivert.', - 'Unable to activate this project.' => 'Prosjektet kunne ikke aktiveres.', - 'Project disabled successfully.' => 'Prosjektet er deaktiveret.', - 'Unable to disable this project.' => 'Prosjektet kunne ikke deaktiveres.', - 'Unable to open this task.' => 'Oppgaven kunne ikke åpnes.', - 'Task opened successfully.' => 'Oppgaven er åpnet.', - 'Unable to close this task.' => 'Oppgaven kunne ikke åpnes.', - 'Task closed successfully.' => 'Oppgaven er lukket.', - 'Unable to update your task.' => 'Oppgaven kunne ikke oppdateres.', - 'Task updated successfully.' => 'Oppgaven er oppdatert.', - 'Unable to create your task.' => 'Oppgave kunne ikke opprettes.', - 'Task created successfully.' => 'Oppgaven er opprettet.', - 'User created successfully.' => 'Brukeren er opprettet.', - 'Unable to create your user.' => 'Brukeren kunne ikke opprettes.', - 'User updated successfully.' => 'Brukeren er oppdatert', - 'Unable to update your user.' => 'Din bruker kunne ikke oppdateres.', - 'User removed successfully.' => 'Brukeren er fjernet.', - 'Unable to remove this user.' => 'Brukeren kunne ikke slettes.', - 'Board updated successfully.' => 'Hovedsiden er oppdatert.', - 'Ready' => 'Klar', - 'Backlog' => 'Backlog', - 'Work in progress' => 'Under arbeid', - 'Done' => 'Utført', - 'Application version:' => 'Versjon:', - 'Id' => 'ID', - '%d closed tasks' => '%d lukkede oppgaver', - 'No task for this project' => 'Ingen oppgaver i dette prosjektet', - 'Public link' => 'Offentligt lenke', - 'Timezone' => 'Tidssone', - 'Sorry, I didn\'t find this information in my database!' => 'Denne informasjonen kunne ikke finnes i databasen!', - 'Page not found' => 'Siden er ikke funnet', - 'Complexity' => 'Kompleksitet', - 'Task limit' => 'Oppgave begrensning', - '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', - 'Invalid date' => 'Ugyldig dato', - 'Automatic actions' => 'Automatiske handlinger', - 'Your automatic action have been created successfully.' => 'Din automatiske handling er opprettet.', - 'Unable to create your automatic action.' => 'Din automatiske handling kunne ikke opprettes.', - 'Remove an action' => 'Fjern en handling', - 'Unable to remove this action.' => 'Handlingen kunne ikke fjernes.', - 'Action removed successfully.' => 'Handlingen er fjernet.', - 'Automatic actions for the project "%s"' => 'Automatiske handlinger for prosjektet "%s"', - 'Add an action' => 'Legg til en handling', - 'Event name' => 'Hendelsehet', - 'Action name' => 'Handling', - 'Action parameters' => 'Handlingsparametre', - 'Action' => 'Handling', - 'Event' => 'Hendelse', - 'When the selected event occurs execute the corresponding action.' => 'Når den valgte hendelsen oppstår, utfør tilsvarende handling.', - 'Next step' => 'Neste', - 'Define action parameters' => 'Definer handlingsparametre', - 'Do you really want to remove this action: "%s"?' => 'Vil du slette denne handlingen: "%s"?', - 'Remove an automatic action' => 'Fjern en automatisk handling', - 'Assign the task to a specific user' => 'Tildel oppgaven til en bestemt bruker', - 'Assign the task to the person who does the action' => 'Tildel oppgaven til den person, som utfører handlingen', - 'Duplicate the task to another project' => 'Kopier oppgaven til et annet prosjekt', - 'Move a task to another column' => 'Flytt oppgaven til en annen kolonne', - 'Task modification' => 'Oppgaveendring', - 'Task creation' => 'Oppgaveoprettelse', - 'Closing a task' => 'Lukke en oppgave', - 'Assign a color to a specific user' => 'Tildel en farge til en bestemt bruker', - 'Column title' => 'Kolonne tittel', - 'Position' => 'Posisjon', - 'Duplicate to another project' => 'Kopier til et annet prosjekt', - 'Duplicate' => 'Kopier', - 'link' => 'link', - 'Comment updated successfully.' => 'Kommentar oppdatert.', - 'Unable to update your comment.' => 'Din kommentar kunne ikke oppdateres.', - 'Remove a comment' => 'Fjern en kommentar', - 'Comment removed successfully.' => 'Kommentaren ble fjernet.', - 'Unable to remove this comment.' => 'Kommentaren kunne ikke fjernes.', - 'Do you really want to remove this comment?' => 'Vil du fjerne denne kommentaren?', - 'Current password for the user "%s"' => 'Aktivt passord for brukeren "%s"', - 'The current password is required' => 'Passord er påkrevet', - 'Wrong password' => 'Feil passord', - 'Unknown' => 'Ukjent', - 'Last logins' => 'Siste innlogging', - 'Login date' => 'Login dato', - 'Authentication method' => 'Godkjenningsmetode', - 'IP address' => 'IP Adresse', - 'User agent' => 'User Agent', - 'Persistent connections' => 'Varige forbindelser', - 'No session.' => 'Ingen session.', - 'Expiration date' => 'Utløpsdato', - 'Remember Me' => 'Husk meg', - 'Creation date' => 'Opprettelsesdato', - 'Everybody' => 'Alle', - 'Open' => 'Åpen', - 'Closed' => 'Lukket', - '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', - 'Email address invalid' => 'Ugyldig epost', - // 'Your external account is not linked anymore to your profile.' => '', - // 'Unable to unlink your external account.' => '', - // 'External authentication failed' => '', - // 'Your external account is linked to your profile successfully.' => '', - 'Email' => 'Epost', - 'Task removed successfully.' => 'Oppgaven er fjernet.', - 'Unable to remove this task.' => 'Oppgaven kunne ikke fjernes.', - 'Remove a task' => 'Fjern en oppgave', - 'Do you really want to remove this task: "%s"?' => 'Vil du fjerne denne oppgaven: "%s"?', - 'Assign automatically a color based on a category' => 'Tildel automatisk en farge baseret for en kategori', - 'Assign automatically a category based on a color' => 'Tildel automatisk en kategori basert på en farve', - 'Task creation or modification' => 'Oppgaveopprettelse eller endring', - 'Category' => 'Kategori', - 'Category:' => 'Kategori:', - 'Categories' => 'Kategorier', - 'Your category have been created successfully.' => 'Kategorien er opprettet.', - 'Unable to create your category.' => 'Kategorien kunne ikke opprettes.', - 'Your category have been updated successfully.' => 'Kategorien er oppdatert.', - 'Unable to update your category.' => 'Kategorien kunne ikke oppdateres.', - 'Remove a category' => 'Fjern en kategori', - 'Category removed successfully.' => 'Kategorien er fjernet.', - 'Unable to remove this category.' => 'Kategorien kunne ikke fjernes.', - 'Category modification for the project "%s"' => 'Endring av kategori for prosjektet "%s"', - 'Category Name' => 'Kategorinavn', - 'Add a new category' => 'Legg til ny kategori', - 'Do you really want to remove this category: "%s"?' => 'Vil du fjerne kategorien: "%s"?', - 'All categories' => 'Alle kategorier', - 'No category' => 'Ingen kategori', - 'The name is required' => 'Navnet er påkrevet', - 'Remove a file' => 'Fjern en fil', - 'Unable to remove this file.' => 'Filen kunne ikke fjernes.', - 'File removed successfully.' => 'Filen er fjernet.', - 'Attach a document' => 'Legg til et dokument', - 'Do you really want to remove this file: "%s"?' => 'Vil du fjerne filen: "%s"?', - 'Attachments' => 'Vedlegg', - 'Edit the task' => 'Rediger oppgaven', - 'Add a comment' => 'Legg til en kommentar', - 'Edit a comment' => 'Rediger en kommentar', - 'Summary' => 'Sammendrag', - 'Time tracking' => 'Tidsregistrering', - 'Estimate:' => 'Estimat:', - 'Spent:' => 'Brukt:', - 'Do you really want to remove this sub-task?' => 'Vil du fjerne denne deloppgaven?', - 'Remaining:' => 'Gjenværende:', - 'hours' => 'timer', - 'spent' => 'brukt', - 'estimated' => 'estimat', - 'Sub-Tasks' => 'Deloppgave', - 'Add a sub-task' => 'Legg til en deloppgave', - 'Original estimate' => 'Original estimering', - 'Create another sub-task' => 'Legg til en ny deloppgave', - 'Time spent' => 'Tidsforbruk', - 'Edit a sub-task' => 'Rediger en deloppgave', - 'Remove a sub-task' => 'Fjern en deloppgave', - 'The time must be a numeric value' => 'Tiden skal være en nummerisk erdi', - 'Todo' => 'Gjøremål', - 'In progress' => 'Under arbeid', - 'Sub-task removed successfully.' => 'Deloppgaven er fjernet.', - 'Unable to remove this sub-task.' => 'Deloppgaven kunne ikke fjernes.', - 'Sub-task updated successfully.' => 'Deloppgaven er opdateret.', - 'Unable to update your sub-task.' => 'Deloppgaven kunne ikke opdateres.', - 'Unable to create your sub-task.' => 'Deloppgaven kunne ikke oprettes.', - 'Sub-task added successfully.' => 'Deloppgaven er lagt til.', - 'Maximum size: ' => 'Maksimum størrelse: ', - 'Unable to upload the file.' => 'Filen kunne ikke lastes opp.', - 'Display another project' => 'Vis annet prosjekt...', - 'Created by %s' => 'Opprettet av %s', - 'Tasks Export' => 'Oppgave eksport', - 'Tasks exportation for "%s"' => 'Oppgaveeksportering for "%s"', - 'Start Date' => 'Start-dato', - 'End Date' => 'Slutt-dato', - 'Execute' => 'KKjør', - 'Task Id' => 'Oppgave ID', - 'Creator' => 'Laget av', - 'Modification date' => 'Endringsdato', - 'Completion date' => 'Ferdigstillingsdato', - 'Clone' => 'Kopier', - 'Project cloned successfully.' => 'Prosjektet er kopiert.', - 'Unable to clone this project.' => 'Prosjektet kunne ikke kopieres', - 'Enable email notifications' => 'Aktiver epostvarslinger', - 'Task position:' => 'Oppgaveposisjon:', - 'The task #%d have been opened.' => 'Oppgaven #%d er åpnet.', - 'The task #%d have been closed.' => 'Oppgaven #%d er lukket.', - 'Sub-task updated' => 'Deloppgaven er oppdatert', - 'Title:' => 'Tittel:', - 'Status:' => 'Status:', - 'Assignee:' => 'Ansvarlig:', - 'Time tracking:' => 'Tidsmåling:', - 'New sub-task' => 'Ny deloppgave', - 'New attachment added "%s"' => 'Nytt vedlegg er lagt tilet "%s"', - 'New comment posted by %s' => 'Ny kommentar fra %s', - 'New attachment' => 'Nytt vedlegg', - 'New comment' => 'Ny kommentar', - 'Comment updated' => 'Kommentar oppdatert', - 'New subtask' => 'Ny deloppgave', - 'Subtask updated' => 'Deloppgave oppdatert', - 'Task updated' => 'Oppgave oppdatert', - 'Task closed' => 'Oppgave lukket', - 'Task opened' => 'Oppgave åpnet', - 'I want to receive notifications only for those projects:' => 'Jeg vil kun ha varslinger for disse prosjekter:', - 'view the task on Kanboard' => 'se oppgaven påhovedsiden', - 'Public access' => 'Offentlig tilgang', - 'Active tasks' => 'Aktive oppgaver', - 'Disable public access' => 'Deaktiver offentlig tilgang', - 'Enable public access' => 'Aktiver offentlig tilgang', - 'Public access disabled' => 'Offentlig tilgang er deaktivert', - 'Do you really want to disable this project: "%s"?' => 'Vil du deaktivere prosjektet: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Vil du aktivere prosjektet: "%s"?', - 'Project activation' => 'Prosjekt aktivering', - 'Move the task to another project' => 'Flytt oppgaven til et annet prosjekt', - 'Move to another project' => 'Flytt til et annet prosjekt', - 'Do you really want to duplicate this task?' => 'Vil du kopiere denne oppgaven?', - 'Duplicate a task' => 'Kopier en oppgave', - 'External accounts' => 'Eksterne kontoer', - 'Account type' => 'Kontotype', - 'Local' => 'Lokal', - 'Remote' => 'Fjernstyrt', - 'Enabled' => 'Aktiv', - 'Disabled' => 'Deaktivert', - 'Username:' => 'Brukernavn', - 'Name:' => 'Navn:', - 'Email:' => 'Epost:', - 'Notifications:' => 'Varslinger:', - 'Notifications' => 'Varslinger', - 'Account type:' => 'Konto type:', - 'Edit profile' => 'Rediger profil', - 'Change password' => 'Endre passord', - 'Password modification' => 'Passordendring', - 'External authentications' => 'Ekstern godkjenning', - 'Never connected.' => 'Aldri innlogget.', - 'No external authentication enabled.' => 'Ingen eksterne godkjenninger aktiveret.', - 'Password modified successfully.' => 'Passord er endret.', - 'Unable to change the password.' => 'Passordet kuenne ikke endres.', - 'Change category' => 'Endre kategori', - '%s updated the task %s' => '%s oppdaterte oppgaven %s', - '%s opened the task %s' => '%s åpnet oppgaven %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s flyttet oppgaven %s til posisjonen #%d i kolonnen "%s"', - '%s moved the task %s to the column "%s"' => '%s flyttet oppgaven %s til kolonnen "%s"', - '%s created the task %s' => '%s opprettet oppgaven %s', - '%s closed the task %s' => '%s lukket oppgaven %s', - '%s created a subtask for the task %s' => '%s opprettet en deloppgave for oppgaven %s', - '%s updated a subtask for the task %s' => '%s oppdaterte en deloppgave for oppgaven %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Tildelt til %s med et estimat på %s/%sh', - 'Not assigned, estimate of %sh' => 'Ikke tildelt, estimert til %sh', - '%s updated a comment on the task %s' => '%s oppdaterte en kommentar til oppgaven %s', - '%s commented the task %s' => '%s har kommentert oppgaven %s', - '%s\'s activity' => '%s\'s aktvitet', - 'RSS feed' => 'RSS feed', - '%s updated a comment on the task #%d' => '%s oppdaterte en kommentar til oppgaven #%d', - '%s commented on the task #%d' => '%s kommenterte oppgaven #%d', - '%s updated a subtask for the task #%d' => '%s oppdaterte en deloppgave til oppgaven #%d', - '%s created a subtask for the task #%d' => '%s opprettet en deloppgave til oppgaven #%d', - '%s updated the task #%d' => '%s oppdaterte oppgaven #%d', - '%s created the task #%d' => '%s opprettet oppgaven #%d', - '%s closed the task #%d' => '%s lukket oppgaven #%d', - '%s open the task #%d' => '%s åpnet oppgaven #%d', - '%s moved the task #%d to the column "%s"' => '%s flyttet oppgaven #%d til kolonnen "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s flyttet oppgaven #%d til posisjonen %d i kolonnen "%s"', - 'Activity' => 'Aktivitetslogg', - 'Default values are "%s"' => 'Standardverdier er "%s"', - 'Default columns for new projects (Comma-separated)' => 'Standard kolonne for nye prosjekter (komma-separert)', - 'Task assignee change' => 'Endring av oppgaveansvarlig', - '%s change the assignee of the task #%d to %s' => '%s endre ansvarlig for oppgaven #%d til %s', - '%s changed the assignee of the task %s to %s' => '%s endret ansvarlig for oppgaven %s til %s', - 'New password for the user "%s"' => 'Nytt passord for brukeren "%s"', - 'Choose an event' => 'Velg en hendelse', - 'Create a task from an external provider' => 'Oppret en oppgave fra en ekstern tilbyder', - 'Change the assignee based on an external username' => 'Endre ansvarlige baseret på et eksternt brukernavn', - 'Change the category based on an external label' => 'Endre kategorien basert på en ekstern etikett', - 'Reference' => 'Referanse', - 'Label' => 'Etikett', - 'Database' => 'Database', - 'About' => 'Om', - 'Database driver:' => 'Database driver:', - 'Board settings' => 'Innstillinger for prosjektside', - 'Webhook settings' => 'Webhook innstillinger', - 'Reset token' => 'Resette token', - 'API endpoint:' => 'API endpoint:', - 'Refresh interval for private board' => 'Oppdateringsintervall for privat hovedside', - 'Refresh interval for public board' => 'Oppdateringsintervall for offentlig hovedside', - 'Task highlight period' => 'Fremhevingsperiode for oppgave', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Periode for ø anta at en oppgave nylig ble endretg (0 for å deaktivere, 2 dager som standard)', - 'Frequency in second (60 seconds by default)' => 'Frekevens i sekunder (60 sekunder som standard)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvens i sekunder (0 for øt deaktivere denne funksjonen, 10 sekunder som standard)', - 'Application URL' => 'Applikasjons URL', - 'Token regenerated.' => 'Token regenerert.', - 'Date format' => 'Datoformat', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO format er alltid akseptert, eksempelvis: "%s" og "%s"', - 'New private project' => 'Nytt privat prosjekt', - 'This project is private' => 'Dette projektet er privat', - 'Add' => 'Legg til', - 'Start date' => 'Start dato', - 'Time estimated' => 'Tid estimert', - 'There is nothing assigned to you.' => 'Ingen er tildelt deg.', - 'My tasks' => 'Mine oppgaver', - 'Activity stream' => 'Aktivitetslogg', - 'Dashboard' => 'Hovedsiden', - 'Confirmation' => 'Bekreftelse', - 'Allow everybody to access to this project' => 'Gi alle tilgang til dette prosjektet', - 'Everybody have access to this project.' => 'Alle har tilgang til dette prosjektet', - // 'Webhooks' => '', - // 'API' => '', - 'Create a comment from an external provider' => 'Opprett en kommentar fra en ekstern tilbyder', - 'Project management' => 'Prosjektinnstillinger', - 'My projects' => 'Mine prosjekter', - 'Columns' => 'Kolonner', - 'Task' => 'Oppgave', - // 'Your are not member of any project.' => '', - 'Percentage' => 'Prosent', - 'Number of tasks' => 'Antall oppgaver', - 'Task distribution' => 'Kolonnefordeling', - 'Reportings' => 'Rapportering', - // 'Task repartition for "%s"' => '', - 'Analytics' => 'Analyser', - 'Subtask' => 'Deloppgave', - 'My subtasks' => 'Mine deloppgaver', - 'User repartition' => 'Brukerfordeling', - // 'User repartition for "%s"' => '', - 'Clone this project' => 'Kopier dette prosjektet', - 'Column removed successfully.' => 'Kolonne flyttet', - // 'Not enough data to show the graph.' => '', - 'Previous' => 'Forrige', - // 'The id must be an integer' => '', - // 'The project id must be an integer' => '', - // 'The status must be an integer' => '', - // 'The subtask id is required' => '', - // 'The subtask id must be an integer' => '', - // 'The task id is required' => '', - // 'The task id must be an integer' => '', - // 'The user id must be an integer' => '', - // 'This value is required' => '', - // 'This value must be numeric' => '', - // 'Unable to create this task.' => '', - 'Cumulative flow diagram' => 'Kumulativt flytdiagram', - // 'Cumulative flow diagram for "%s"' => '', - 'Daily project summary' => 'Daglig prosjektsammendrag', - // 'Daily project summary export' => '', - // 'Daily project summary export for "%s"' => '', - 'Exports' => 'Eksporter', - // 'This export contains the number of tasks per column grouped per day.' => '', - 'Active swimlanes' => 'Aktive svømmebaner', - 'Add a new swimlane' => 'Legg til en ny svømmebane', - 'Change default swimlane' => 'Endre standard svømmebane', - 'Default swimlane' => 'Standard svømmebane', - // 'Do you really want to remove this swimlane: "%s"?' => '', - // 'Inactive swimlanes' => '', - 'Remove a swimlane' => 'Fjern en svømmebane', - 'Show default swimlane' => 'Vis standard svømmebane', - // 'Swimlane modification for the project "%s"' => '', - 'Swimlane removed successfully.' => 'Svømmebane fjernet', - 'Swimlanes' => 'Svømmebaner', - 'Swimlane updated successfully.' => 'Svømmebane oppdatert', - // 'The default swimlane have been updated successfully.' => '', - // 'Unable to remove this swimlane.' => '', - // 'Unable to update this swimlane.' => '', - // 'Your swimlane have been created successfully.' => '', - // 'Example: "Bug, Feature Request, Improvement"' => '', - // 'Default categories for new projects (Comma-separated)' => '', - 'Integrations' => 'Integrasjoner', - 'Integration with third-party services' => 'Integrasjoner med tredje-parts tjenester', - 'Subtask Id' => 'Deloppgave ID', - 'Subtasks' => 'Deloppgaver', - 'Subtasks Export' => 'Eksporter deloppgaver', - // 'Subtasks exportation for "%s"' => '', - 'Task Title' => 'Oppgavetittel', - // 'Untitled' => '', - 'Application default' => 'Standardinstilling', - 'Language:' => 'Språk', - 'Timezone:' => 'Tidssone', - 'All columns' => 'Alle kolonner', - 'Calendar' => 'Kalender', - 'Next' => 'Neste', - // '#%d' => '', - 'All swimlanes' => 'Alle svømmebaner', - 'All colors' => 'Alle farger', - // 'Moved to column %s' => '', - 'User dashboard' => 'Brukerens hovedside', - // 'Allow only one subtask in progress at the same time for a user' => '', - // 'Edit column "%s"' => '', - // 'Select the new status of the subtask: "%s"' => '', - 'Subtask timesheet' => 'Tidsskjema for deloppgaver', - 'There is nothing to show.' => 'Ingen data å vise', - // 'Time Tracking' => '', - // 'You already have one subtask in progress' => '', - 'Which parts of the project do you want to duplicate?' => 'Hvilke deler av dette prosjektet ønsker du å kopiere?', - // 'Disallow login form' => '', - 'Start' => 'Start', - 'End' => 'Slutt', - 'Task age in days' => 'Dager siden oppgaven ble opprettet', - 'Days in this column' => 'Dager siden oppgaven ble lagt i denne kolonnen', - // '%dd' => '', - 'Add a new link' => 'Legg til en ny relasjon', - // 'Do you really want to remove this link: "%s"?' => '', - // 'Do you really want to remove this link with task #%d?' => '', - 'Field required' => 'Feltet må fylles ut', - 'Link added successfully.' => 'Ny relasjon er lagt til', - 'Link updated successfully.' => 'Relasjon er oppdatert', - 'Link removed successfully.' => 'Relasjon er fjernet', - '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' => '', - // 'Unable to create your link.' => '', - // 'Unable to update your link.' => '', - // 'Unable to remove this link.' => '', - 'relates to' => 'relatert til', - 'blocks' => 'blokkerer', - 'is blocked by' => 'blokkeres av', - 'duplicates' => 'kopierer', - 'is duplicated by' => 'er en kopi av', - 'is a child of' => 'er en underordnet oppgave av', - 'is a parent of' => 'er en overordnet oppgave av', - 'targets milestone' => 'milepel', - 'is a milestone of' => 'er en milepel av', - 'fixes' => 'løser', - 'is fixed by' => 'løses av', - 'This task' => 'Denne oppgaven', - // '<1h' => '', - // '%dh' => '', - 'Expand tasks' => 'Utvid oppgavevisning', - 'Collapse tasks' => 'Komprimer oppgavevisning', - 'Expand/collapse tasks' => 'Utvide/komprimere oppgavevisning', - // 'Close dialog box' => '', - // 'Submit a form' => '', - // 'Board view' => '', - 'Keyboard shortcuts' => 'Hurtigtaster', - // 'Open board switcher' => '', - // 'Application' => '', - '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' => '', - // 'CAD - Canadian Dollar' => '', - // 'CHF - Swiss Francs' => '', - // 'Custom Stylesheet' => '', - 'download' => 'last ned', - // 'EUR - Euro' => '', - // 'GBP - British Pound' => '', - // 'INR - Indian Rupee' => '', - // 'JPY - Japanese Yen' => '', - // 'NZD - New Zealand Dollar' => '', - // 'RSD - Serbian dinar' => '', - // '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', - 'Move the task to another column when assignee is cleared' => 'Flytt oppgaven til en annen kolonne når ppgavetildeling fjernes ', - 'Source column' => 'Opprinnelig kolonne', - 'Transitions' => 'Statusendringer', - // 'Executer' => '', - // 'Time spent in the column' => '', - // 'Task transitions' => '', - // 'Task transitions export' => '', - // 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '', - 'Currency rates' => '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.' => '', - // 'Webhook URL' => '', - // '%s remove the assignee of the task %s' => '', - // 'Enable Gravatar images' => '', - // 'Information' => '', - // 'Check two factor authentication code' => '', - // 'The two factor authentication code is not valid.' => '', - // 'The two factor authentication code is valid.' => '', - // 'Code' => '', - 'Two factor authentication' => 'Dobbel godkjenning', - // 'This QR code contains the key URI: ' => '', - // 'Check my code' => '', - // 'Secret key: ' => '', - // 'Test your device' => '', - 'Assign a color when the task is moved to a specific column' => 'Endre til en valgt farge hvis en oppgave flyttes til en spesifikk kolonne', - // '%s via Kanboard' => '', - // 'Burndown chart for "%s"' => '', - // 'Burndown chart' => '', - // 'This chart show the task complexity over the time (Work Remaining).' => '', - // 'Screenshot taken %s' => '', - 'Add a screenshot' => 'Legg til et skjermbilde', - // 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '', - 'Screenshot uploaded successfully.' => 'Skjermbilde opplastet', - // 'SEK - Swedish Krona' => '', - 'Identifier' => 'Prosjektkode', - // 'Disable two factor authentication' => '', - // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', - // 'Edit link' => '', - // 'Start to type task title...' => '', - // 'A task cannot be linked to itself' => '', - // 'The exact same link already exists' => '', - // 'Recurrent task is scheduled to be generated' => '', - // 'Score' => '', - // 'The identifier must be unique' => '', - // 'This linked task id doesn\'t exists' => '', - // 'This value must be alphanumeric' => '', - 'Edit recurrence' => 'Endre gjentakelser', - 'Generate recurrent task' => 'Opprett gjentagende oppgave', - 'Trigger to generate recurrent task' => 'Betingelse for å generere gjentakende oppgave', - 'Factor to calculate new due date' => 'Faktor for å beregne ny tidsfrist', - 'Timeframe to calculate new due date' => 'Tidsramme for å beregne ny tidsfrist', - 'Base date to calculate new due date' => 'Grunnlagsdato for å beregne ny tidsfrist', - 'Action date' => 'Hendelsesdato', - 'Base date to calculate new due date: ' => 'Grunnlagsdato for å beregne ny tidsfrist', - 'This task has created this child task: ' => 'Denne oppgaven har opprettet denne relaterte oppgaven', - 'Day(s)' => 'Dager', - 'Existing due date' => 'Eksisterende forfallsdato', - 'Factor to calculate new due date: ' => 'Faktor for å beregne ny tidsfrist', - 'Month(s)' => 'Måneder', - 'Recurrence' => 'Gjentakelse', - 'This task has been created by: ' => 'Denne oppgaven er opprettet av:', - // 'Recurrent task has been generated:' => '', - // 'Timeframe to calculate new due date: ' => '', - // 'Trigger to generate recurrent task: ' => '', - 'When task is closed' => 'Når oppgaven er lukket', - 'When task is moved from first column' => 'Når oppgaven er flyttet fra første kolon', - 'When task is moved to last column' => 'Når oppgaven er flyttet til siste kolonne', - 'Year(s)' => 'år', - 'Calendar settings' => 'Kalenderinstillinger', - 'Project calendar view' => 'Visning prosjektkalender', - 'Project settings' => 'Prosjektinnstillinger', - // 'Show subtasks based on the time tracking' => '', - // 'Show tasks based on the creation date' => '', - // 'Show tasks based on the start date' => '', - // 'Subtasks time tracking' => '', - // 'User calendar view' => '', - 'Automatically update the start date' => 'Oppdater automatisk start-datoen', - // 'iCal feed' => '', - 'Preferences' => 'Preferanser', - 'Security' => 'Sikkerhet', - 'Two factor authentication disabled' => 'Dobbelgodkjenning deaktivert', - 'Two factor authentication enabled' => 'Dobbelgodkjenning aktivert', - // 'Unable to update this user.' => '', - // 'There is no user management for private projects.' => '', - // 'User that will receive the email' => '', - // 'Email subject' => '', - 'Date' => 'Dato', - 'Add a comment log when moving the task between columns' => 'Legg til en kommentar i loggen når en oppgave flyttes mellom kolonnene', - 'Move the task to another column when the category is changed' => 'Flytt oppgaven til en annen kolonne når kategorien endres', - 'Send a task by email to someone' => 'Send en oppgave på epost til noen', - // 'Reopen a task' => '', - 'Column change' => 'Endret kolonne', - 'Position change' => 'Posisjonsendring', - 'Swimlane change' => 'Endret svømmebane', - 'Assignee change' => 'Endret eier', - // '[%s] Overdue tasks' => '', - 'Notification' => 'Varsel', - // '%s moved the task #%d to the first swimlane' => '', - // '%s moved the task #%d to the swimlane "%s"' => '', - 'Swimlane' => 'Svømmebane', - // 'Gravatar' => '', - // '%s moved the task %s to the first swimlane' => '', - // '%s moved the task %s to the swimlane "%s"' => '', - // 'This report contains all subtasks information for the given date range.' => '', - // 'This report contains all tasks information for the given date range.' => '', - // 'Project activities for %s' => '', - // 'view the board on Kanboard' => '', - // 'The task have been moved to the first swimlane' => '', - // 'The task have been moved to another swimlane:' => '', - // 'New title: %s' => '', - // 'The task is not assigned anymore' => '', - // 'New assignee: %s' => '', - // 'There is no category now' => '', - // 'New category: %s' => '', - // 'New color: %s' => '', - // 'New complexity: %d' => '', - // 'The due date have been removed' => '', - // 'There is no description anymore' => '', - // 'Recurrence settings have been modified' => '', - // 'Time spent changed: %sh' => '', - // 'Time estimated changed: %sh' => '', - // 'The field "%s" have been updated' => '', - // 'The description has been modified:' => '', - // 'Do you really want to close the task "%s" as well as all subtasks?' => '', - 'I want to receive notifications for:' => 'Jeg vil motta varslinger om:', - 'All tasks' => 'Alle oppgaver', - 'Only for tasks assigned to me' => 'Kun oppgaver som er tildelt meg', - 'Only for tasks created by me' => 'Kun oppgaver som er opprettet av meg', - 'Only for tasks created by me and assigned to me' => 'Kun oppgaver som er opprettet av meg og tildelt meg', - // '%%Y-%%m-%%d' => '', - 'Total for all columns' => 'Totalt for alle kolonner', - // 'You need at least 2 days of data to show the chart.' => '', - // '<15m' => '', - // '<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', - 'Reset filters' => 'Nullstill filter', - 'My tasks due tomorrow' => 'Mine oppgaver med frist i morgen', - 'Tasks due today' => 'Oppgaver med frist i dag', - 'Tasks due tomorrow' => 'Oppgaver med frist i morgen', - 'Tasks due yesterday' => 'Oppgaver med frist i går', - 'Closed tasks' => 'Fullførte oppgaver', - 'Open tasks' => 'Åpne oppgaver', - 'Not assigned' => 'Ikke tildelt', - 'View advanced search syntax' => 'Vis hjelp for avansert søk ', - 'Overview' => 'Oversikt', - 'Board/Calendar/List view' => 'Oversikt/kalender/listevisning', - 'Switch to the board view' => 'Oversiktsvisning', - 'Switch to the calendar view' => 'Kalendevisning', - 'Switch to the list view' => 'Listevisning', - 'Go to the search/filter box' => 'Gå til søk/filter', - 'There is no activity yet.' => 'Ingen aktiviteter ennå.', - 'No tasks found.' => 'Ingen oppgaver funnet', - 'Keyboard shortcut: "%s"' => 'Hurtigtaster: "%s"', - 'List' => 'Liste', - 'Filter' => 'Filter', - 'Advanced search' => 'Avansert søk', - 'Example of query: ' => 'Eksempel på spørring', - 'Search by project: ' => 'Søk etter prosjekt', - 'Search by column: ' => 'Søk etter kolonne', - 'Search by assignee: ' => 'Søk etter tildelt', - 'Search by color: ' => 'Søk etter farge', - 'Search by category: ' => 'Søk etter kategori', - 'Search by description: ' => 'Søk etter beskrivelse', - 'Search by due date: ' => 'Søk etter frist', - // 'Lead and Cycle time for "%s"' => '', - // 'Average time spent into each column for "%s"' => '', - // 'Average time spent into each column' => '', - // 'Average time spent' => '', - // 'This chart show the average time spent into each column for the last %d tasks.' => '', - // 'Average Lead and Cycle time' => '', - // 'Average lead time: ' => '', - // 'Average cycle time: ' => '', - // 'Cycle Time' => '', - // 'Lead Time' => '', - // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', - // 'Average time into each column' => '', - // 'Lead and cycle time' => '', - // 'Lead time: ' => '', - // 'Cycle time: ' => '', - // 'Time spent into each column' => '', - // 'The lead time is the duration between the task creation and the completion.' => '', - // 'The cycle time is the duration between the start date and the completion.' => '', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - // 'Set automatically the start date' => '', - // 'Edit Authentication' => '', - // 'Remote user' => '', - // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', - // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - 'New remote user' => '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.' => '', - // 'Trigger automatically subtask time tracking' => '', - // 'Include closed tasks in the cumulative flow diagram' => '', - 'Current swimlane: %s' => 'Nåværende svømmebane: %s', - 'Current column: %s' => 'Nåværende kolonne: %s', - 'Current category: %s' => ': %s', - 'no category' => 'ingen kategori', - 'Current assignee: %s' => 'Tildelt til %s', - 'not assigned' => 'ikke tildelt', - 'Author:' => 'Opprettet av', - 'contributors' => 'bidragsytere', - 'License:' => 'Lisens:', - 'License' => 'Lisens', - 'Enter the text below' => 'Legg inn teksten nedenfor', - 'Gantt chart for %s' => 'Gantt skjema for %s', - // 'Sort by position' => '', - 'Sort by date' => 'Sorter etter dato', - 'Add task' => 'Legg til oppgave', - 'Start date:' => 'Startdato:', - 'Due date:' => 'Frist:', - 'There is no start date or due date for this task.' => 'Det er ingen startdato eller frist for denne oppgaven', - // 'Moving or resizing a task will change the start and due date of the task.' => '', - 'There is no task in your project.' => 'Det er ingen oppgaver i dette prosjektet', - 'Gantt chart' => 'Gantt skjema', - 'People who are project managers' => 'Prosjektledere', - 'People who are project members' => 'Prosjektmedlemmer', - // 'NOK - Norwegian Krone' => '', - 'Show this column' => 'Vis denne kolonnen', - 'Hide this column' => 'Skjul denne kolonnen', - 'open file' => 'Åpne fil', - 'End date' => 'Sluttdato', - 'Users overview' => 'Brukeroversikt', - 'Members' => 'Medlemmer', - 'Shared project' => 'Delt prosjekt', - 'Project managers' => 'Prosjektledere', - // 'Gantt chart for all projects' => '', - 'Projects list' => 'Prosjektliste', - 'Gantt chart for this project' => 'Gantt skjema for dette prosjektet', - 'Project board' => 'Prosjektsiden', - 'End date:' => 'Sluttdato:', - // 'There is no start date or end date for this project.' => '', - 'Projects Gantt chart' => 'Gantt skjema for prosjekter', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - 'Milestone' => 'Milepæl', - 'Documentation: %s' => 'Dokumentasjon: %s', - 'Switch to the Gantt chart view' => 'Gantt skjema visning', - 'Reset the search/filter box' => 'Nullstill søk/filter', - 'Documentation' => 'Dokumentasjon', - 'Table of contents' => 'Innholdsfortegnelse', - 'Gantt' => 'Gantt', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - 'Link type' => 'Relasjonstype', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - 'Project members' => 'Prosjektmedlemmer', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/nl_NL/translations.php b/sources/app/Locale/nl_NL/translations.php deleted file mode 100644 index 69f2b86..0000000 --- a/sources/app/Locale/nl_NL/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'Geen', - 'edit' => 'bewerken', - 'Edit' => 'Bewerken', - 'remove' => 'verwijderen', - 'Remove' => 'Verwijderen', - 'Yes' => 'Ja', - 'No' => 'Nee', - 'cancel' => 'annuleren', - 'or' => 'of', - 'Yellow' => 'Geel', - 'Blue' => 'Blauw', - 'Green' => 'Groen', - 'Purple' => 'Paars', - 'Red' => 'Rood', - 'Orange' => 'Oranje', - 'Grey' => 'Grijs', - 'Brown' => 'Bruin', - 'Deep Orange' => 'Dieporanje', - 'Dark Grey' => 'Donkergrijs', - 'Pink' => 'Roze', - // 'Teal' => '', - 'Cyan' => 'Cyaan', - 'Lime' => 'Limoen', - 'Light Green' => 'Lichtgroen', - 'Amber' => 'Amber', - 'Save' => 'Opslaan', - 'Login' => 'Inloggen', - 'Official website:' => 'Officiële website :', - 'Unassigned' => 'Niet toegewezen', - 'View this task' => 'Deze taak bekijken', - 'Remove user' => 'Gebruiker verwijderen', - 'Do you really want to remove this user: "%s"?' => 'Weet u zeker dat u deze gebruiker wil verwijderen : « %s » ?', - 'All users' => 'Alle gebruikers', - 'Username' => 'Gebruikersnaam', - 'Password' => 'Wachtwoord', - 'Administrator' => 'Administrator', - 'Sign in' => 'Inloggen', - 'Users' => 'Gebruikers', - 'No user' => 'Geen gebruiker', - 'Forbidden' => 'Geweigerd', - 'Access Forbidden' => 'Toegang geweigerd', - 'Edit user' => 'Gebruiker bewerken', - 'Logout' => 'Uitloggen', - 'Bad username or password' => 'Verkeerde gebruikersnaam of wachtwoord', - 'Edit project' => 'Project bewerken', - 'Name' => 'Naam', - 'Projects' => 'Projecten', - 'No project' => 'Geen project', - 'Project' => 'Project', - 'Status' => 'Status', - 'Tasks' => 'Taken', - 'Board' => 'Bord', - 'Actions' => 'Acties', - 'Inactive' => 'Inactief', - 'Active' => 'Actief', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Weet u zeker dat u dit project wil verwijderen : « %s » ?', - 'Remove project' => 'Project verwijderen', - 'Edit the board for "%s"' => 'Bord bewerken voor « %s »', - 'All projects' => 'Alle projecten', - 'Add a new column' => 'Kolom toevoegen', - '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!', - 'Settings' => 'Instellingen', - 'Application settings' => 'Applicatie instellingen', - 'Language' => 'Taal', - 'Webhook token:' => 'Webhook token :', - 'API token:' => 'API token :', - 'Database size:' => 'Database grootte :', - 'Download the database' => 'Download de database', - 'Optimize the database' => 'Optimaliseer de database', - '(VACUUM command)' => '(VACUUM commando)', - '(Gzip compressed Sqlite file)' => '(Gzip ingepakt Sqlite bestand)', - 'Close a task' => 'Taak sluiten', - 'Edit a task' => 'Taak bewerken', - 'Column' => 'Kolom', - 'Color' => 'Kleur', - 'Assignee' => 'Toegewezene', - 'Create another task' => 'Nog een taak aanmaken', - 'New task' => 'Nieuwe taak', - 'Open a task' => 'Een taak openen', - 'Do you really want to open this task: "%s"?' => 'Weet u zeker dat u deze taak wil openen : « %s » ?', - 'Back to the board' => 'Terug naar het bord', - 'There is nobody assigned' => 'Er is niemand toegewezen', - 'Column on the board:' => 'Kolom op het bord : ', - 'Close this task' => 'Deze taak sluiten', - 'Open this task' => 'Deze taak openen', - 'There is no description.' => 'Er is geen omschrijving.', - 'Add a new task' => 'Een nieuwe taak toevoegen', - 'The username is required' => 'De gebruikersnaam is verplicht', - 'The maximum length is %d characters' => 'De maximale lengte is %d karakters', - 'The minimum length is %d characters' => 'De minimale lengte is %d karakters', - 'The password is required' => 'Het wachtwoord is verplicht', - 'This value must be an integer' => 'Deze waarde dient een integer te zijn', - 'The username must be unique' => 'De gebruikersnaam moet uniek zijn', - 'The user id is required' => 'Het gebruikers id is verplicht', - 'Passwords don\'t match' => 'De wachtwoorden komen niet overeen', - 'The confirmation is required' => 'De bevestiging is verplicht', - 'The project is required' => 'Het project is verplicht', - 'The id is required' => 'Het id is verplicht', - 'The project id is required' => 'Het project id is verplicht', - 'The project name is required' => 'De projectnaam is verplicht', - 'The title is required' => 'De titel is verplicht', - 'Settings saved successfully.' => 'Instellingen succesvol opgeslagen.', - 'Unable to save your settings.' => 'Instellingen opslaan niet gelukt.', - 'Database optimization done.' => 'Database optimaliseren voltooid.', - 'Your project have been created successfully.' => 'Uw project is succesvol aangemaakt.', - 'Unable to create your project.' => 'Het aanmaken van het project is niet gelukt.', - 'Project updated successfully.' => 'Project succesvol geupdate.', - 'Unable to update this project.' => 'Updaten van project niet gelukt.', - 'Unable to remove this project.' => 'Verwijderen van project niet gelukt.', - 'Project removed successfully.' => 'Project succesvol verwijderd.', - 'Project activated successfully.' => 'Project succesvol geactiveerd.', - 'Unable to activate this project.' => 'Project activeren niet gelukt.', - 'Project disabled successfully.' => 'Project uitschakelen succesvol.', - 'Unable to disable this project.' => 'Project uitschakelen niet gelukt.', - 'Unable to open this task.' => 'Openen van deze taak niet gelukt.', - 'Task opened successfully.' => 'Taak succesvol geopend.', - 'Unable to close this task.' => 'Sluiten van deze taak niet gelukt.', - 'Task closed successfully.' => 'Taak succesvol gesloten.', - 'Unable to update your task.' => 'Updaten van uw taak mislukt.', - 'Task updated successfully.' => 'Taak succesvol geupdate.', - 'Unable to create your task.' => 'Taak aanmaken niet gelukt.', - 'Task created successfully.' => 'Taak succesvol aangemaakt.', - 'User created successfully.' => 'Gebruiker succesvol aangemaakt.', - 'Unable to create your user.' => 'Aanmaken van gebruiker niet gelukt.', - 'User updated successfully.' => 'Gebruiker succesvol geupdate', - 'Unable to update your user.' => 'Updaten van gebruiker niet gelukt.', - 'User removed successfully.' => 'Gebruiker succesvol verwijderd.', - 'Unable to remove this user.' => 'Verwijderen van gebruikers niet gelukt.', - 'Board updated successfully.' => 'Board succesvol geupdate.', - 'Ready' => 'Klaar', - 'Backlog' => 'Het wachten', - 'Work in progress' => 'In behandeling', - 'Done' => 'Afgewerkt', - 'Application version:' => 'Applicatie versie :', - 'Id' => 'Id', - '%d closed tasks' => '%d gesloten taken', - 'No task for this project' => 'Geen taken voor dit project', - 'Public link' => 'Publieke link', - 'Timezone' => 'Tijdzone', - 'Sorry, I didn\'t find this information in my database!' => 'Sorry deze informatie kon niet worden gevonden in de database !', - 'Page not found' => 'Pagina niet gevonden', - 'Complexity' => 'Complexiteit', - 'Task limit' => 'Taak limiet.', - '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', - 'Invalid date' => 'Ongeldige datum', - 'Automatic actions' => 'Geautomatiseerd acties', - 'Your automatic action have been created successfully.' => 'Geautomatiseerde actie succesvol aangemaakt.', - 'Unable to create your automatic action.' => 'Geautomatiseerde actie aanmaken niet gelukt.', - 'Remove an action' => 'Actie verwijderen', - 'Unable to remove this action.' => 'Actie verwijderen niet gelukt', - 'Action removed successfully.' => 'Actie succesvol verwijder.', - 'Automatic actions for the project "%s"' => 'Automatiseer acties voor project « %s »', - 'Add an action' => 'Actie toevoegen', - 'Event name' => 'Naam gebeurtenis', - 'Action name' => 'Actie naam', - 'Action parameters' => 'Actie paramaters', - 'Action' => 'Actie', - 'Event' => 'Evenement', - 'When the selected event occurs execute the corresponding action.' => 'Als de geselecteerde gebeurtenis optreedt de volgende actie uitvoeren', - 'Next step' => 'Volgende stap', - 'Define action parameters' => 'Bepaal actie parameters', - 'Do you really want to remove this action: "%s"?' => 'Weet u zeker dat u de volgende actie wil verwijderen : « %s » ?', - 'Remove an automatic action' => 'Automatische actie verwijderen', - 'Assign the task to a specific user' => 'Taak toewijzen aan een gebruiker', - 'Assign the task to the person who does the action' => 'Taak toewijzen aan een gebruiker die de actie uitvoert', - 'Duplicate the task to another project' => 'Taak dupliceren in een ander project', - 'Move a task to another column' => 'Taak verplaatsen naar een andere kolom', - 'Task modification' => 'Taak aanpassen', - 'Task creation' => 'Taak aanmaken', - 'Closing a task' => 'Taak sluiten', - 'Assign a color to a specific user' => 'Wijs een kleur toe aan een gebruiker', - 'Column title' => 'Kolom titel', - 'Position' => 'Positie', - 'Duplicate to another project' => 'Dupliceren in een ander project', - 'Duplicate' => 'Dupliceren', - 'link' => 'koppelen', - 'Comment updated successfully.' => 'Commentaar succesvol aangepast.', - 'Unable to update your comment.' => 'Commentaar aanpassen niet gelukt.', - 'Remove a comment' => 'Commentaar verwijderen', - 'Comment removed successfully.' => 'Commentaar succesvol verwijder.', - 'Unable to remove this comment.' => 'Commentaar verwijderen niet gelukt.', - 'Do you really want to remove this comment?' => 'Weet u zeker dat u dit commentaar wil verwijderen ?', - 'Current password for the user "%s"' => 'Huidig wachtwoord voor gebruiker « %s »', - 'The current password is required' => 'Huidig wachtwoord is verplicht', - 'Wrong password' => 'Onjuist wachtwoord', - 'Unknown' => 'Onbekend', - 'Last logins' => 'Laatste logins', - 'Login date' => 'Login datum', - 'Authentication method' => 'Authenticatie methode', - 'IP address' => 'IP adres', - 'User agent' => 'User agent', - 'Persistent connections' => 'Persistente connectie', - 'No session.' => 'Geen sessie.', - 'Expiration date' => 'Verloopdatum', - 'Remember Me' => 'Onthoud mij', - 'Creation date' => 'Aanmaakdatum', - 'Everybody' => 'Iedereen', - 'Open' => 'Open', - 'Closed' => 'Gesloten', - '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', - 'Email address invalid' => 'Ongeldig emailadres', - // 'Your external account is not linked anymore to your profile.' => '', - // 'Unable to unlink your external account.' => '', - // 'External authentication failed' => '', - // 'Your external account is linked to your profile successfully.' => '', - 'Email' => 'Email', - 'Task removed successfully.' => 'Taak succesvol verwijderd.', - 'Unable to remove this task.' => 'Taak verwijderen niet gelukt.', - 'Remove a task' => 'Taak verwijderen', - 'Do you really want to remove this task: "%s"?' => 'Weet u zeker dat u deze taak wil verwijderen « %s » ?', - 'Assign automatically a color based on a category' => 'Automatisch een kleur toewijzen aan de hand van een categorie', - 'Assign automatically a category based on a color' => 'Automatisch een categorie toewijzen aan de hand van een kleur', - 'Task creation or modification' => 'Taak aanmaken of wijzigen', - 'Category' => 'Categorie', - 'Category:' => 'Categorie :', - 'Categories' => 'Categorieën', - 'Your category have been created successfully.' => 'Categorie succesvol aangemaakt.', - 'Unable to create your category.' => 'Categorie aanmaken niet gelukt.', - 'Your category have been updated successfully.' => 'Categorie succesvol aangepast.', - 'Unable to update your category.' => 'Aanpassen van categorie niet gelukt.', - 'Remove a category' => 'Categorie verwijderen', - 'Category removed successfully.' => 'Categorie succesvol verwijderd.', - 'Unable to remove this category.' => 'Categorie verwijderen niet gelukt.', - 'Category modification for the project "%s"' => 'Categorie aanpassen voor project « %s »', - 'Category Name' => 'Categorie naam', - 'Add a new category' => 'Categorie toevoegen', - 'Do you really want to remove this category: "%s"?' => 'Weet u zeker dat u deze categorie wil verwijderen: « %s » ?', - 'All categories' => 'Alle categorieën', - 'No category' => 'Geen categorie', - 'The name is required' => 'De naam is verplicht', - 'Remove a file' => 'Bestand verwijderen', - 'Unable to remove this file.' => 'Bestand verwijderen niet gelukt.', - 'File removed successfully.' => 'Bestand succesvol verwijdered.', - 'Attach a document' => 'Document toevoegen', - 'Do you really want to remove this file: "%s"?' => 'Weet u zeker dat u dit bestand wil verwijderen: « %s » ?', - 'Attachments' => 'Bijlages', - 'Edit the task' => 'Taak aanpassen', - 'Add a comment' => 'Commentaar toevoegen', - 'Edit a comment' => 'Commentaar aanpassen', - 'Summary' => 'Samenvatting', - 'Time tracking' => 'Tijdschrijven', - 'Estimate:' => 'Schatting :', - 'Spent:' => 'Besteed :', - 'Do you really want to remove this sub-task?' => 'Weet u zeker dat u deze subtaak wil verwijderen ?', - 'Remaining:' => 'Resterend :', - 'hours' => 'uren', - 'spent' => 'besteed', - 'estimated' => 'geschat', - 'Sub-Tasks' => 'Subtaken', - 'Add a sub-task' => 'Subtaak toevoegen', - 'Original estimate' => 'Orginele schatting', - 'Create another sub-task' => 'Nog een subtaak toevoegen', - 'Time spent' => 'Tijd besteed', - 'Edit a sub-task' => 'Subtaak aanpassen', - 'Remove a sub-task' => 'Subtaak verwijderen', - 'The time must be a numeric value' => 'De tijd moet een numerieke waarde zijn', - 'Todo' => 'Nog te doen', - 'In progress' => 'In behandeling', - 'Sub-task removed successfully.' => 'Subtaak succesvol verwijderd.', - 'Unable to remove this sub-task.' => 'Subtaak verwijderen niet gelukt.', - 'Sub-task updated successfully.' => 'Subtaak succesvol aangepast.', - 'Unable to update your sub-task.' => 'Subtaak aanpassen niet gelukt.', - 'Unable to create your sub-task.' => 'Subtaak aanmaken niet gelukt.', - 'Sub-task added successfully.' => 'Subtaak succesvol aangemaakt.', - 'Maximum size: ' => 'Maximale grootte : ', - 'Unable to upload the file.' => 'Uploaden van bestand niet gelukt.', - 'Display another project' => 'Een ander project weergeven', - 'Created by %s' => 'Aangemaakt door %s', - 'Tasks Export' => 'Taken exporteren', - 'Tasks exportation for "%s"' => 'Taken exporteren voor « %s »', - 'Start Date' => 'Startdatum', - 'End Date' => 'Einddatum', - 'Execute' => 'Uitvoeren', - 'Task Id' => 'Taak Id', - 'Creator' => 'Aangemaakt door', - 'Modification date' => 'Wijzigingsdatum', - 'Completion date' => 'Afgerond op', - 'Clone' => 'Kloon', - 'Project cloned successfully.' => 'Project succesvol gekloond.', - 'Unable to clone this project.' => 'Klonen van project niet gelukt.', - 'Enable email notifications' => 'Email notificatie aanzetten', - 'Task position:' => 'Taak positie :', - 'The task #%d have been opened.' => 'Taak #%d is geopend.', - 'The task #%d have been closed.' => 'Taak #%d is gesloten.', - 'Sub-task updated' => 'Subtaak aangepast', - 'Title:' => 'Titel :', - 'Status:' => 'Status :', - 'Assignee:' => 'Toegewezene :', - 'Time tracking:' => 'Tijdschrijven :', - 'New sub-task' => 'Nieuwe subtaak', - 'New attachment added "%s"' => 'Nieuwe bijlage toegevoegd « %s »', - 'New comment posted by %s' => 'Nieuw commentaar geplaatst door « %s »', - 'New attachment' => 'Nieuwe bijlage', - 'New comment' => 'Nieuw commentaar', - 'Comment updated' => 'Commentaar aangepast', - 'New subtask' => 'Nieuwe subtaak', - 'Subtask updated' => 'Subtaak aangepast', - 'Task updated' => 'Taak aangepast', - 'Task closed' => 'Taak gesloten', - 'Task opened' => 'Taak geopend', - 'I want to receive notifications only for those projects:' => 'Ik wil notificaties ontvangen van de volgende projecten :', - 'view the task on Kanboard' => 'taak bekijken op Kanboard', - 'Public access' => 'Publieke toegang', - 'Active tasks' => 'Actieve taken', - 'Disable public access' => 'Publieke toegang uitschakelen', - 'Enable public access' => 'Publieke toegang inschakelen', - 'Public access disabled' => 'Publieke toegang uitgeschakeld', - 'Do you really want to disable this project: "%s"?' => 'Weet u zeker dat u dit project wil uitschakelen : « %s » ?', - 'Do you really want to enable this project: "%s"?' => 'Weet u zeker dat u dit project wil activeren : « %s » ?', - 'Project activation' => 'Project activatie', - 'Move the task to another project' => 'Taak verplaatsen naar een ander project', - 'Move to another project' => 'Verplaats naar een ander project', - 'Do you really want to duplicate this task?' => 'Weet u zeker dat u deze taak wil dupliceren ?', - 'Duplicate a task' => 'Taak dupliceren', - 'External accounts' => 'Externe accounts', - 'Account type' => 'Account type', - 'Local' => 'Lokaal', - 'Remote' => 'Remote', - 'Enabled' => 'Actief', - 'Disabled' => 'Inactief', - 'Username:' => 'Gebruikersnaam :', - 'Name:' => 'Naam :', - 'Email:' => 'Email :', - 'Notifications:' => 'Notificaties :', - 'Notifications' => 'Notificaties', - 'Account type:' => 'Account type:', - 'Edit profile' => 'Profiel aanpassen', - 'Change password' => 'Wachtwoord aanpassen', - 'Password modification' => 'Wachtwoord aanpassen', - 'External authentications' => 'Externe authenticatie', - 'Never connected.' => 'Nooit verbonden.', - 'No external authentication enabled.' => 'Geen externe authenticatie aangezet.', - 'Password modified successfully.' => 'Wachtwoord succesvol aangepast.', - 'Unable to change the password.' => 'Aanpassen van wachtwoord niet gelukt.', - 'Change category' => 'Categorie aanpassen', - '%s updated the task %s' => '%s heeft taak %s aangepast', - '%s opened the task %s' => '%s heeft taak %s geopend', - '%s moved the task %s to the position #%d in the column "%s"' => '%s heeft taak %s naar positie %d in de kolom « %s » verplaatst', - '%s moved the task %s to the column "%s"' => '%s heeft taak %s verplaatst naar kolom « %s »', - '%s created the task %s' => '%s heeft taak %s aangemaakt', - '%s closed the task %s' => '%s heeft taak %s gesloten', - '%s created a subtask for the task %s' => '%s heeft een subtaak aangemaakt voor taak %s', - '%s updated a subtask for the task %s' => '%s heeft een subtaak aangepast voor taak %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Toegewezen aan %s met een schatting van %s/%sh', - 'Not assigned, estimate of %sh' => 'Niet toegewezen, schatting: %sh', - '%s updated a comment on the task %s' => '%s heeft een commentaar aangepast voor taak %s', - '%s commented the task %s' => '%s heeft een commentaar geplaatst voor taak %s', - '%s\'s activity' => 'Activiteiten van %s', - 'RSS feed' => 'RSS feed', - '%s updated a comment on the task #%d' => '%s heeft een commentaar aangepast voor taak %d', - '%s commented on the task #%d' => '%s heeft commentaar geplaatst voor taak %d', - '%s updated a subtask for the task #%d' => '%s heeft een commentaar aangepast voor subtaak %d', - '%s created a subtask for the task #%d' => '%s heeft een subtaak aangemaakt voor taak %d', - '%s updated the task #%d' => '%s heeft taak %d aangepast', - '%s created the task #%d' => '%s heeft taak %d aangemaakt', - '%s closed the task #%d' => '%s heeft taak %d gesloten', - '%s open the task #%d' => '%s a heeft taak %d geopend', - '%s moved the task #%d to the column "%s"' => '%s heeft taak %d verplaatst naar kolom « %s »', - '%s moved the task #%d to the position %d in the column "%s"' => '%s heeft taak %d verplaatst naar positie %d in kolom « %s »', - 'Activity' => 'Activiteit', - 'Default values are "%s"' => 'Standaardwaarden zijn « %s »', - 'Default columns for new projects (Comma-separated)' => 'Standaard kolommen voor nieuw projecten (komma gescheiden)', - 'Task assignee change' => 'Taak toegewezene verandering', - '%s change the assignee of the task #%d to %s' => '%s heeft de toegewezene voor taak %d veranderd in %s', - '%s changed the assignee of the task %s to %s' => '%s heeft de toegewezene voor taak %s veranderd in %s', - 'New password for the user "%s"' => 'Nieuw wachtwoord voor gebruiker « %s »', - 'Choose an event' => 'Kies een gebeurtenis', - 'Create a task from an external provider' => 'Maak een taak aan vanuit een externe provider', - 'Change the assignee based on an external username' => 'Verander de toegewezene aan de hand van de externe gebruikersnaam', - 'Change the category based on an external label' => 'Verander de categorie aan de hand van een extern label', - 'Reference' => 'Referentie', - 'Label' => 'Label', - 'Database' => 'Database', - 'About' => 'Over', - 'Database driver:' => 'Database driver :', - 'Board settings' => 'Bord instellingen', - 'Webhook settings' => 'Webhook instellingen', - 'Reset token' => 'Token resetten', - 'API endpoint:' => 'API endpoint :', - 'Refresh interval for private board' => 'Verversingsinterval voor private borden', - 'Refresh interval for public board' => 'Verversingsinterval voor publieke borden', - 'Task highlight period' => 'Taak highlight periode', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Periode (in seconden) om aan te geven of een taak recent is aangepast (0 om uit te schakelen, standaard 2 dagen)', - 'Frequency in second (60 seconds by default)' => 'Frequentie in seconden (stadaard 60)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frequentie in seconden (0 om uit te schakelen, standaard 10)', - 'Application URL' => 'Applicatie URL', - 'Token regenerated.' => 'Token opnieuw gegenereerd.', - 'Date format' => 'Datum formaat', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formaat is altijd geaccepteerd, bijvoorbeeld : « %s » et « %s »', - 'New private project' => 'Nieuw privé project', - 'This project is private' => 'Dit project is privé', - 'Add' => 'Toevoegen', - 'Start date' => 'Startdatum', - 'Time estimated' => 'Geschatte tijd', - 'There is nothing assigned to you.' => 'Er is niets aan u toegewezen.', - 'My tasks' => 'Mijn taken', - 'Activity stream' => 'Activiteiten', - 'Dashboard' => 'Dashboard', - // 'Confirmation' => '', - 'Allow everybody to access to this project' => 'Geef iedereen toegang tot dit project', - 'Everybody have access to this project.' => 'Iedereen heeft toegang tot dit project.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Voeg een commentaar toe van een externe provider', - 'Project management' => 'Project management', - 'My projects' => 'Mijn projecten', - 'Columns' => 'Kolommen', - 'Task' => 'Taak', - 'Your are not member of any project.' => 'U bent van geen enkel project lid.', - 'Percentage' => 'Percentage', - 'Number of tasks' => 'Aantal taken', - 'Task distribution' => 'Distributie van taken', - 'Reportings' => 'Rapporten', - 'Task repartition for "%s"' => 'Taakverdeling voor « %s »', - 'Analytics' => 'Analytics', - 'Subtask' => 'Subtaak', - 'My subtasks' => 'Mijn subtaken', - 'User repartition' => 'Gebruikerverdeling', - 'User repartition for "%s"' => 'Gebruikerverdeling voor « %s »', - 'Clone this project' => 'Kloon dit project', - 'Column removed successfully.' => 'Kolom succesvol verwijderd.', - 'Not enough data to show the graph.' => 'Niet genoeg data om de grafiek te laten zien.', - // 'Previous' => '', - 'The id must be an integer' => 'Het id moet een integer zijn', - 'The project id must be an integer' => 'Het project id moet een integer zijn', - 'The status must be an integer' => 'De status moet een integer zijn', - 'The subtask id is required' => 'Het id van de subtaak is verplicht', - 'The subtask id must be an integer' => 'Het id van de subtaak moet een integer zijn', - 'The task id is required' => 'Het id van de taak is verplicht', - 'The task id must be an integer' => 'Het id van de taak moet een integer zijn', - 'The user id must be an integer' => 'Het id van de gebruiker moet een integer zijn', - 'This value is required' => 'Deze waarde is verplicht', - 'This value must be numeric' => 'Deze waarde moet numeriek zijn', - 'Unable to create this task.' => 'Aanmaken van de taak mislukt', - 'Cumulative flow diagram' => 'Cummulatief stroomdiagram', - 'Cumulative flow diagram for "%s"' => 'Cummulatief stroomdiagram voor « %s »', - 'Daily project summary' => 'Dagelijkse project samenvatting', - 'Daily project summary export' => 'Dagelijkse project samenvatting export', - 'Daily project summary export for "%s"' => 'Dagelijkse project samenvatting voor « %s »', - 'Exports' => 'Exports', - 'This export contains the number of tasks per column grouped per day.' => 'Dit rapport bevat het aantal taken per kolom gegroupeerd per dag.', - 'Active swimlanes' => 'Actieve swinlanes', - 'Add a new swimlane' => 'Nieuwe swimlane toevoegen', - 'Change default swimlane' => 'Standaard swimlane aapassen', - 'Default swimlane' => 'Standaard swinlane', - 'Do you really want to remove this swimlane: "%s"?' => 'Weet u zeker dat u deze swimlane wil verwijderen : « %s » ?', - 'Inactive swimlanes' => 'Inactieve swinlanes', - 'Remove a swimlane' => 'Verwijder swinlane', - 'Show default swimlane' => 'Standaard swimlane tonen', - 'Swimlane modification for the project "%s"' => 'Swinlane aanpassing voor project « %s »', - 'Swimlane removed successfully.' => 'Swimlane succesvol verwijderd.', - 'Swimlanes' => 'Swimlanes', - 'Swimlane updated successfully.' => 'Swimlane succesvol aangepast.', - 'The default swimlane have been updated successfully.' => 'De standaard swimlane is succesvol aangepast.', - 'Unable to remove this swimlane.' => 'Swimlane verwijderen niet gelukt.', - 'Unable to update this swimlane.' => 'Swimlane aanpassen niet gelukt.', - 'Your swimlane have been created successfully.' => 'Swimlane succesvol aangemaakt.', - 'Example: "Bug, Feature Request, Improvement"' => 'Voorbeeld: « Bug, Feature Request, Improvement »', - 'Default categories for new projects (Comma-separated)' => 'Standaard categorieën voor nieuwe projecten (komma gescheiden)', - 'Integrations' => 'Integraties', - 'Integration with third-party services' => 'Integratie met derde-partij-services', - 'Subtask Id' => 'Subtaak id', - 'Subtasks' => 'Subtaken', - 'Subtasks Export' => 'Subtaken exporteren', - 'Subtasks exportation for "%s"' => 'Subtaken exporteren voor project « %s »', - 'Task Title' => 'Taak title', - 'Untitled' => 'Geen titel', - 'Application default' => 'Standaard taal voor applicatie', - 'Language:' => 'Taal :', - 'Timezone:' => 'Tijdzone :', - 'All columns' => 'Alle kolommen', - 'Calendar' => 'Agenda', - 'Next' => 'Volgende', - '#%d' => '%d', - 'All swimlanes' => 'Alle swimlanes', - 'All colors' => 'Alle kleuren', - 'Moved to column %s' => 'Verplaatst naar kolom %s', - 'User dashboard' => 'Gebruiker dashboard', - 'Allow only one subtask in progress at the same time for a user' => 'Sta maximaal één subtaak in behandeling toe per gebruiker', - 'Edit column "%s"' => 'Kolom « %s » aanpassen', - 'Select the new status of the subtask: "%s"' => 'Selecteer nieuwe status voor subtaak : « %s »', - 'Subtask timesheet' => 'Subtaak timesheet', - 'There is nothing to show.' => 'Er is niets om te laten zijn.', - 'Time Tracking' => 'Tijdschrijven', - 'You already have one subtask in progress' => 'U heeft al een subtaak in behandeling', - 'Which parts of the project do you want to duplicate?' => 'Welke onderdelen van het project wilt u dupliceren?', - // 'Disallow login form' => '', - 'Start' => 'Start', - 'End' => 'Eind', - 'Task age in days' => 'Leeftijd taak in dagen', - 'Days in this column' => 'Dagen in deze kolom', - '%dd' => '%dj', - 'Add a new link' => 'Nieuwe link toevoegen', - 'Do you really want to remove this link: "%s"?' => 'Weet u zeker dat u deze link wil verwijderen : « %s » ?', - 'Do you really want to remove this link with task #%d?' => 'Weet u zeker dat u deze link met taak %d wil verwijderen?', - 'Field required' => 'Veld verplicht', - 'Link added successfully.' => 'Link succesvol toegevoegd.', - 'Link updated successfully.' => 'Link succesvol aangepast.', - 'Link removed successfully.' => 'Link succesvol verwijderd.', - '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', - 'Unable to create your link.' => 'Link aanmaken niet gelukt.', - 'Unable to update your link.' => 'Link aanpassen niet gelukt.', - 'Unable to remove this link.' => 'Link verwijderen niet gelukt.', - 'relates to' => 'is gerelateerd aan', - 'blocks' => 'blokkeert', - 'is blocked by' => 'is geblokkeerd door', - 'duplicates' => 'dupliceert', - 'is duplicated by' => 'is gedupliceerd', - 'is a child of' => 'is een kind van', - 'is a parent of' => 'is een ouder van', - 'targets milestone' => 'is nodig voor milestone', - 'is a milestone of' => 'is een milestone voor', - 'fixes' => 'corrigeert', - 'is fixed by' => 'word gecorrigeerd door', - 'This task' => 'Deze taak', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Taken uitklappen', - 'Collapse tasks' => 'Taken inklappen', - 'Expand/collapse tasks' => 'Taken in/uiklappen', - 'Close dialog box' => 'Venster sluiten', - 'Submit a form' => 'Formulier insturen', - 'Board view' => 'Bord weergave', - 'Keyboard shortcuts' => 'Keyboard snelkoppelingen', - 'Open board switcher' => 'Open bord switcher', - 'Application' => 'Applicatie', - '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' => '', - // 'CAD - Canadian Dollar' => '', - // 'CHF - Swiss Francs' => '', - // 'Custom Stylesheet' => '', - // 'download' => '', - 'EUR - Euro' => 'EUR - Euro', - // 'GBP - British Pound' => '', - // 'INR - Indian Rupee' => '', - // 'JPY - Japanese Yen' => '', - // 'NZD - New Zealand Dollar' => '', - // 'RSD - Serbian dinar' => '', - // 'USD - US Dollar' => '', - 'Destination column' => 'Doel kolom', - // 'Move the task to another column when assigned to a user' => '', - // 'Move the task to another column when assignee is cleared' => '', - 'Source column' => 'Bron kolom', - // 'Transitions' => '', - // 'Executer' => '', - // 'Time spent in the column' => '', - // 'Task transitions' => '', - // 'Task transitions export' => '', - // 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '', - 'Currency rates' => 'Wisselkoersen', - 'Rate' => 'Koers', - // 'Change reference currency' => '', - // 'Add a new currency rate' => '', - // 'Reference currency' => '', - // 'The currency rate have been added successfully.' => '', - // 'Unable to add this currency rate.' => '', - 'Webhook URL' => 'Webhook URL', - // '%s remove the assignee of the task %s' => '', - // 'Enable Gravatar images' => '', - // 'Information' => '', - // 'Check two factor authentication code' => '', - // 'The two factor authentication code is not valid.' => '', - // 'The two factor authentication code is valid.' => '', - // 'Code' => '', - // 'Two factor authentication' => '', - // 'This QR code contains the key URI: ' => '', - // 'Check my code' => '', - // 'Secret key: ' => '', - // 'Test your device' => '', - // 'Assign a color when the task is moved to a specific column' => '', - // '%s via Kanboard' => '', - // 'Burndown chart for "%s"' => '', - // 'Burndown chart' => '', - // 'This chart show the task complexity over the time (Work Remaining).' => '', - // 'Screenshot taken %s' => '', - // 'Add a screenshot' => '', - // 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '', - // 'Screenshot uploaded successfully.' => '', - // 'SEK - Swedish Krona' => '', - // 'Identifier' => '', - // 'Disable two factor authentication' => '', - // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', - 'Edit link' => 'Bewerk link', - // 'Start to type task title...' => '', - // 'A task cannot be linked to itself' => '', - // 'The exact same link already exists' => '', - // 'Recurrent task is scheduled to be generated' => '', - // 'Score' => '', - // 'The identifier must be unique' => '', - // 'This linked task id doesn\'t exists' => '', - // 'This value must be alphanumeric' => '', - // 'Edit recurrence' => '', - // 'Generate recurrent task' => '', - // 'Trigger to generate recurrent task' => '', - // 'Factor to calculate new due date' => '', - // 'Timeframe to calculate new due date' => '', - // 'Base date to calculate new due date' => '', - // 'Action date' => '', - // 'Base date to calculate new due date: ' => '', - // 'This task has created this child task: ' => '', - 'Day(s)' => 'Dag(en)', - // 'Existing due date' => '', - // 'Factor to calculate new due date: ' => '', - 'Month(s)' => 'Maand(en)', - // 'Recurrence' => '', - // 'This task has been created by: ' => '', - // 'Recurrent task has been generated:' => '', - // 'Timeframe to calculate new due date: ' => '', - // 'Trigger to generate recurrent task: ' => '', - // 'When task is closed' => '', - // 'When task is moved from first column' => '', - // 'When task is moved to last column' => '', - 'Year(s)' => 'Jaar/Jaren', - 'Calendar settings' => 'Kalender instellingen', - // 'Project calendar view' => '', - 'Project settings' => 'Project instellingen', - // 'Show subtasks based on the time tracking' => '', - // 'Show tasks based on the creation date' => '', - // 'Show tasks based on the start date' => '', - // 'Subtasks time tracking' => '', - // 'User calendar view' => '', - // 'Automatically update the start date' => '', - // 'iCal feed' => '', - 'Preferences' => 'Voorkeuren', - // 'Security' => '', - 'Two factor authentication disabled' => 'Authenticatie in twee stappen uitgeschakeld', - 'Two factor authentication enabled' => 'Authenticatie in twee stappen ingeschakeld', - 'Unable to update this user.' => 'Niet mogelijk om deze gebruiker bij te werken', - // 'There is no user management for private projects.' => '', - 'User that will receive the email' => 'Gebruiker die de mail ontvangt', - 'Email subject' => 'Email onderwerp', - 'Date' => 'Datum', - // 'Add a comment log when moving the task between columns' => '', - // 'Move the task to another column when the category is changed' => '', - // 'Send a task by email to someone' => '', - 'Reopen a task' => 'Heropen een taak', - // 'Column change' => '', - // 'Position change' => '', - // 'Swimlane change' => '', - // 'Assignee change' => '', - // '[%s] Overdue tasks' => '', - // 'Notification' => '', - // '%s moved the task #%d to the first swimlane' => '', - // '%s moved the task #%d to the swimlane "%s"' => '', - 'Swimlane' => 'Swimlane', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s heeft de taak %s naar de eerste swimlane verplaatst', - '%s moved the task %s to the swimlane "%s"' => '%s heeft taak %s naar swimlane "%s" verplaatst', - // 'This report contains all subtasks information for the given date range.' => '', - // 'This report contains all tasks information for the given date range.' => '', - // 'Project activities for %s' => '', - // 'view the board on Kanboard' => '', - // 'The task have been moved to the first swimlane' => '', - // 'The task have been moved to another swimlane:' => '', - 'New title: %s' => 'Nieuw titel: %s', - // 'The task is not assigned anymore' => '', - // 'New assignee: %s' => '', - // 'There is no category now' => '', - // 'New category: %s' => '', - // 'New color: %s' => '', - // 'New complexity: %d' => '', - // 'The due date have been removed' => '', - // 'There is no description anymore' => '', - // 'Recurrence settings have been modified' => '', - // 'Time spent changed: %sh' => '', - // 'Time estimated changed: %sh' => '', - // 'The field "%s" have been updated' => '', - // 'The description has been modified:' => '', - // 'Do you really want to close the task "%s" as well as all subtasks?' => '', - 'I want to receive notifications for:' => 'Ik wil notificaties ontvangen voor:', - 'All tasks' => 'Alle taken', - // 'Only for tasks assigned to me' => '', - // 'Only for tasks created by me' => '', - // 'Only for tasks created by me and assigned to me' => '', - '%%Y-%%m-%%d' => '%%d-%%m-%%Y', - // 'Total for all columns' => '', - // 'You need at least 2 days of data to show the chart.' => '', - '<15m' => '<15m', - '<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', - 'Reset filters' => 'Reset filters', - // 'My tasks due tomorrow' => '', - // 'Tasks due today' => '', - // 'Tasks due tomorrow' => '', - // 'Tasks due yesterday' => '', - 'Closed tasks' => 'Gesloten taken', - 'Open tasks' => 'Open taken', - // 'Not assigned' => '', - // 'View advanced search syntax' => '', - 'Overview' => 'Overzicht', - // 'Board/Calendar/List view' => '', - // 'Switch to the board view' => '', - // 'Switch to the calendar view' => '', - // 'Switch to the list view' => '', - // 'Go to the search/filter box' => '', - // 'There is no activity yet.' => '', - // 'No tasks found.' => '', - // 'Keyboard shortcut: "%s"' => '', - 'List' => 'Lijst', - 'Filter' => 'Filter', - 'Advanced search' => 'Uitgebreid zoeken', - // 'Example of query: ' => '', - // 'Search by project: ' => '', - // 'Search by column: ' => '', - // 'Search by assignee: ' => '', - // 'Search by color: ' => '', - // 'Search by category: ' => '', - // 'Search by description: ' => '', - // 'Search by due date: ' => '', - // 'Lead and Cycle time for "%s"' => '', - // 'Average time spent into each column for "%s"' => '', - // 'Average time spent into each column' => '', - // 'Average time spent' => '', - // 'This chart show the average time spent into each column for the last %d tasks.' => '', - // 'Average Lead and Cycle time' => '', - // 'Average lead time: ' => '', - // 'Average cycle time: ' => '', - // 'Cycle Time' => '', - // 'Lead Time' => '', - // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', - // 'Average time into each column' => '', - // 'Lead and cycle time' => '', - // 'Lead time: ' => '', - // 'Cycle time: ' => '', - // 'Time spent into each column' => '', - // 'The lead time is the duration between the task creation and the completion.' => '', - // 'The cycle time is the duration between the start date and the completion.' => '', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - // 'Set automatically the start date' => '', - // 'Edit Authentication' => '', - // 'Remote user' => '', - // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', - // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - // 'New remote user' => '', - // 'New local user' => '', - // 'Default task color' => '', - // 'This feature does not work with all browsers.' => '', - // 'There is no destination project available.' => '', - // 'Trigger automatically subtask time tracking' => '', - // 'Include closed tasks in the cumulative flow diagram' => '', - // 'Current swimlane: %s' => '', - // 'Current column: %s' => '', - // 'Current category: %s' => '', - // 'no category' => '', - // 'Current assignee: %s' => '', - // 'not assigned' => '', - // 'Author:' => '', - // 'contributors' => '', - // 'License:' => '', - // 'License' => '', - // 'Enter the text below' => '', - // 'Gantt chart for %s' => '', - // 'Sort by position' => '', - // 'Sort by date' => '', - // 'Add task' => '', - // 'Start date:' => '', - // 'Due date:' => '', - // 'There is no start date or due date for this task.' => '', - // 'Moving or resizing a task will change the start and due date of the task.' => '', - // 'There is no task in your project.' => '', - // 'Gantt chart' => '', - // 'People who are project managers' => '', - // 'People who are project members' => '', - // 'NOK - Norwegian Krone' => '', - 'Show this column' => 'Toon deze kolom', - 'Hide this column' => 'Verberg deze kolom', - 'open file' => 'open bestand', - // 'End date' => '', - // 'Users overview' => '', - 'Members' => 'Leden', - // 'Shared project' => '', - // 'Project managers' => '', - // 'Gantt chart for all projects' => '', - // 'Projects list' => '', - // 'Gantt chart for this project' => '', - // 'Project board' => '', - // 'End date:' => '', - // 'There is no start date or end date for this project.' => '', - // 'Projects Gantt chart' => '', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - 'Milestone' => 'Mijlpaal', - // 'Documentation: %s' => '', - // 'Switch to the Gantt chart view' => '', - // 'Reset the search/filter box' => '', - // 'Documentation' => '', - // 'Table of contents' => '', - // 'Gantt' => '', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - // 'Link type' => '', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - // 'Project members' => '', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/pl_PL/translations.php b/sources/app/Locale/pl_PL/translations.php deleted file mode 100644 index 7c132bb..0000000 --- a/sources/app/Locale/pl_PL/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => ' ', - 'None' => 'Brak', - 'edit' => 'edytuj', - 'Edit' => 'Edytuj', - 'remove' => 'usuń', - 'Remove' => 'Usuń', - 'Yes' => 'Tak', - 'No' => 'Nie', - 'cancel' => 'anuluj', - 'or' => 'lub', - 'Yellow' => 'Żółty', - 'Blue' => 'Niebieski', - 'Green' => 'Zielony', - 'Purple' => 'Fioletowy', - 'Red' => 'Czerwony', - 'Orange' => 'Pomarańczowy', - 'Grey' => 'Szary', - 'Brown' => 'Brąz', - 'Deep Orange' => 'Ciemnopomarańczowy', - 'Dark Grey' => 'Ciemnoszary', - 'Pink' => 'Różowy', - 'Teal' => 'Turkusowy', - 'Cyan' => 'Cyjan', - 'Lime' => 'Limonkowy', - 'Light Green' => 'Jasnozielony', - 'Amber' => 'Bursztynowy', - 'Save' => 'Zapisz', - 'Login' => 'Login', - 'Official website:' => 'Oficjalna strona:', - 'Unassigned' => 'Nieprzypisany', - 'View this task' => 'Zobacz zadanie', - 'Remove user' => 'Usuń użytkownika', - 'Do you really want to remove this user: "%s"?' => 'Na pewno chcesz usunąć użytkownika: "%s"?', - 'All users' => 'Wszyscy użytkownicy', - 'Username' => 'Nazwa użytkownika', - 'Password' => 'Hasło', - 'Administrator' => 'Administrator', - 'Sign in' => 'Zaloguj', - 'Users' => 'Użytkownicy', - 'No user' => 'Brak użytkowników', - 'Forbidden' => 'Zabroniony', - 'Access Forbidden' => 'Dostęp zabroniony', - 'Edit user' => 'Edytuj użytkownika', - 'Logout' => 'Wyloguj', - 'Bad username or password' => 'Zła nazwa użytkownika lub hasło', - 'Edit project' => 'Edytuj projekt', - 'Name' => 'Nazwa', - 'Projects' => 'Projekty', - 'No project' => 'Brak projektów', - 'Project' => 'Projekt', - 'Status' => 'Status', - 'Tasks' => 'Zadania', - 'Board' => 'Tablica', - 'Actions' => 'Akcje', - 'Inactive' => 'Nieaktywny', - 'Active' => 'Aktywny', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Na pewno chcesz usunąć projekt: "%s"?', - 'Remove project' => 'Usuń projekt', - 'Edit the board for "%s"' => 'Edytuj tablicę dla "%s"', - 'All projects' => 'Wszystkie projekty', - 'Add a new column' => 'Dodaj nową kolumnę', - '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!', - 'Settings' => 'Ustawienia', - 'Application settings' => 'Ustawienia aplikacji', - 'Language' => 'Język', - 'Webhook token:' => 'Token :', - 'API token:' => 'Token dla API', - 'Database size:' => 'Rozmiar bazy danych :', - 'Download the database' => 'Pobierz bazę danych', - 'Optimize the database' => 'Optymalizuj bazę danych', - '(VACUUM command)' => '(komenda VACUUM)', - '(Gzip compressed Sqlite file)' => '(baza danych spakowana Gzip)', - 'Close a task' => 'Zakończ zadanie', - 'Edit a task' => 'Edytuj zadanie', - 'Column' => 'Kolumna', - 'Color' => 'Kolor', - 'Assignee' => 'Odpowiedzialny', - 'Create another task' => 'Dodaj kolejne zadanie', - 'New task' => 'Nowe zadanie', - 'Open a task' => 'Otwórz zadanie', - 'Do you really want to open this task: "%s"?' => 'Na pewno chcesz otworzyć zadanie: "%s"?', - 'Back to the board' => 'Powrót do tablicy', - 'There is nobody assigned' => 'Nikt nie jest przypisany', - 'Column on the board:' => 'Kolumna na tablicy:', - 'Close this task' => 'Zamknij zadanie', - 'Open this task' => 'Otwórz zadanie', - 'There is no description.' => 'Brak opisu.', - 'Add a new task' => 'Dodaj zadanie', - 'The username is required' => 'Nazwa użytkownika jest wymagana', - 'The maximum length is %d characters' => 'Maksymalna długość wynosi %d znaków', - 'The minimum length is %d characters' => 'Minimalna długość wynosi %d znaków', - 'The password is required' => 'Hasło jest wymagane', - 'This value must be an integer' => 'Wartość musi być liczbą całkowitą', - 'The username must be unique' => 'Nazwa użytkownika musi być unikalna', - 'The user id is required' => 'ID użytkownika jest wymagane', - 'Passwords don\'t match' => 'Hasła nie pasują do siebie', - 'The confirmation is required' => 'Wymagane jest potwierdzenie', - 'The project is required' => 'Projekt jest wymagany', - 'The id is required' => 'ID jest wymagane', - 'The project id is required' => 'ID projektu jest wymagane', - 'The project name is required' => 'Nazwa projektu jest wymagana', - 'The title is required' => 'Tutył jest wymagany', - 'Settings saved successfully.' => 'Ustawienia zapisane.', - 'Unable to save your settings.' => 'Nie udało się zapisać ustawień.', - 'Database optimization done.' => 'Optymalizacja bazy danych zakończona.', - 'Your project have been created successfully.' => 'Projekt został pomyślnie utworzony.', - 'Unable to create your project.' => 'Nie udało się stworzyć projektu.', - 'Project updated successfully.' => 'Projekt zaktualizowany.', - 'Unable to update this project.' => 'Nie można zaktualizować projektu.', - 'Unable to remove this project.' => 'Nie można usunąć projektu.', - 'Project removed successfully.' => 'Projekt usunięty.', - 'Project activated successfully.' => 'Projekt aktywowany.', - 'Unable to activate this project.' => 'Nie można aktywować projektu.', - 'Project disabled successfully.' => 'Projekt wyłączony.', - 'Unable to disable this project.' => 'Nie można wyłączyć projektu.', - 'Unable to open this task.' => 'Nie można otworzyć tego zadania.', - 'Task opened successfully.' => 'Zadanie otwarte.', - 'Unable to close this task.' => 'Nie można zamknąć tego zadania.', - 'Task closed successfully.' => 'Zadanie zamknięte.', - 'Unable to update your task.' => 'Nie można zaktualizować tego zadania.', - 'Task updated successfully.' => 'Zadanie zaktualizowane.', - 'Unable to create your task.' => 'Nie można dodać zadania.', - 'Task created successfully.' => 'Zadanie zostało utworzone.', - 'User created successfully.' => 'Użytkownik dodany', - 'Unable to create your user.' => 'Nie udało się dodać użytkownika.', - 'User updated successfully.' => 'Profil użytkownika został zaaktualizowany.', - 'Unable to update your user.' => 'Nie udało się zaktualizować użytkownika.', - 'User removed successfully.' => 'Użytkownik usunięty.', - 'Unable to remove this user.' => 'Nie udało się usunąć użytkownika.', - 'Board updated successfully.' => 'Tablica została zaktualizowana.', - 'Ready' => 'Gotowe', - 'Backlog' => 'Log', - 'Work in progress' => 'W trakcie', - 'Done' => 'Zakończone', - 'Application version:' => 'Wersja aplikacji:', - 'Id' => 'Id', - '%d closed tasks' => '%d zamkniętych zadań', - 'No task for this project' => 'Brak zadań dla tego projektu', - 'Public link' => 'Link publiczny', - 'Timezone' => 'Strefa czasowa', - 'Sorry, I didn\'t find this information in my database!' => 'Niestety nie znaleziono tej informacji w bazie danych', - 'Page not found' => 'Strona nie istnieje', - 'Complexity' => 'Poziom trudności', - 'Task limit' => 'Limit zadań', - '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', - 'Invalid date' => 'Błędna data', - 'Automatic actions' => 'Akcje automatyczne', - 'Your automatic action have been created successfully.' => 'Twoja akcja została dodana', - 'Unable to create your automatic action.' => 'Nie udało się utworzyć akcji', - 'Remove an action' => 'Usuń akcję', - 'Unable to remove this action.' => 'Nie można usunąć akcji', - 'Action removed successfully.' => 'Akcja usunięta', - 'Automatic actions for the project "%s"' => 'Akcje automatyczne dla projektu "%s"', - 'Add an action' => 'Nowa akcja', - 'Event name' => 'Nazwa zdarzenia', - 'Action name' => 'Nazwa akcji', - 'Action parameters' => 'Parametry akcji', - 'Action' => 'Akcja', - 'Event' => 'Zdarzenie', - 'When the selected event occurs execute the corresponding action.' => 'Gdy następuje wybrane zdarzenie, uruchom odpowiednią akcję', - 'Next step' => 'Następny krok', - 'Define action parameters' => 'Zdefiniuj parametry akcji', - 'Do you really want to remove this action: "%s"?' => 'Na pewno chcesz usunąć akcję "%s"?', - 'Remove an automatic action' => 'Usuń akcję automatyczną', - 'Assign the task to a specific user' => 'Przypisz zadanie do wybranego użytkownika', - 'Assign the task to the person who does the action' => 'Przypisz zadanie do osoby wykonującej akcję', - 'Duplicate the task to another project' => 'Kopiuj zadanie do innego projektu', - 'Move a task to another column' => 'Przeniesienie zadania do innej kolumny', - 'Task modification' => 'Modyfikacja zadania', - 'Task creation' => 'Tworzenie zadania', - 'Closing a task' => 'Zamknięcie zadania', - 'Assign a color to a specific user' => 'Przypisz kolor do wybranego użytkownika', - 'Column title' => 'Tytuł kolumny', - 'Position' => 'Pozycja', - 'Duplicate to another project' => 'Skopiuj do innego projektu', - 'Duplicate' => 'Utwórz kopię', - 'link' => 'link', - 'Comment updated successfully.' => 'Komentarz został zapisany.', - 'Unable to update your comment.' => 'Nie udało się zapisać komentarza.', - 'Remove a comment' => 'Usuń komentarz', - 'Comment removed successfully.' => 'Komentarz został usunięty.', - 'Unable to remove this comment.' => 'Nie udało się usunąć komentarza.', - 'Do you really want to remove this comment?' => 'Czy na pewno usunąć ten komentarz?', - 'Current password for the user "%s"' => 'Aktualne hasło dla użytkownika "%s"', - 'The current password is required' => 'Wymanage jest aktualne hasło', - 'Wrong password' => 'Błędne hasło', - 'Unknown' => 'Nieznany', - 'Last logins' => 'Ostatnie logowania', - 'Login date' => 'Data logowania', - 'Authentication method' => 'Sposób uwierzytelnienia', - 'IP address' => 'Adres IP', - 'User agent' => 'Przeglądarka', - 'Persistent connections' => 'Stałe połączenia', - 'No session.' => 'Brak sesji.', - 'Expiration date' => 'Data zakończenia', - 'Remember Me' => 'Pamiętaj mnie', - 'Creation date' => 'Data utworzenia', - 'Everybody' => 'Wszyscy', - 'Open' => 'Otwarto', - 'Closed' => 'Zamknięto', - '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', - 'Email address invalid' => 'Błędny adres email', - 'Your external account is not linked anymore to your profile.' => 'Twoje zewnętrzne konto nie jest już połączone z profilem', - 'Unable to unlink your external account.' => 'Nie można odłączyć zewnętrznego konta', - 'External authentication failed' => 'Uwierzytelnianie zewnętrzne zakończyło się niepowodzeniem', - 'Your external account is linked to your profile successfully.' => 'Twoje zewnętrzne konto zostało pomyślnie połączone z profilem', - 'Email' => 'Email', - 'Task removed successfully.' => 'Zadanie usunięto pomyślnie.', - 'Unable to remove this task.' => 'Nie można usunąć tego zadania.', - 'Remove a task' => 'Usuń zadanie', - 'Do you really want to remove this task: "%s"?' => 'Czy na pewno chcesz usunąć zadanie "%s"?', - 'Assign automatically a color based on a category' => 'Przypisz kolor automatycznie na podstawie kategori', - 'Assign automatically a category based on a color' => 'Przypisz kategorię automatycznie na podstawie koloru', - 'Task creation or modification' => 'Tworzenie lub usuwanie zadania', - 'Category' => 'Kategoria', - 'Category:' => 'Kategoria:', - 'Categories' => 'Kategorie', - 'Your category have been created successfully.' => 'Pomyślnie utworzono kategorię.', - 'Unable to create your category.' => 'Nie można tworzyć kategorii.', - 'Your category have been updated successfully.' => 'Pomyślnie zaktualizowano kategorię', - 'Unable to update your category.' => 'Nie można zaktualizować kategorii', - 'Remove a category' => 'Usuń kategorię', - 'Category removed successfully.' => 'Pomyślnie usunięto kategorię.', - 'Unable to remove this category.' => 'Nie można usunąć tej kategorii.', - 'Category modification for the project "%s"' => 'Zmiana kategorii projektu "%s"', - 'Category Name' => 'Nazwa kategorii', - 'Add a new category' => 'Utwórz nową kategorię', - 'Do you really want to remove this category: "%s"?' => 'Czy na pewno chcesz usunąć kategorię: "%s"?', - 'All categories' => 'Wszystkie kategorie', - 'No category' => 'Brak kategorii', - 'The name is required' => 'Nazwa jest wymagana', - 'Remove a file' => 'Usuń plik', - 'Unable to remove this file.' => 'Nie można usunąć tego pliku.', - 'File removed successfully.' => 'Plik Usunięty pomyślnie.', - 'Attach a document' => 'Dołącz plik', - 'Do you really want to remove this file: "%s"?' => 'Czy na pewno chcesz usunąć plik: "%s"?', - 'Attachments' => 'Załączniki', - 'Edit the task' => 'Edytuj zadanie', - 'Add a comment' => 'Dodaj komentarz', - 'Edit a comment' => 'Edytuj komentarz', - 'Summary' => 'Podsumowanie', - 'Time tracking' => 'Śledzenie czasu', - 'Estimate:' => 'Szacowany:', - 'Spent:' => 'Przeznaczony:', - 'Do you really want to remove this sub-task?' => 'Czy na pewno chcesz usunąć to pod-zadanie?', - 'Remaining:' => 'Pozostało:', - 'hours' => 'godzin(y)', - 'spent' => 'przeznaczono', - 'estimated' => 'szacowany', - 'Sub-Tasks' => 'Pod-zadania', - 'Add a sub-task' => 'Dodaj pod-zadanie', - 'Original estimate' => 'Szacowanie początkowe', - 'Create another sub-task' => 'Dodaj kolejne pod-zadanie', - 'Time spent' => 'Spędzony czas', - 'Edit a sub-task' => 'Edytuj pod-zadanie', - 'Remove a sub-task' => 'Usuń pod-zadanie', - 'The time must be a numeric value' => 'Czas musi być wartością liczbową', - 'Todo' => 'Do zrobienia', - 'In progress' => 'W trakcie', - 'Sub-task removed successfully.' => 'Pod-zadanie usunięte pomyślnie.', - 'Unable to remove this sub-task.' => 'Nie można usunąć tego pod-zadania.', - 'Sub-task updated successfully.' => 'Pod-zadanie zaktualizowane pomyślnie.', - 'Unable to update your sub-task.' => 'Nie można zaktualizować tego pod-zadania.', - 'Unable to create your sub-task.' => 'Nie można utworzyć tego pod-zadania.', - 'Sub-task added successfully.' => 'Pod-zadanie utworzone pomyślnie', - 'Maximum size: ' => 'Maksymalny rozmiar: ', - 'Unable to upload the file.' => 'Nie można wczytać pliku.', - 'Display another project' => 'Wyświetl inny projekt', - 'Created by %s' => 'Utworzone przez %s', - 'Tasks Export' => 'Eksport zadań', - 'Tasks exportation for "%s"' => 'Eksport zadań dla "%s"', - 'Start Date' => 'Data początkowa', - 'End Date' => 'Data Końcowa', - 'Execute' => 'Wykonaj', - 'Task Id' => 'Identyfikator Zadania', - 'Creator' => 'Autor', - 'Modification date' => 'Data modyfikacji', - 'Completion date' => 'Data ukończenia', - 'Clone' => 'Sklonuj', - 'Project cloned successfully.' => 'Projekt sklonowany pomyślnie.', - 'Unable to clone this project.' => 'Nie można sklonować projektu.', - 'Enable email notifications' => 'Włącz powiadomienia email', - 'Task position:' => 'Pozycja zadania:', - 'The task #%d have been opened.' => 'Zadania #%d zostały otwarte.', - 'The task #%d have been closed.' => 'Zadania #%d zostały zamknięte.', - 'Sub-task updated' => 'Pod-zadanie zaktualizowane', - 'Title:' => 'Nazwa:', - // 'Status:' => '', - 'Assignee:' => 'Przypisano do:', - 'Time tracking:' => 'Śledzenie czasu: ', - 'New sub-task' => 'Nowe Pod-zadanie', - 'New attachment added "%s"' => 'Nowy załącznik dodany "%s"', - 'New comment posted by %s' => 'Nowy komentarz dodany przez %s', - 'New attachment' => 'Nowy załącznik', - 'New comment' => 'Nowy Komentarz', - 'Comment updated' => 'Komentarz zaktualizowany', - 'New subtask' => 'Nowe pod-zadanie', - 'Subtask updated' => 'Zaktualizowane pod-zadanie', - 'Task updated' => 'Zaktualizowane zadanie', - 'Task closed' => 'Zadanie zamknięte', - 'Task opened' => 'Zadanie otwarte', - 'I want to receive notifications only for those projects:' => 'Chcę otrzymywać powiadomienia tylko dla poniższych projektów:', - 'view the task on Kanboard' => 'Zobacz zadanie', - 'Public access' => 'Dostęp publiczny', - 'Active tasks' => 'Aktywne zadania', - 'Disable public access' => 'Zablokuj dostęp publiczny', - 'Enable public access' => 'Odblokuj dostęp publiczny', - 'Public access disabled' => 'Dostęp publiczny zablokowany', - 'Do you really want to disable this project: "%s"?' => 'Czy na pewno chcesz wyłączyć projekt: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Czy na pewno chcesz włączyć projekt: "%s"?', - 'Project activation' => 'Aktywacja projektu', - 'Move the task to another project' => 'Przenieś zadanie do innego projektu', - 'Move to another project' => 'Przenieś do innego projektu', - 'Do you really want to duplicate this task?' => 'Czy na pewno chcesz zduplikować to zadanie?', - 'Duplicate a task' => 'Zduplikuj zadanie', - 'External accounts' => 'Konta zewnętrzne', - 'Account type' => 'Typ konta', - 'Local' => 'Lokalne', - 'Remote' => 'Zdalne', - 'Enabled' => 'Odblokowane', - 'Disabled' => 'Zablokowane', - 'Username:' => 'Nazwa Użytkownika (login):', - 'Name:' => 'Imię i Nazwisko', - 'Email:' => 'Email: ', - 'Notifications:' => 'Powiadomienia: ', - 'Notifications' => 'Powiadomienia', - 'Account type:' => 'Typ konta:', - 'Edit profile' => 'Edytuj profil', - 'Change password' => 'Zmień hasło', - 'Password modification' => 'Zmiana hasła', - 'External authentications' => 'Uwierzytelnienia zewnętrzne', - 'Never connected.' => 'Nigdy nie połączone.', - 'No external authentication enabled.' => 'Brak włączonych uwierzytelnień zewnętrznych.', - 'Password modified successfully.' => 'Hasło zmienione pomyślne.', - 'Unable to change the password.' => 'Nie można zmienić hasła.', - 'Change category' => 'Zmień kategorię', - '%s updated the task %s' => '%s zaktualizował zadanie %s', - '%s opened the task %s' => '%s otworzył zadanie %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s przeniósł zadanie %s na pozycję #%d w kolumnie "%s"', - '%s moved the task %s to the column "%s"' => '%s przeniósł zadanie %s do kolumny "%s"', - '%s created the task %s' => '%s utworzył zadanie %s', - '%s closed the task %s' => '%s zamknął zadanie %s', - '%s created a subtask for the task %s' => '%s utworzył pod-zadanie dla zadania %s', - '%s updated a subtask for the task %s' => '%s zaktualizował pod-zadanie dla zadania %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Przypisano do %s z szacowanym czasem wykonania %s/%sh', - 'Not assigned, estimate of %sh' => 'Nie przypisane, szacowany czas wykonania %sh', - '%s updated a comment on the task %s' => '%s zaktualizował komentarz do zadania %s', - '%s commented the task %s' => '%s skomentował zadanie %s', - '%s\'s activity' => 'Aktywność %s', - 'RSS feed' => 'Kanał RSS', - '%s updated a comment on the task #%d' => '%s zaktualizował komentarz do zadania #%d', - '%s commented on the task #%d' => '%s skomentował zadanie #%d', - '%s updated a subtask for the task #%d' => '%s zaktualizował pod-zadanie dla zadania #%d', - '%s created a subtask for the task #%d' => '%s utworzył pod-zadanie dla zadania #%d', - '%s updated the task #%d' => '%s zaktualizował zadanie #%d', - '%s created the task #%d' => '%s utworzył zadanie #%d', - '%s closed the task #%d' => '%s zamknął zadanie #%d', - '%s open the task #%d' => '%s otworzył zadanie #%d', - '%s moved the task #%d to the column "%s"' => '%s przeniósł zadanie #%d do kolumny "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s przeniósł zadanie #%d na pozycję %d w kolmnie "%s"', - 'Activity' => 'Aktywność', - 'Default values are "%s"' => 'Domyślne wartości: "%s"', - 'Default columns for new projects (Comma-separated)' => 'Domyślne kolumny dla nowych projektów (oddzielone przecinkiem)', - 'Task assignee change' => 'Zmień osobę odpowiedzialną', - '%s change the assignee of the task #%d to %s' => '%s zmienił osobę odpowiedzialną za zadanie #%d na %s', - '%s changed the assignee of the task %s to %s' => '%s zmienił osobę odpowiedzialną za zadanie %s na %s', - 'New password for the user "%s"' => 'Nowe hasło użytkownika "%s"', - 'Choose an event' => 'Wybierz zdarzenie', - 'Create a task from an external provider' => 'Utwórz zadanie z dostawcy zewnętrznego', - 'Change the assignee based on an external username' => 'Zmień osobę odpowiedzialną na podstawie zewnętrznej nazwy użytkownika', - 'Change the category based on an external label' => 'Zmień kategorię na podstawie zewnętrznej etykiety', - // 'Reference' => '', - 'Label' => 'Etykieta', - 'Database' => 'Baza danych', - 'About' => 'Informacje', - 'Database driver:' => 'Silnik bazy danych:', - 'Board settings' => 'Ustawienia tablicy', - 'Webhook settings' => 'Ustawienia webhook', - 'Reset token' => 'Resetuj token', - 'API endpoint:' => 'Endpoint API', - 'Refresh interval for private board' => 'Częstotliwość odświeżania dla tablicy prywatnej', - 'Refresh interval for public board' => 'Częstotliwość odświeżania dla tablicy publicznej', - 'Task highlight period' => 'Okres wyróżniania zadań', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Okres (w sekundach) wymagany do uznania projektu za niedawno zmieniony (0 ab zablokować, domyślnie 2 dni)', - 'Frequency in second (60 seconds by default)' => 'Częstotliwość w sekundach (domyślnie 60 sekund)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Częstotliwość w sekundach (0 aby zablokować, domyślnie 10 sekund)', - 'Application URL' => 'Adres URL aplikacji', - 'Token regenerated.' => 'Token wygenerowany ponownie.', - 'Date format' => 'Format daty', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO jest zawsze akceptowany, przykłady: "%s", "%s"', - 'New private project' => 'Nowy projekt prywatny', - 'This project is private' => 'Ten projekt jest prywatny', - 'Add' => 'Dodaj', - 'Start date' => 'Data rozpoczęcia', - 'Time estimated' => 'Szacowany czas', - 'There is nothing assigned to you.' => 'Nie ma przypisanych zadań', - 'My tasks' => 'Moje zadania', - 'Activity stream' => 'Strumień aktywności', - 'Dashboard' => 'Dashboard', - 'Confirmation' => 'Potwierdzenie', - 'Allow everybody to access to this project' => 'Udostępnij ten projekt wszystkim', - 'Everybody have access to this project.' => 'Wszyscy mają dostęp do tego projektu.', - 'Webhooks' => 'Webhooki', - // 'API' => '', - 'Create a comment from an external provider' => 'Utwórz komentarz od zewnętrznego dostawcy', - 'Project management' => 'Menadżer projektu', - 'My projects' => 'Moje projekty', - 'Columns' => 'Kolumny', - 'Task' => 'Zadanie', - 'Your are not member of any project.' => 'Nie bierzesz udziału w żadnym projekcie', - 'Percentage' => 'Procent', - 'Number of tasks' => 'Liczba zadań', - 'Task distribution' => 'Rozmieszczenie zadań', - 'Reportings' => 'Raporty', - 'Task repartition for "%s"' => 'Przydział zadań dla "%s"', - 'Analytics' => 'Analizy', - 'Subtask' => 'Pod-zadanie', - 'My subtasks' => 'Moje pod-zadania', - 'User repartition' => 'Przydział użytkownika', - 'User repartition for "%s"' => 'Przydział użytkownika dla "%s"', - 'Clone this project' => 'Sklonuj ten projekt', - 'Column removed successfully.' => 'Kolumna usunięta pomyślnie.', - 'Not enough data to show the graph.' => 'Za mało danych do utworzenia wykresu.', - 'Previous' => 'Poprzedni', - 'The id must be an integer' => 'ID musi być liczbą całkowitą', - 'The project id must be an integer' => 'ID projektu musi być liczbą całkowitą', - 'The status must be an integer' => 'Status musi być liczbą całkowitą', - 'The subtask id is required' => 'ID pod-zadanie jest wymagane', - 'The subtask id must be an integer' => 'ID pod-zadania musi być liczbą całkowitą', - 'The task id is required' => 'ID zadania jest wymagane', - 'The task id must be an integer' => 'ID zadania musi być liczbą całkowitą', - 'The user id must be an integer' => 'ID użytkownika musi być liczbą całkowitą', - 'This value is required' => 'Wymagana wartość', - 'This value must be numeric' => 'Wartość musi być liczbą', - 'Unable to create this task.' => 'Nie można tworzyć zadania.', - 'Cumulative flow diagram' => 'Zbiorowy diagram przepływu', - 'Cumulative flow diagram for "%s"' => 'Zbiorowy diagram przepływu dla "%s"', - 'Daily project summary' => 'Dzienne raport z projektu', - 'Daily project summary export' => 'Eksport dziennego podsumowania projektu', - 'Daily project summary export for "%s"' => 'Wygeneruj dzienny raport dla projektu: "%s"', - 'Exports' => 'Eksporty', - 'This export contains the number of tasks per column grouped per day.' => 'Ten eksport zawiera ilość zadań zgrupowanych w kolumnach na dzień', - 'Active swimlanes' => 'Aktywne tory', - 'Add a new swimlane' => 'Dodaj tor', - 'Change default swimlane' => 'Zmień domyślny tor', - 'Default swimlane' => 'Domyślny tor', - 'Do you really want to remove this swimlane: "%s"?' => 'Czy na pewno chcesz usunąć tor: "%s"?', - 'Inactive swimlanes' => 'Nieaktywne tory', - 'Remove a swimlane' => 'Usuń tor', - 'Show default swimlane' => 'Pokaż domyślny tor', - 'Swimlane modification for the project "%s"' => 'Edycja torów dla projektu "%s"', - 'Swimlane removed successfully.' => 'Tor usunięty pomyślnie.', - 'Swimlanes' => 'Tory', - 'Swimlane updated successfully.' => 'Zaktualizowano tor.', - 'The default swimlane have been updated successfully.' => 'Domyślny tor zaktualizowany pomyślnie.', - 'Unable to remove this swimlane.' => 'Nie można usunąć toru.', - 'Unable to update this swimlane.' => 'Nie można zaktualizować toru.', - 'Your swimlane have been created successfully.' => 'Tor utworzony pomyślnie.', - 'Example: "Bug, Feature Request, Improvement"' => 'Przykład: "Błąd, Żądanie Funkcjonalności, Udoskonalenia"', - 'Default categories for new projects (Comma-separated)' => 'Domyślne kategorie dla nowych projektów (oddzielone przecinkiem)', - 'Integrations' => 'Integracje', - 'Integration with third-party services' => 'Integracja z usługami firm trzecich', - 'Subtask Id' => 'ID pod-zadania', - 'Subtasks' => 'Pod-zadania', - 'Subtasks Export' => 'Eksport pod-zadań', - 'Subtasks exportation for "%s"' => 'Wygeneruj raport pod-zadań dla projektu "%s"', - 'Task Title' => 'Nazwa zadania', - 'Untitled' => 'Bez nazwy', - 'Application default' => 'Domyślne dla aplikacji', - 'Language:' => 'Język:', - 'Timezone:' => 'Strefa czasowa:', - 'All columns' => 'Wszystkie kolumny', - 'Calendar' => 'Kalendarz', - 'Next' => 'Następny', - '#%d' => 'nr %d', - 'All swimlanes' => 'Wszystkie tory', - 'All colors' => 'Wszystkie kolory', - 'Moved to column %s' => 'Przeniosiono do kolumny %s', - 'User dashboard' => 'Panel użytkownika', - 'Allow only one subtask in progress at the same time for a user' => 'Zezwalaj na tylko jedno pod-zadanie o statusie "w trakcie" jednocześnie', - 'Edit column "%s"' => 'Zmień kolumnę "%s"', - 'Select the new status of the subtask: "%s"' => 'Wybierz nowy status dla pod-zadania: "%s"', - 'Subtask timesheet' => 'Oś czasu pod-zadania', - 'There is nothing to show.' => 'Nie nic do wyświetlenia', - 'Time Tracking' => 'Śledzenie czasu', - 'You already have one subtask in progress' => 'Masz już zadanie o statusie "w trakcie"', - 'Which parts of the project do you want to duplicate?' => 'Które elementy projektu chcesz zduplikować?', - 'Disallow login form' => 'Zablokuj możliwość logowania', - 'Start' => 'Początek', - 'End' => 'Koniec', - 'Task age in days' => 'Wiek zadania w dniach', - 'Days in this column' => 'Dni w tej kolumnie', - // '%dd' => '', - 'Add a new link' => 'Dodaj nowy link', - 'Do you really want to remove this link: "%s"?' => 'Czy na pewno chcesz usunąć ten link: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Czy na pewno chcesz usunąć ten link razem z zadaniem nr %d?', - 'Field required' => 'Pole wymagane', - 'Link added successfully.' => 'Link dodany', - 'Link updated successfully.' => 'Link zaktualizowany', - 'Link removed successfully.' => 'Link usunięty', - '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', - 'Unable to create your link.' => 'Nie można utworzyć linku.', - 'Unable to update your link.' => 'Nie można zaktualizować linku,', - 'Unable to remove this link.' => 'Nie można usunąć linku,', - 'relates to' => 'odnosi się do', - 'blocks' => 'blokuje', - 'is blocked by' => 'jest blokowane przez', - 'duplicates' => 'duplikuje', - 'is duplicated by' => 'jest duplikowane przez', - 'is a child of' => 'jest dzieckiem', - 'is a parent of' => 'jest rodzicem', - 'targets milestone' => 'oznacza krok milowy', - 'is a milestone of' => 'jest krokiem milowym', - 'fixes' => 'naprawia', - 'is fixed by' => 'zostało naprawione przez', - 'This task' => 'To zadanie', - // '<1h' => '', - // '%dh' => '', - 'Expand tasks' => 'Rozwiń zadania', - 'Collapse tasks' => 'Zwiń zadania', - 'Expand/collapse tasks' => 'Zwiń/Rozwiń zadania', - 'Close dialog box' => 'Zamknij okno', - 'Submit a form' => 'Wyślij formularz', - 'Board view' => 'Widok tablicy', - 'Keyboard shortcuts' => 'Skróty klawiszowe', - 'Open board switcher' => 'Przełącz tablice', - 'Application' => 'Aplikacja', - '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', - 'CAD - Canadian Dollar' => 'CAD - Dolar kanadyjski', - 'CHF - Swiss Francs' => 'CHF - Frank szwajcarski', - 'Custom Stylesheet' => 'Niestandardowy arkusz stylów', - 'download' => 'pobierz', - // 'EUR - Euro' => '', - 'GBP - British Pound' => 'GBP - Funt brytyjski', - 'INR - Indian Rupee' => 'INR - Rupia indyjska', - 'JPY - Japanese Yen' => 'JPY - Jen japoński', - 'NZD - New Zealand Dollar' => 'NZD - Dolar nowozelandzki', - 'RSD - Serbian dinar' => 'RSD - Dinar serbski', - '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', - 'Move the task to another column when assignee is cleared' => 'Przenieś zadanie do innej kolumny gdy osoba odpowiedzialna zostanie usunięta', - 'Source column' => 'Kolumna źródłowa', - 'Transitions' => 'Przeniesienia', - 'Executer' => 'Wykonał', - 'Time spent in the column' => 'Czas spędzony w tej kolumnie', - 'Task transitions' => 'Przeniesienia zadań', - 'Task transitions export' => 'Wygeneruj raport z przeniesień zadań', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Ten raport zawiera wszystkie przeniesienia pomiędzy kolumnami wraz z datą oraz osobą odpowiedzialną', - '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', - 'Webhook URL' => 'Adres webhooka', - '%s remove the assignee of the task %s' => '%s usunął osobę przypisaną do zadania %s', - 'Enable Gravatar images' => 'Włącz Gravatar', - 'Information' => 'Informacje', - 'Check two factor authentication code' => 'Sprawdź kod weryfikujący', - 'The two factor authentication code is not valid.' => 'Kod weryfikujący niepoprawny', - 'The two factor authentication code is valid.' => 'Kod weryfikujący poprawny', - 'Code' => 'Kod', - 'Two factor authentication' => 'Dwustopniowe uwierzytelnianie', - 'This QR code contains the key URI: ' => 'Ten kod QR zawiera URI klucza: ', - 'Check my code' => 'Sprawdź kod', - 'Secret key: ' => 'Tajny kod: ', - 'Test your device' => 'Przetestuj urządzenie', - 'Assign a color when the task is moved to a specific column' => 'Przypisz kolor gdy zadanie jest przeniesione do danej kolumny', - '%s via Kanboard' => '%s poprzez Kanboard', - 'Burndown chart for "%s"' => 'Wykres Burndown dla "%s"', - 'Burndown chart' => 'Wykres Burndown', - 'This chart show the task complexity over the time (Work Remaining).' => 'Ten wykres pokazuje złożoność zadania na przestrzeni czasu (pozostała praca).', - 'Screenshot taken %s' => 'Zrzut ekranu zapisany %s', - 'Add a screenshot' => 'Dołącz zrzut ekranu', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Zrób zrzut ekranu i wciśnij CTRL+V by dodać go tutaj.', - 'Screenshot uploaded successfully.' => 'Zrzut ekranu dodany.', - 'SEK - Swedish Krona' => 'SEK - Korona szwedzka', - 'Identifier' => 'Identyfikator', - 'Disable two factor authentication' => 'Wyłącz dwustopniowe uwierzytelnianie', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Czy na pewno chcesz wyłączyć dwustopniowe uwierzytelnianie dla tego użytkownika: "%s"?', - 'Edit link' => 'Edytuj link', - 'Start to type task title...' => 'Rozpocznij wpisywanie tytułu zadania...', - 'A task cannot be linked to itself' => 'Link do zadania nie może wskazywać na samego siebie', - 'The exact same link already exists' => 'Taki link już istnieje', - 'Recurrent task is scheduled to be generated' => 'Zaplanowano zadanie cykliczne', - 'Score' => 'Wynik', - 'The identifier must be unique' => 'Identyfikator musi być unikatowy', - 'This linked task id doesn\'t exists' => 'Id zadania nie istnieje', - 'This value must be alphanumeric' => 'Ta wartość musi być alfanumeryczna', - 'Edit recurrence' => 'Edytuj rekurencje', - 'Generate recurrent task' => 'Włącz rekurencje', - 'Trigger to generate recurrent task' => 'Wyzwalacz tworzący zadanie cykliczne', - 'Factor to calculate new due date' => 'Czynnik wyliczający nowy termin', - 'Timeframe to calculate new due date' => 'Ramy czasowe do wyliczenia nowego terminu', - 'Base date to calculate new due date' => 'Data bazowa do wyliczenia nowego terminu', - 'Action date' => 'Data akcji', - 'Base date to calculate new due date: ' => 'Data bazowa do wyliczenia nowego terminu: ', - 'This task has created this child task: ' => 'Zadanie utworzyło zadanie pokrewne: ', - 'Day(s)' => 'Dni', - 'Existing due date' => 'Istniejący termin', - 'Factor to calculate new due date: ' => 'Czynnik wyliczający nowy termin: ', - 'Month(s)' => 'Miesięcy', - 'Recurrence' => 'Cykl', - 'This task has been created by: ' => 'Zadanie utworzone przez: ', - 'Recurrent task has been generated:' => 'Zadanie cykliczne zostało utworzone: ', - 'Timeframe to calculate new due date: ' => 'Ramy czasowe do wyliczenia nowego terminu: ', - 'Trigger to generate recurrent task: ' => 'Wyzwalacz tworzący zadanie cykliczne: ', - 'When task is closed' => 'Zamknięcie zadania', - 'When task is moved from first column' => 'Przeniesienie zadania z pierwszej kolumny', - 'When task is moved to last column' => 'Przeniesienie zadania do ostatniej kolumny', - 'Year(s)' => 'Lat', - 'Calendar settings' => 'Ustawienia kalendarza', - 'Project calendar view' => 'Widok kalendarza projektu', - 'Project settings' => 'Ustawienia Projektu', - 'Show subtasks based on the time tracking' => 'Pokaż pod-zadania w śledzeniu czasu', - 'Show tasks based on the creation date' => 'Pokaż zadania względem daty utworzenia', - 'Show tasks based on the start date' => 'Pokaż zadania względem daty rozpoczęcia', - 'Subtasks time tracking' => 'Śledzenie czasu pod-zadań', - 'User calendar view' => 'Widok kalendarza użytkownika', - 'Automatically update the start date' => 'Automatycznie aktualizuj datę rozpoczęcia', - // 'iCal feed' => '', - 'Preferences' => 'Ustawienia', - 'Security' => 'Zabezpieczenia', - 'Two factor authentication disabled' => 'Dwustopniowe uwierzytelnianie wyłączone', - 'Two factor authentication enabled' => 'Dwustopniowe uwierzytelnianie włączone', - 'Unable to update this user.' => 'Nie można zaktualizować tego użytkownika', - 'There is no user management for private projects.' => 'Projekty prywatne nie wspierają zarządzania użytkownikami. Projekt prywatny ma tylko jednego użytkownika.', - 'User that will receive the email' => 'Adresat', - 'Email subject' => 'Temat', - 'Date' => 'Data', - 'Add a comment log when moving the task between columns' => 'Wygeneruj komentarz pod zadaniem podczas przenoszenia między kolumnami', - 'Move the task to another column when the category is changed' => 'Przenieś zadanie do innej kolumny gdy kategoria ulegnie zmianie', - 'Send a task by email to someone' => 'Wyślij zadanie emailem do kogoś', - 'Reopen a task' => 'Otwórz ponownie zadanie', - 'Column change' => 'Zmiana kolumny', - 'Position change' => 'Zmiana pozycji', - 'Swimlane change' => 'Zmiana toru', - 'Assignee change' => 'Zmiana przypisanego użytkownika', - '[%s] Overdue tasks' => '[%s] zaległych zadań', - 'Notification' => 'Powiadomienie', - '%s moved the task #%d to the first swimlane' => '%s przeniosł zadanie #%d na pierwszy tor', - '%s moved the task #%d to the swimlane "%s"' => '%s przeniosł zadanie #%d na tor "%s"', - 'Swimlane' => 'Tor', - // 'Gravatar' => '', - '%s moved the task %s to the first swimlane' => '%s przeniosł zadanie %s na pierwszy tor', - '%s moved the task %s to the swimlane "%s"' => '%s przeniosł zadanie %s na tor "%s"', - 'This report contains all subtasks information for the given date range.' => 'Niniejszy raport zawiera wszystkie informacje o pod-zadaniach dla podanego zakresu dat.', - 'This report contains all tasks information for the given date range.' => 'Niniejszy raport zawiera wszystkie informacje o zadaniach dla podanego zakresu dat.', - 'Project activities for %s' => 'Aktywności w ramach projektu dla %s', - 'view the board on Kanboard' => 'Zobacz tablice', - 'The task have been moved to the first swimlane' => 'Zadanie zostało przeniesione do piewszego toru', - 'The task have been moved to another swimlane:' => 'Zadanie zostało przeniesione do innego toru:', - 'New title: %s' => 'Nowy tytuł: %s', - 'The task is not assigned anymore' => 'Brak osoby odpowiedzialnej za zadanie', - 'New assignee: %s' => 'Nowy odpowiedzialny: %s', - 'There is no category now' => 'Aktualnie zadanie nie posiada kategorii', - 'New category: %s' => 'Nowa kategoria: %s', - 'New color: %s' => 'Nowy kolor: %s', - 'New complexity: %d' => 'Nowa złożoność: %d', - 'The due date have been removed' => 'Termin został usunięty', - 'There is no description anymore' => 'Nie ma już opisu', - 'Recurrence settings have been modified' => 'Ustawienia cyklu zostały zmienione', - 'Time spent changed: %sh' => 'Spędzony czas uległ zmianie: %sh', - 'Time estimated changed: %sh' => 'Szacowany czas uległ zmianie: %sh', - 'The field "%s" have been updated' => 'Pole "%s" zostało zaktualizowane', - 'The description has been modified:' => 'Opis został zmodyfikowany:', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Naprawdę chcesz zamknąć zadanie "%s" wraz z wszystkimi pod-zadaniami?', - 'I want to receive notifications for:' => 'Wysyłaj powiadomienia dla:', - 'All tasks' => 'Wszystkich zadań', - 'Only for tasks assigned to me' => 'Tylko zadań przypisanych do mnie', - 'Only for tasks created by me' => 'Tylko zadań utworzonych przeze mnie', - 'Only for tasks created by me and assigned to me' => 'Tylko zadań przypisanych lub utworzonych przeze mnie', - // '%%Y-%%m-%%d' => '', - 'Total for all columns' => 'Ogółem dla wszystkich kolumn', - 'You need at least 2 days of data to show the chart.' => 'Potrzebujesz przynajmniej 2 dni by wyświetlić wykres', - // '<15m' => '', - // '<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ń', - 'Reset filters' => 'Resetuj zastosowane filtry', - 'My tasks due tomorrow' => 'Moje zadania do jutra', - 'Tasks due today' => 'Zadania do dzisiaj', - 'Tasks due tomorrow' => 'Zadania do jutra', - 'Tasks due yesterday' => 'Zadania na wczoraj', - 'Closed tasks' => 'Zamknięte zadania', - 'Open tasks' => 'Otwarte zadania', - 'Not assigned' => 'Nieprzypisane zadania', - 'View advanced search syntax' => 'Pomoc dotycząca budowania filtrów', - 'Overview' => 'Podsumowanie', - 'Board/Calendar/List view' => 'Widok: Tablica/Kalendarz/Lista', - 'Switch to the board view' => 'Przełącz na tablicę', - 'Switch to the calendar view' => 'Przełącz na kalendarz', - 'Switch to the list view' => 'Przełącz na listę', - 'Go to the search/filter box' => 'Użyj pola wyszukiwania/filtrów', - 'There is no activity yet.' => 'Brak powiadomień', - 'No tasks found.' => 'Nie znaleziono zadań', - 'Keyboard shortcut: "%s"' => 'Skrót klawiaturowy: "%s"', - 'List' => 'Lista', - 'Filter' => 'Filtr', - 'Advanced search' => 'Zaawansowane wyszukiwanie', - 'Example of query: ' => 'Przykładowe zapytanie:', - 'Search by project: ' => 'Szukaj wg projektów:', - 'Search by column: ' => 'Szukaj wg kolumn:', - 'Search by assignee: ' => 'Szukaj wg użytkownika:', - 'Search by color: ' => 'Szukaj wg koloru:', - 'Search by category: ' => 'Szukaj wg kategorii:', - 'Search by description: ' => 'Szukaj wg opisu:', - 'Search by due date: ' => 'Szukaj wg terminu:', - 'Lead and Cycle time for "%s"' => 'Czas cyklu i realizacji dla "%s"', - 'Average time spent into each column for "%s"' => 'Średni czas spędzony w każdej z kolumn dla "%s"', - 'Average time spent into each column' => 'Średni czas spędzony w każdej z kolumn', - 'Average time spent' => 'Średni spędzony czas', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Niniejszy wykres pokazuje średni czas spędzony w każdej z kolumn dla ostatnich %d zadań.', - 'Average Lead and Cycle time' => 'Średni czas cyklu i realizacji', - 'Average lead time: ' => 'Średni czas realizacji:', - 'Average cycle time: ' => 'Średni czas cyklu:', - 'Cycle Time' => 'Czas cyklu', - 'Lead Time' => 'Czas realizacji', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Niniejszy wykres pokazuje średni czas cyklu i realizacji dla ostatnich %d zadań na przestrzeni czasu.', - 'Average time into each column' => 'Średni czas dla każdej kolumny', - 'Lead and cycle time' => 'Czas cyklu i realizacji', - 'Lead time: ' => 'Czas realizacji:', - 'Cycle time: ' => 'Czas cyklu:', - 'Time spent into each column' => 'Czas spędzony przez zadanie w każdej z kolumn', - 'The lead time is the duration between the task creation and the completion.' => 'Czas realizacji pomiędzy utworzeniem a ukończeniem zadania.', - 'The cycle time is the duration between the start date and the completion.' => 'Czas cyklu pomiędzy datą rozpoczęcia a ukończeniem zadania.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Jeśli zadanie nie jest zamknięte, bieżący czas zostaje użyty zamiast daty ukończenia.', - 'Set automatically the start date' => 'Ustaw automatycznie datę rozpoczęcia', - 'Edit Authentication' => 'Edycja uwierzytelnienia', - '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.', - 'Trigger automatically subtask time tracking' => 'Ustaw automatyczne śledzenie czasu dla pod-zadań', - 'Include closed tasks in the cumulative flow diagram' => 'Obejmuj zamknięte zadania w zbiorczym diagramie przepływu', - 'Current swimlane: %s' => 'Bieżący tor: %s', - 'Current column: %s' => 'Bieżąca kolumna: %s', - 'Current category: %s' => 'Bieżąca kategoria: %s', - 'no category' => 'brak kategorii', - 'Current assignee: %s' => 'Aktualnie odpowiedzialna osoba: %s', - 'not assigned' => 'Brak osoby odpowiedzialnej', - 'Author:' => 'Autor', - 'contributors' => 'współautorzy', - 'License:' => 'Licencja:', - 'License' => 'Licencja', - 'Enter the text below' => 'Wpisz tekst poniżej', - 'Gantt chart for %s' => 'Wykres Gantt dla %s', - 'Sort by position' => 'Sortuj wg pozycji', - 'Sort by date' => 'Sortuj wg daty', - 'Add task' => 'Dodaj zadanie', - 'Start date:' => 'Data rozpoczęcia:', - 'Due date:' => 'Termin', - 'There is no start date or due date for this task.' => 'Brak daty rozpoczęcia lub terminu zadania', - 'Moving or resizing a task will change the start and due date of the task.' => 'Przeniesienie bądź edycja zmieni datę rozpoczęcia oraz termin ukończenia zadania.', - 'There is no task in your project.' => 'Brak zadań w projekcie.', - 'Gantt chart' => 'Wykres Gantta', - 'People who are project managers' => 'Użytkownicy będący menedżerami projektu', - 'People who are project members' => 'Użytkownicy będący uczestnikami projektu', - 'NOK - Norwegian Krone' => 'NOK - Korona norweska', - 'Show this column' => 'Pokaż tą kolumnę', - 'Hide this column' => 'Ukryj tą kolumnę', - 'open file' => 'otwórz plik', - 'End date' => 'Data zakończenia', - 'Users overview' => 'Przegląd użytkowników', - 'Members' => 'Członkowie', - 'Shared project' => 'Projekt udostępniony', - 'Project managers' => 'Menedżerowie projektu', - 'Gantt chart for all projects' => 'Wykres Gantta dla wszystkich projektów', - 'Projects list' => 'Lista projektów', - 'Gantt chart for this project' => 'Wykres Gantta dla bieżacego projektu', - 'Project board' => 'Talica projektu', - 'End date:' => 'Data zakończenia:', - 'There is no start date or end date for this project.' => 'Nie zdefiniowano czasu trwania projektu', - 'Projects Gantt chart' => 'Wykres Gantta dla projektów', - 'Change task color when using a specific task link' => 'Zmień kolor zadania używając specjalnego adresu URL', - 'Task link creation or modification' => 'Adres URL do utworzenia zadania lub modyfikacji', - 'Milestone' => 'Kamień milowy', - 'Documentation: %s' => 'Dokumentacja: %s', - 'Switch to the Gantt chart view' => 'Przełącz na wykres Gantta', - 'Reset the search/filter box' => 'Zresetuj pole wyszukiwania/filtrowania', - 'Documentation' => 'Dokumentacja', - 'Table of contents' => 'Tablica zawartości', - // 'Gantt' => '', - 'Author' => 'Autor', - 'Version' => 'Wersja', - 'Plugins' => 'Wtyczki', - 'There is no plugin loaded.' => 'Nie wykryto żadnych wtyczek.', - 'Set maximum column height' => 'Rozwiń kolumny', - 'Remove maximum column height' => 'Zwiń kolumny', - 'My notifications' => 'Powiadomienia', - 'Custom filters' => 'Dostosuj filtry', - 'Your custom filter have been created successfully.' => 'Niestandardowy filtr został utworzony.', - 'Unable to create your custom filter.' => 'Nie można utworzyć niestandardowego filtra.', - 'Custom filter removed successfully.' => 'Niestandardowy filtr został usunięty.', - 'Unable to remove this custom filter.' => 'Nie można usunąć niestandardowego filtra.', - 'Edit custom filter' => 'Edytuj niestandardowy filtr', - 'Your custom filter have been updated successfully.' => 'Niestandardowy filtr został zaktualizowany', - 'Unable to update custom filter.' => 'Nie można zaktualizować niestandardowego filtra.', - // 'Web' => '', - 'New attachment on task #%d: %s' => 'Nowy załącznik do zadania #%d: %s', - 'New comment on task #%d' => 'Nowy komentarz do zadania #%d', - 'Comment updated on task #%d' => 'Aktualizacja komentarza do zadania #%d', - 'New subtask on task #%d' => 'Nowe pod-zadanie dla zadania #%d', - 'Subtask updated on task #%d' => 'Aktualizacja pod-zadania w zadaniu #%d', - 'New task #%d: %s' => 'Nowe zadanie #%d: %s', - 'Task updated #%d' => 'Aktualizacja zadania #%d', - 'Task #%d closed' => 'Zamknięto zadanie #%d', - 'Task #%d opened' => 'Otwarto zadanie #%d', - 'Column changed for task #%d' => 'Zmieniono kolumnę zadania #%d', - 'New position for task #%d' => 'Ustalono nową pozycję zadania #%d', - 'Swimlane changed for task #%d' => 'Zmieniono tor dla zadania #%d', - 'Assignee changed on task #%d' => 'Zmieniono osobę odpowiedzialną dla zadania #%d', - '%d overdue tasks' => '%d zaległych zadań', - 'Task #%d is overdue' => 'Zadanie #%d jest zaległe', - 'No new notifications.' => 'Brak nowych powiadomień.', - 'Mark all as read' => 'Oznacz wszystkie jako przeczytane', - 'Mark as read' => 'Oznacz jako przeczytane', - 'Total number of tasks in this column across all swimlanes' => 'Całkowita liczba zadań z tej kolumny z wszystkich torów', - 'Collapse swimlane' => 'Zwiń tor', - 'Expand swimlane' => 'Rozwiń tor', - 'Add a new filter' => 'Dodaj nowy filtr', - 'Share with all project members' => 'Udostępnij wszystkim uczestnikom projektu', - 'Shared' => 'Udostępnione', - '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!', - 'Import users from CSV file' => 'Importuj użytkowników z pliku CSV', - '%d user(s) have been imported successfully.' => '%d użytkowników zostało zaimportowanych.', - 'Comma' => 'Przecinek', - 'Semi-colon' => 'Średnik', - 'Tab' => 'Tabulacja', - 'Vertical bar' => 'Kreska pionowa', - 'Double Quote' => 'Cudzysłów', - 'Single Quote' => 'Apostrof', - '%s attached a file to the task #%d' => '%s dołączył(a) plik do zadania #%d', - 'There is no column or swimlane activated in your project!' => 'Żaden tor badź kolumna nie została aktywowana!', - 'Append filter (instead of replacement)' => 'Dołączaj filtr do zastosowanego filtru(zamiast przełączać)', - 'Append/Replace' => 'Dołącz/Zastąp', - 'Append' => 'Dołącz', - 'Replace' => 'Zastąp', - 'Import' => 'Importuj', - 'change sorting' => 'odwróć sortowanie', - 'Tasks Importation' => 'Import zadań', - 'Delimiter' => 'Separator pola', - 'Enclosure' => 'Separator tekstu', - 'CSV File' => 'Plik CSV', - 'Instructions' => 'Instrukcje', - 'Your file must use the predefined CSV format' => 'Twój plik musi być zgodny z predefiniowanym formatem CSV (pobierz szablon)', - 'Your file must be encoded in UTF-8' => 'Twój plik musi być kodowany w UTF-8', - 'The first row must be the header' => 'Pierwszy wiersz pliku musi definiować nagłówki', - 'Duplicates are not verified for you' => 'Duplikaty nie będą weryfikowane', - 'The due date must use the ISO format: YYYY-MM-DD' => 'Data musi być w formacie ISO: YYYY-MM-DD', - 'Download CSV template' => 'Pobierz szablon pliku CSV', - 'No external integration registered.' => 'Żadna zewnętrzna integracja nie została zarejestrowana.', - 'Duplicates are not imported' => 'Duplikaty nie zostaną zaimportowane', - 'Usernames must be lowercase and unique' => 'Nazwy użytkowników muszą być unikalne i składać się z małych liter', - 'Passwords will be encrypted if present' => 'Hasła zostaną zaszyfrowane jeśli występują', - '%s attached a new file to the task %s' => '%s załączył nowy plik do zadania %s', - 'Link type' => 'Rodzaj link\'u', - 'Assign automatically a category based on a link' => 'Przypisz kategorię automatycznie na podstawie linku', - 'BAM - Konvertible Mark' => 'BAM - Bośnia i Hercegowina Cabrio Marka', - 'Assignee Username' => 'Przypisz nazwę użytkownika', - 'Assignee Name' => 'Przypisz imię', - 'Groups' => 'Grupy', - 'Members of %s' => 'Członkowie %s', - 'New group' => 'Nowa grupa', - 'Group created successfully.' => 'Grupa została utworzona.', - 'Unable to create your group.' => 'Nie można utworzyć grupy.', - 'Edit group' => 'Edytuj grupę', - 'Group updated successfully.' => 'Grupa została zaaktualizowana.', - 'Unable to update your group.' => 'Nie można zaaktualizować grupy.', - 'Add group member to "%s"' => 'Dodaj członka do grupy "%s"', - 'Group member added successfully.' => 'Użytkownik został dodany do grupy.', - 'Unable to add group member.' => 'Nie można dodać użytkownika do grupy.', - 'Remove user from group "%s"' => 'Usuń użytkownika z grupy "%s"', - 'User removed successfully from this group.' => 'Użytkownik został usunięty z grupy.', - 'Unable to remove this user from the group.' => 'Nie można usunąć użytkownika z grupy.', - 'Remove group' => 'Usuń grupę', - 'Group removed successfully.' => 'Grupa została usunięta.', - 'Unable to remove this group.' => 'Nie można usunąć grupy.', - 'Project Permissions' => 'Prawa dostępowe projektu', - 'Manager' => 'Menedżer', - 'Project Manager' => 'Menedżer projektu', - 'Project Member' => 'Uczestnik projektu', - 'Project Viewer' => 'Obserwator projektu', - 'Your account is locked for %d minutes' => 'Twoje konto zostało zablokowane na %d minut', - 'Invalid captcha' => 'Błędny kod z obrazka (captcha)', - 'The name must be unique' => 'Nazwa musi być unikatowa', - 'View all groups' => 'Wyświetl wszystkie grupy', - 'View group members' => 'Wyświetl wszystkich członków grupy', - 'There is no user available.' => 'Żaden użytkownik nie jest dostępny.', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Czy na pewno chcesz usunąć użytkownika "%s" z grupy "%s"?', - 'There is no group.' => 'Nie utworzono jeszcze żadnej grupy.', - 'External Id' => 'Zewnętrzny Id', - 'Add group member' => 'Dodaj członka grupy', - 'Do you really want to remove this group: "%s"?' => 'Czy na pewno chcesz usunąć grupę "%s"?', - 'There is no user in this group.' => 'Wybrana grupa nie posiada członków.', - 'Remove this user' => 'Usuń użytkownika', - 'Permissions' => 'Prawa dostępu', - 'Allowed Users' => 'Użytkownicy, którzy mają dostęp', - 'No user have been allowed specifically.' => 'Żaden użytkownik nie ma przyznanego dostępu.', - 'Role' => 'Rola', - 'Enter user name...' => 'Wprowadź nazwę użytkownika...', - 'Allowed Groups' => 'Grupy, które mają dostęp', - 'No group have been allowed specifically.' => 'Żadna grupa nie ma przyznanego dostępu.', - 'Group' => 'Grupa', - 'Group Name' => 'Nazwa grupy', - 'Enter group name...' => 'Wprowadź nazwę grupy...', - 'Role:' => 'Rola:', - 'Project members' => 'Uczestnicy projektu', - 'Compare hours for "%s"' => 'Porównaj godziny dla "%s"', - '%s mentioned you in the task #%d' => '%s wspomiał o Tobie w zadaniu #%d', - '%s mentioned you in a comment on the task #%d' => '%s wspomiał o Tobie w komentarzu do zadania #%d', - 'You were mentioned in the task #%d' => 'Wspomiano o Tobie w zadaniu #%d', - 'You were mentioned in a comment on the task #%d' => 'Wspomiano o Tobie w komentarzu do zadania #%d', - 'Mentioned' => 'Wspomiano', - 'Compare Estimated Time vs Actual Time' => 'Porównaj szacowany czas z rzeczywistym', - 'Estimated hours: ' => 'Szacowane godziny: ', - 'Actual hours: ' => 'Rzeczywiste godziny: ', - 'Hours Spent' => 'Spędzone godziny', - 'Hours Estimated' => 'Szacowane godziny', - 'Estimated Time' => 'Szacowany czas', - 'Actual Time' => 'Rzeczywisty czas', - 'Estimated vs actual time' => 'Szacowany vs rzeczywisty czas', - 'RUB - Russian Ruble' => 'RUB - Rosyjskie Ruble', - 'Assign the task to the person who does the action when the column is changed' => 'Przypisz zadanie do osoby wykonującej akcję gdy kolumna zostanie zmodyfikowana', - 'Close a task in a specific column' => 'Zamknij zadanie w określonej kolumnie', - // 'Time-based One-time Password Algorithm' => '', - 'Two-Factor Provider: ' => 'Dostawca: ', - 'Disable two-factor authentication' => 'Wyłącz dwustopniowe uwierzytelnianie', - 'Enable two-factor authentication' => 'Włącz dwustopniowe uwierzytelnianie', - 'There is no integration registered at the moment.' => 'W chwili obecnej nie ma zarejestrowanej żadnej integracji.', - 'Password Reset for Kanboard' => 'Resetuj hasło do Kanboarda', - 'Forgot password?' => 'Nie pamiętasz hasła?', - 'Enable "Forget Password"' => 'Włącz "Nie pamiętasz hasła?"', - 'Password Reset' => 'Resetuj hasło', - 'New password' => 'Nowe hasło', - 'Change Password' => 'Zmień hasło', - 'To reset your password click on this link:' => 'Kliknij w poniższy link, aby zresetować hasło:', - 'Last Password Reset' => 'Ostatnie odzyskiwanie hasła', - 'The password has never been reinitialized.' => 'Hasło nigdy nie było odzyskiwane.', - 'Creation' => 'Utworzenie', - 'Expiration' => 'Wygaśnięcie', - 'Password reset history' => 'Historia resetowania hasła', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Wszystkie zadania z kolumny "%s" i toru "%s" zostały zamknięte.', - 'Do you really want to close all tasks of this column?' => 'Na pewno chcesz zamknąć wszystkie zadania z tej kolumny?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d zadania z kolumny "%s" i toru "%s" zostaną zamknięte.', - 'Close all tasks of this column' => 'Zamknij wszystkie zadania w tej kolumnie', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Wtyczki obsługujące dodatkowe powiadomienia nie zostały zainstalowane. Dalej jednak możesz korzystać z standardowych powiadomień (sprawdź w ustawieniach Twojego profilu).', - 'My dashboard' => 'Mój dashboard', - 'My profile' => 'Mój profil', - 'Project owner: ' => 'Właściciel 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', - 'Task priority' => 'Priorytety zadań', - 'General' => 'Ogólne', - 'Dates' => 'Czas życia projektu', - 'Default priority' => 'Domyślny priorytet', - 'Lowest priority' => 'Najniższy priorytet', - 'Highest priority' => 'Najwyższy priorytet', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Jeżeli dla najniższego i najwyższego priorytetu ustawisz 0, to priorytety dla tablicy zostaną wyłączone.', - 'Close a task when there is no activity' => 'Zamknij zadanie gdy nie jest aktywne', - 'Duration in days' => 'Czas trwania w dniach', - 'Send email when there is no activity on a task' => 'Wyślij email gdy zadanie nie jest aktywne', - 'Unable to fetch link information.' => 'Nie można pobrać informacji o połączeniach.', - // 'Daily background job for tasks' => '', - 'Auto' => 'Automatyczny', - 'Related' => 'Powiązanie', - 'Attachment' => 'Załącznik', - 'Title not found' => 'Nie odnaleziono tytułu', - 'Web Link' => 'Link URL', - 'External links' => 'Linki zewnętrzne', - 'Add external link' => 'Dodaj link zewnętrzny', - 'Type' => 'Typ', - 'Dependency' => 'Zależność', - 'Add internal link' => 'Dodaj link do innego zadania', - 'Add a new external link' => 'Dodaj nowy link zewnętrzny', - 'Edit external link' => 'Edytuj link zewnętrzny', - 'External link' => 'Link zewnętrzny', - 'Copy and paste your link here...' => 'Skopiuj i wklej link tutaj ...', - // 'URL' => '', - 'Internal links' => 'Linki do innych zadań', - 'Assign to me' => 'Przypisz do mnie', - 'Me' => 'JA', - 'Do not duplicate anything' => 'Nie kopiuj żadnego projektu', - 'Projects management' => 'Zarządzanie projektami', - 'Users management' => 'Zarządzanie użytkownikami', - 'Groups management' => 'Zarządzanie grupami', - 'Create from another project' => 'Utwórz na podstawie innego projektu', - 'open' => 'otwarty', - 'closed' => 'zamknięty', - 'Priority:' => 'Priorytet:', - 'Reference:' => 'Odnośnik:', - 'Complexity:' => 'Złożoność:', - 'Swimlane:' => 'Proces:', - 'Column:' => 'Kolumna:', - 'Position:' => 'Pozycja:', - 'Creator:' => 'Utworzył:', - 'Time estimated:' => 'Szacowany czas:', - '%s hours' => '%s godzin', - 'Time spent:' => 'Spędzony czas:', - 'Created:' => 'Utworzone:', - 'Modified:' => 'Zmodyfikowane:', - 'Completed:' => 'Ukończone:', - '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: ', - 'New due date: ' => 'Nowy termin: ', - 'Start date changed: ' => 'Data rozpoczęcia została zmieniona: ', - 'Disable private projects' => 'Wyłącz prywatne projekty', - 'Do you really want to remove this custom filter: "%s"?' => 'Na pewno usunąć niestandardowy filtr: "%s"?', - 'Remove a custom filter' => 'Usuń niestandardowy filtr', - 'User activated successfully.' => 'Użytkownik został aktywowany.', - 'Unable to enable this user.' => 'Nie można włączyć użytkownika.', - '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', - 'Two Factor' => 'Dwustopniowe', - 'Disable user' => 'Wyłącz użytkownika', - 'Do you really want to disable this user: "%s"?' => 'Na pewno wyłączyć użytkownika: "%s"?', - 'Enable user' => 'Włącz użytkownika', - 'Do you really want to enable this user: "%s"?' => 'Na pewno włączyć użytkownika: "%s"?', - 'Download' => 'Pobierz', - 'Uploaded: %s' => 'Data załączenia: %s', - 'Size: %s' => 'Rozmiar: %s', - 'Uploaded by %s' => 'Załadowany przez %s', - 'Filename' => 'Nazwa pliku', - 'Size' => 'Rozmiar', - 'Column created successfully.' => 'Utworzono kolumnę.', - 'Another column with the same name exists in the project' => 'Inna kolumna o tej samej nazwie już istnieje w projekcie', - 'Default filters' => 'Domyślne filtry', - 'Your board doesn\'t have any columns!' => 'Twoja tablica nie ma żadnej kolumny!', - 'Change column position' => 'Zmień pozycję kolumny', - 'Switch to the project overview' => 'Przełącz do podsumowania projektu', - 'User filters' => 'Filtry użytkownika', - 'Category filters' => 'Filtry kategorii', - 'Upload a file' => 'Prześlij plik', - 'View file' => 'Wyświetl plik', - 'Last activity' => 'Ostatnia aktywność', - 'Change subtask position' => 'Zmień pozycję pod-zadania', - 'This value must be greater than %d' => 'Wartość musi być większa niż %d', - 'Another swimlane with the same name exists in the project' => 'Inny tor o tej samej nazwie już istnieje w projekcie', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Przykład: http://example.kanboard.net/ (użyty do wygenerowania bezwzględnych adresów URL)', - 'Actions duplicated successfully.' => 'Pomyślnie zduplikowano akcje.', - 'Unable to duplicate actions.' => 'Nie można zduplikować akcji.', - 'Add a new action' => 'Dodaj nową akcję', - 'Import from another project' => 'Importuj z innego projektu', - 'There is no action at the moment.' => 'W chwili obecnej nie dodano żadnych akcji.', - 'Import actions from another project' => 'Importuj akcje z innego projektu', - 'There is no available project.' => 'Brak dostępnego projektu.', - 'Local File' => 'Plik lokalny', - 'Configuration' => 'Konfiguracja', - 'PHP version:' => 'Wersja PHP:', - // 'PHP SAPI:' => '', - 'OS version:' => 'Wersja OS:', - 'Database version:' => 'Wersja bazy danych:', - 'Browser:' => 'Przeglądarka', - 'Task view' => 'Widok zadań', - 'Edit task' => 'Edytuj zadanie', - 'Edit description' => 'Edytuj opis', - 'New internal link' => 'Nowy wewnętrzny link', - 'Display list of keyboard shortcuts' => 'Wyświetl skróty klawiszowe', - // 'Menu' => '', - 'Set start date' => 'Ustaw datę rozpoczęcia', - // 'Avatar' => '', - 'Upload my avatar image' => 'Prześlij avatar', - 'Remove my image' => 'Usuń', - 'The OAuth2 state parameter is invalid' => 'Parametr stanu OAuth2 jest niepoprawny', - 'User not found.' => 'Nie znaleziono użytkownika', - 'Search in activity stream' => 'Szukaj w strumieniu aktywności', - 'My activities' => 'Moje aktywności', - 'Activity until yesterday' => 'Aktywności do wczoraj', - 'Activity until today' => 'Aktywności do dzisiaj', - 'Search by creator: ' => 'Wyszukaj według twórcy: ', - 'Search by creation date: ' => 'Wyszukaj według daty utworzenia: ', - 'Search by task status: ' => 'Wyszukaj według statusu zadania: ', - 'Search by task title: ' => 'Wyszukaj po tytule zadania: ', - 'Activity stream search' => 'Wyszukaj w strumieniu aktywności', - 'Projects where "%s" is manager' => 'Projekty gdzie "%s" jest menedżerem', - 'Projects where "%s" is member' => 'Projekty gdzie "%s" jest uczestnikiem', - 'Open tasks assigned to "%s"' => 'Otwarte zadania przypisane do "%s"', - 'Closed tasks assigned to "%s"' => 'Zamknięte zadania przypisane do "%s"', - // 'Assign automatically a color based on a priority' => '', - 'Overdue tasks for the project(s) "%s"' => 'Zaległe zadania dla projektu/projektów "%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' => '', -); diff --git a/sources/app/Locale/pt_BR/translations.php b/sources/app/Locale/pt_BR/translations.php deleted file mode 100644 index 343915b..0000000 --- a/sources/app/Locale/pt_BR/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => ' ', - 'None' => 'Nenhum', - 'edit' => 'editar', - 'Edit' => 'Editar', - 'remove' => 'remover', - 'Remove' => 'Remover', - 'Yes' => 'Sim', - 'No' => 'Não', - 'cancel' => 'cancelar', - 'or' => 'ou', - 'Yellow' => 'Amarelo', - 'Blue' => 'Azul', - 'Green' => 'Verde', - 'Purple' => 'Roxo', - 'Red' => 'Vermelho', - 'Orange' => 'Laranja', - 'Grey' => 'Cinza', - 'Brown' => 'Marrom', - 'Deep Orange' => 'Laranja escuro', - 'Dark Grey' => 'Cinza escuro', - 'Pink' => 'Roza', - 'Teal' => 'Turquesa', - 'Cyan' => 'Azul intenso', - 'Lime' => 'Verde limão', - 'Light Green' => 'Verde claro', - 'Amber' => 'Âmbar', - 'Save' => 'Salvar', - 'Login' => 'Login', - 'Official website:' => 'Site oficial:', - 'Unassigned' => 'Não Atribuída', - 'View this task' => 'Ver esta tarefa', - 'Remove user' => 'Remover usuário', - 'Do you really want to remove this user: "%s"?' => 'Você realmente deseja remover este usuário: "%s"?', - 'All users' => 'Todos os usuários', - 'Username' => 'Nome de usuário', - 'Password' => 'Senha', - 'Administrator' => 'Administrador', - 'Sign in' => 'Entrar', - 'Users' => 'Usuários', - 'No user' => 'Sem usuário', - 'Forbidden' => 'Proibido', - 'Access Forbidden' => 'Acesso negado', - 'Edit user' => 'Editar usuário', - 'Logout' => 'Sair', - 'Bad username or password' => 'Usuário ou senha inválidos', - 'Edit project' => 'Editar projeto', - 'Name' => 'Nome', - 'Projects' => 'Projetos', - 'No project' => 'Nenhum projeto', - 'Project' => 'Projeto', - 'Status' => 'Status', - 'Tasks' => 'Tarefas', - 'Board' => 'Board', - 'Actions' => 'Ações', - 'Inactive' => 'Inativo', - 'Active' => 'Ativo', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Você realmente deseja remover este projeto: "%s"?', - 'Remove project' => 'Remover projeto', - 'Edit the board for "%s"' => 'Editar o board para "%s"', - 'All projects' => 'Todos os projetos', - 'Add a new column' => 'Adicionar uma nova coluna', - '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!', - 'Settings' => 'Configurações', - 'Application settings' => 'Configurações da aplicação', - 'Language' => 'Idioma', - 'Webhook token:' => 'Token de webhooks:', - 'API token:' => 'API Token:', - 'Database size:' => 'Tamanho do banco de dados:', - 'Download the database' => 'Download do banco de dados', - 'Optimize the database' => 'Otimizar o banco de dados', - '(VACUUM command)' => '(Comando VACUUM)', - '(Gzip compressed Sqlite file)' => '(Arquivo Sqlite comprimido com Gzip)', - 'Close a task' => 'Finalizar uma tarefa', - 'Edit a task' => 'Editar uma tarefa', - 'Column' => 'Coluna', - 'Color' => 'Cor', - 'Assignee' => 'Designação', - 'Create another task' => 'Criar outra tarefa', - 'New task' => 'Nova tarefa', - 'Open a task' => 'Abrir uma tarefa', - 'Do you really want to open this task: "%s"?' => 'Você realmente deseja abrir esta tarefa: "%s"?', - 'Back to the board' => 'Voltar ao board', - 'There is nobody assigned' => 'Não há ninguém designado', - 'Column on the board:' => 'Coluna no board:', - 'Close this task' => 'Finalizar esta tarefa', - 'Open this task' => 'Abrir esta tarefa', - 'There is no description.' => 'Não há descrição.', - 'Add a new task' => 'Adicionar uma nova tarefa', - 'The username is required' => 'O nome de usuário é obrigatório', - 'The maximum length is %d characters' => 'O tamanho máximo é %d caracteres', - 'The minimum length is %d characters' => 'O tamanho mínimo é %d caracteres', - 'The password is required' => 'A senha é obrigatória', - 'This value must be an integer' => 'O valor deve ser um número inteiro', - 'The username must be unique' => 'O nome de usuário deve ser único', - 'The user id is required' => 'O ID de usuário é obrigatório', - 'Passwords don\'t match' => 'As senhas não coincidem', - 'The confirmation is required' => 'A confirmação é obrigatória', - 'The project is required' => 'O projeto é obrigatório', - 'The id is required' => 'O ID é obrigatório', - 'The project id is required' => 'O ID do projeto é obrigatório', - 'The project name is required' => 'O nome do projeto é obrigatório', - 'The title is required' => 'O título é obrigatório', - 'Settings saved successfully.' => 'Configurações salvas com sucesso.', - 'Unable to save your settings.' => 'Não é possível salvar suas configurações.', - 'Database optimization done.' => 'Otimização do banco de dados finalizada.', - 'Your project have been created successfully.' => 'Seu projeto foi criado com sucesso.', - 'Unable to create your project.' => 'Não é possível criar o seu projeto.', - 'Project updated successfully.' => 'Projeto atualizado com sucesso.', - 'Unable to update this project.' => 'Não é possível atualizar este projeto.', - 'Unable to remove this project.' => 'Não é possível remover este projeto.', - 'Project removed successfully.' => 'Projeto removido com sucesso.', - 'Project activated successfully.' => 'Projeto ativado com sucesso.', - 'Unable to activate this project.' => 'Não é possível ativar este projeto.', - 'Project disabled successfully.' => 'Projeto desativado com sucesso.', - 'Unable to disable this project.' => 'Não é possível desativar este projeto.', - 'Unable to open this task.' => 'Não é possível abrir esta tarefa.', - 'Task opened successfully.' => 'Tarefa aberta com sucesso.', - 'Unable to close this task.' => 'Não é possível finalizar esta tarefa.', - 'Task closed successfully.' => 'Tarefa finalizada com sucesso.', - 'Unable to update your task.' => 'Não é possível atualizar a sua tarefa.', - 'Task updated successfully.' => 'Tarefa atualizada com sucesso.', - 'Unable to create your task.' => 'Não é possível criar a sua tarefa.', - 'Task created successfully.' => 'Tarefa criada com sucesso.', - 'User created successfully.' => 'Usuário criado com sucesso.', - 'Unable to create your user.' => 'Não é possível criar o seu usuário.', - 'User updated successfully.' => 'Usuário atualizado com sucesso.', - 'Unable to update your user.' => 'Não é possível atualizar o seu usuário.', - 'User removed successfully.' => 'Usuário removido com sucesso.', - 'Unable to remove this user.' => 'Não é possível remover este usuário.', - 'Board updated successfully.' => 'Board atualizado com sucesso.', - 'Ready' => 'Pronto', - 'Backlog' => 'Backlog', - 'Work in progress' => 'Em andamento', - 'Done' => 'Finalizado', - 'Application version:' => 'Versão da aplicação:', - 'Id' => 'Id', - '%d closed tasks' => '%d tarefas finalizadas', - 'No task for this project' => 'Não há tarefa para este projeto', - 'Public link' => 'Link público', - 'Timezone' => 'Fuso horário', - 'Sorry, I didn\'t find this information in my database!' => 'Desculpe, não encontrei esta informação no meu banco de dados!', - 'Page not found' => 'Página não encontrada', - 'Complexity' => 'Complexidade', - 'Task limit' => 'Limite de tarefas', - '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 de vencimento', - 'Invalid date' => 'Data inválida', - 'Automatic actions' => 'Ações automáticas', - 'Your automatic action have been created successfully.' => 'Sua ação automética foi criada com sucesso.', - 'Unable to create your automatic action.' => 'Não é possível criar sua ação automática.', - 'Remove an action' => 'Remover uma ação', - 'Unable to remove this action.' => 'Não é possível remover esta ação.', - 'Action removed successfully.' => 'Ação removida com sucesso.', - 'Automatic actions for the project "%s"' => 'Ações automáticas para o projeto "%s"', - 'Add an action' => 'Adicionar Ação', - 'Event name' => 'Nome do evento', - 'Action name' => 'Nome da ação', - 'Action parameters' => 'Parâmetros da ação', - 'Action' => 'Ação', - 'Event' => 'Evento', - 'When the selected event occurs execute the corresponding action.' => 'Quando o evento selecionado ocorrer execute a ação correspondente.', - 'Next step' => 'Próximo passo', - 'Define action parameters' => 'Definir parêmetros da ação', - 'Do you really want to remove this action: "%s"?' => 'Você realmente deseja remover esta ação: "%s"?', - 'Remove an automatic action' => 'Remover uma ação automática', - 'Assign the task to a specific user' => 'Designar a tarefa para um usuário específico', - 'Assign the task to the person who does the action' => 'Designar a tarefa para a pessoa que executa a ação', - 'Duplicate the task to another project' => 'Duplicar a tarefa para outro projeto', - 'Move a task to another column' => 'Mover a tarefa para outra coluna', - 'Task modification' => 'Modificação de tarefa', - 'Task creation' => 'Criação de tarefa', - 'Closing a task' => 'Finalizando uma tarefa', - 'Assign a color to a specific user' => 'Designar uma cor para um usuário específico', - 'Column title' => 'Título da coluna', - 'Position' => 'Posição', - 'Duplicate to another project' => 'Duplicar para outro projeto', - 'Duplicate' => 'Duplicar', - 'link' => 'link', - 'Comment updated successfully.' => 'Comentário atualizado com sucesso.', - 'Unable to update your comment.' => 'Não é possível atualizar o seu comentário.', - 'Remove a comment' => 'Remover um comentário', - 'Comment removed successfully.' => 'Comentário removido com sucesso.', - 'Unable to remove this comment.' => 'Não é possível remover este comentário.', - 'Do you really want to remove this comment?' => 'Você realmente deseja remover este comentário?', - 'Current password for the user "%s"' => 'Senha atual para o usuário "%s"', - 'The current password is required' => 'A senha atual é obrigatória', - 'Wrong password' => 'Senha incorreta', - 'Unknown' => 'Desconhecido', - 'Last logins' => 'Últimos logins', - 'Login date' => 'Data de login', - 'Authentication method' => 'Método de autenticação', - 'IP address' => 'Endereço IP', - 'User agent' => 'User Agent', - 'Persistent connections' => 'Conexões persistentes', - 'No session.' => 'Nenhuma sessão.', - 'Expiration date' => 'Data de expiração', - 'Remember Me' => 'Lembre-se de mim', - 'Creation date' => 'Data de criação', - 'Everybody' => 'Todos', - 'Open' => 'Abrir', - 'Closed' => 'Finalizado', - 'Search' => 'Pesquisar', - 'Nothing found.' => 'Nada foi 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', - 'Email address invalid' => 'Endereço de e-mail inválido', - 'Your external account is not linked anymore to your profile.' => 'Sua conta externa não está mais ligada ao seu perfil.', - 'Unable to unlink your external account.' => 'Impossível de remover a sua conta externa.', - 'External authentication failed' => 'Autenticação externa falhou', - 'Your external account is linked to your profile successfully.' => 'Sua conta externa está agora ligada ao seu perfil.', - 'Email' => 'E-mail', - 'Task removed successfully.' => 'Tarefa removida com sucesso.', - 'Unable to remove this task.' => 'Não foi possível remover esta tarefa.', - 'Remove a task' => 'Remover uma tarefa', - 'Do you really want to remove this task: "%s"?' => 'Você realmente deseja remover esta tarefa: "%s"?', - 'Assign automatically a color based on a category' => 'Atribuir automaticamente uma cor com base em uma categoria', - 'Assign automatically a category based on a color' => 'Atribuir automaticamente uma categoria com base em uma cor', - 'Task creation or modification' => 'Criação ou modificação de tarefa', - 'Category' => 'Categoria', - 'Category:' => 'Categoria:', - 'Categories' => 'Categorias', - 'Your category have been created successfully.' => 'Sua categoria foi criada com sucesso.', - 'Unable to create your category.' => 'Não foi possível criar a sua categoria.', - 'Your category have been updated successfully.' => 'A sua categoria foi atualizada com sucesso.', - 'Unable to update your category.' => 'Não foi possível atualizar a sua categoria.', - 'Remove a category' => 'Remover uma categoria', - 'Category removed successfully.' => 'Categoria removida com sucesso.', - 'Unable to remove this category.' => 'Não foi possível remover esta categoria.', - 'Category modification for the project "%s"' => 'Modificação de categoria para o projeto "%s"', - 'Category Name' => 'Nome da categoria', - 'Add a new category' => 'Adicionar uma nova categoria', - 'Do you really want to remove this category: "%s"?' => 'Você realmente deseja remover esta categoria: "%s"?', - 'All categories' => 'Todas as categorias', - 'No category' => 'Nenhum categoria', - 'The name is required' => 'O nome é obrigatório', - 'Remove a file' => 'Remover um arquivo', - 'Unable to remove this file.' => 'Não foi possível remover este arquivo.', - 'File removed successfully.' => 'Arquivo removido com sucesso.', - 'Attach a document' => 'Anexar um documento', - 'Do you really want to remove this file: "%s"?' => 'Você realmente deseja remover este arquivo: "%s"?', - 'Attachments' => 'Anexos', - 'Edit the task' => 'Editar a tarefa', - 'Add a comment' => 'Adicionar um comentário', - 'Edit a comment' => 'Editar um comentário', - 'Summary' => 'Resumo', - 'Time tracking' => 'Rastreamento de tempo', - 'Estimate:' => 'Estimado:', - 'Spent:' => 'Gasto:', - 'Do you really want to remove this sub-task?' => 'Você realmente deseja remover esta subtarefa?', - 'Remaining:' => 'Restante:', - 'hours' => 'horas', - 'spent' => 'gasto', - 'estimated' => 'estimado', - 'Sub-Tasks' => 'Subtarefas', - 'Add a sub-task' => 'Adicionar uma subtarefa', - 'Original estimate' => 'Estimativa original', - 'Create another sub-task' => 'Criar uma outra subtarefa', - 'Time spent' => 'Tempo gasto', - 'Edit a sub-task' => 'Editar uma subtarefa', - 'Remove a sub-task' => 'Remover uma subtarefa', - 'The time must be a numeric value' => 'O tempo deve ser um valor numérico', - 'Todo' => 'À fazer', - 'In progress' => 'Em andamento', - 'Sub-task removed successfully.' => 'Subtarefa removida com sucesso.', - 'Unable to remove this sub-task.' => 'Não foi possível remover esta subtarefa.', - 'Sub-task updated successfully.' => 'Subtarefa atualizada com sucesso.', - 'Unable to update your sub-task.' => 'Não foi possível atualizar a sua subtarefa.', - 'Unable to create your sub-task.' => 'Não é possível criar a sua subtarefa.', - 'Sub-task added successfully.' => 'Subtarefa adicionada com sucesso.', - 'Maximum size: ' => 'Tamanho máximo: ', - 'Unable to upload the file.' => 'Não foi possível carregar o arquivo.', - 'Display another project' => 'Exibir outro projeto', - 'Created by %s' => 'Criado por %s', - 'Tasks Export' => 'Exportar Tarefas', - 'Tasks exportation for "%s"' => 'As tarefas foram exportadas para "%s"', - 'Start Date' => 'Data inicial', - 'End Date' => 'Data final', - 'Execute' => 'Executar', - 'Task Id' => 'ID da Tarefa', - 'Creator' => 'Criado por', - 'Modification date' => 'Data da modificação', - 'Completion date' => 'Data da finalização', - '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' => 'Habilitar notificações por email', - '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.', - 'Sub-task updated' => 'Subtarefa atualizada', - 'Title:' => 'Título:', - 'Status:' => 'Status:', - 'Assignee:' => 'Designado:', - 'Time tracking:' => 'Controle de tempo:', - 'New sub-task' => 'Nova subtarefa', - 'New attachment added "%s"' => 'Novo anexo adicionado "%s"', - 'New comment posted by %s' => 'Novo comentário postado por %s', - 'New attachment' => 'Novo anexo', - 'New comment' => 'Novo comentário', - 'Comment updated' => 'Comentário atualizado', - 'New subtask' => 'Nova subtarefa', - 'Subtask updated' => 'Subtarefa alterada', - 'Task updated' => 'Tarefa alterada', - 'Task closed' => 'Tarefa finalizada', - 'Task opened' => 'Tarefa aberta', - 'I want to receive notifications only for those projects:' => 'Quero receber notificações apenas destes projetos:', - 'view the task on Kanboard' => 'ver a tarefa no Kanboard', - 'Public access' => 'Acesso público', - 'Active tasks' => 'Tarefas ativas', - 'Disable public access' => 'Desabilitar o acesso público', - 'Enable public access' => 'Habilitar o acesso público', - 'Public access disabled' => 'Acesso público desabilitado', - 'Do you really want to disable this project: "%s"?' => 'Você realmente deseja desativar este projeto: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Você realmente deseja ativar este projeto: "%s"?', - 'Project activation' => 'Ativação do projeto', - 'Move the task to another project' => 'Mover a tarefa para outro projeto', - 'Move to another project' => 'Mover para outro projeto', - 'Do you really want to duplicate this task?' => 'Você realmente deseja duplicar esta tarefa?', - 'Duplicate a task' => 'Duplicar uma tarefa', - 'External accounts' => 'Contas externas', - 'Account type' => 'Tipo de conta', - 'Local' => 'Local', - 'Remote' => 'Remoto', - 'Enabled' => 'Habilitado', - 'Disabled' => 'Desabilitado', - 'Username:' => 'Usuário:', - 'Name:' => 'Nome:', - 'Email:' => 'E-mail:', - 'Notifications:' => 'Notificações:', - 'Notifications' => 'Notificações', - 'Account type:' => 'Tipo de conta:', - 'Edit profile' => 'Editar perfil', - 'Change password' => 'Alterar senha', - 'Password modification' => 'Alteração de senha', - 'External authentications' => 'Autenticação externa', - 'Never connected.' => 'Nunca conectado.', - 'No external authentication enabled.' => 'Nenhuma autenticação externa habilitada.', - 'Password modified successfully.' => 'Senha alterada com sucesso.', - 'Unable to change the password.' => 'Não foi possível alterar a senha.', - 'Change category' => 'Mudar categoria', - '%s updated the task %s' => '%s atualizou a tarefa %s', - '%s opened the task %s' => '%s abriu a tarefa %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s moveu a tarefa %s para a posição #%d na coluna "%s"', - '%s moved the task %s to the column "%s"' => '%s moveu a tarefa %s para a coluna "%s"', - '%s created the task %s' => '%s criou a tarefa %s', - '%s closed the task %s' => '%s finalizou a tarefa %s', - '%s created a subtask for the task %s' => '%s criou uma subtarefa para a tarefa %s', - '%s updated a subtask for the task %s' => '%s atualizou uma subtarefa da tarefa %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Designado para %s com tempo estimado de %s/%sh', - 'Not assigned, estimate of %sh' => 'Não designado, estimado em %sh', - '%s updated a comment on the task %s' => '%s atualizou o comentário na tarefa %s', - '%s commented the task %s' => '%s comentou a tarefa %s', - '%s\'s activity' => 'Atividades de%s', - 'RSS feed' => 'Feed RSS', - '%s updated a comment on the task #%d' => '%s atualizou um comentário sobre a tarefa #%d', - '%s commented on the task #%d' => '%s comentou sobre a tarefa #%d', - '%s updated a subtask for the task #%d' => '%s atualizou uma subtarefa para a tarefa #%d', - '%s created a subtask for the task #%d' => '%s criou uma subtarefa para a tarefa #%d', - '%s updated the task #%d' => '%s atualizou a tarefa #%d', - '%s created the task #%d' => '%s criou a tarefa #%d', - '%s closed the task #%d' => '%s finalizou a tarefa #%d', - '%s open the task #%d' => '%s abriu a tarefa #%d', - '%s moved the task #%d to the column "%s"' => '%s moveu a tarefa #%d para a coluna "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s moveu a tarefa #%d para a posição %d na coluna "%s"', - 'Activity' => 'Atividade', - 'Default values are "%s"' => 'Os valores padrão são "%s"', - 'Default columns for new projects (Comma-separated)' => 'Colunas padrão para novos projetos (Separado por vírgula)', - 'Task assignee change' => 'Mudar designação da tarefa', - '%s change the assignee of the task #%d to %s' => '%s mudou a designação da tarefa #%d para %s', - '%s changed the assignee of the task %s to %s' => '%s mudou a designação da tarefa %s para %s', - 'New password for the user "%s"' => 'Nova senha para o usuário "%s"', - 'Choose an event' => 'Escolher um evento', - 'Create a task from an external provider' => 'Criar uma tarefa por meio de um serviço externo', - 'Change the assignee based on an external username' => 'Alterar designação com base em um usuário externo', - 'Change the category based on an external label' => 'Alterar categoria com base em um rótulo externo', - 'Reference' => 'Referência', - 'Label' => 'Rótulo', - 'Database' => 'Banco de dados', - 'About' => 'Sobre', - 'Database driver:' => 'Driver do banco de dados:', - 'Board settings' => 'Configurações do board', - 'Webhook settings' => 'Configurações do Webhook', - 'Reset token' => 'Resetar token', - 'API endpoint:' => 'API endpoint:', - 'Refresh interval for private board' => 'Intervalo de atualização para um board privado', - 'Refresh interval for public board' => 'Intervalo de atualização para um board público', - 'Task highlight period' => 'Período de Tarefa em destaque', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Período (em segundos) para considerar que uma tarefa foi modificada recentemente (0 para desativar, 2 dias por padrão)', - 'Frequency in second (60 seconds by default)' => 'Frequência em segundos (60 segundos por padrão)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frequência em segundos (0 para desativar este recurso, 10 segundos por padrão)', - 'Application URL' => 'URL da Aplicação', - 'Token regenerated.' => 'Novo token gerado.', - 'Date format' => 'Formato de data', - 'ISO format is always accepted, example: "%s" and "%s"' => 'O formato ISO é sempre aceito, exemplo: "%s" e "%s"', - 'New private project' => 'Novo projeto privado', - 'This project is private' => 'Este projeto é privado', - 'Add' => 'Adicionar', - 'Start date' => 'Data de início', - 'Time estimated' => 'Tempo estimado', - 'There is nothing assigned to you.' => 'Não há nada designado à você.', - 'My tasks' => 'Minhas tarefas', - 'Activity stream' => 'Atividades Recentes', - 'Dashboard' => 'Painel de Controle', - 'Confirmation' => 'Confirmação', - 'Allow everybody to access to this project' => 'Permitir que todos acessem este projeto', - 'Everybody have access to this project.' => 'Todos possuem acesso a este projeto.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Criar um comentário por meio de um serviço externo', - 'Project management' => 'Gerenciamento de projetos', - 'My projects' => 'Meus projetos', - 'Columns' => 'Colunas', - 'Task' => 'Tarefas', - 'Your are not member of any project.' => 'Você não é membro de nenhum projeto.', - 'Percentage' => 'Porcentagem', - 'Number of tasks' => 'Número de tarefas', - 'Task distribution' => 'Distribuição de tarefas', - 'Reportings' => 'Relatórios', - 'Task repartition for "%s"' => 'Redistribuição da tarefa para "%s"', - 'Analytics' => 'Estatísticas', - 'Subtask' => 'Subtarefa', - 'My subtasks' => 'Minhas subtarefas', - 'User repartition' => 'Redistribuição de usuário', - 'User repartition for "%s"' => 'Redistribuição de usuário para "%s"', - 'Clone this project' => 'Clonar este projeto', - 'Column removed successfully.' => 'Coluna removida com sucesso.', - 'Not enough data to show the graph.' => 'Não há dados suficientes para mostrar o gráfico.', - 'Previous' => 'Anterior', - 'The id must be an integer' => 'O ID deve ser um número inteiro', - 'The project id must be an integer' => 'O ID do projeto deve ser um inteiro', - 'The status must be an integer' => 'O status deve ser um número inteiro', - 'The subtask id is required' => 'O ID da subtarefa é obrigatório', - 'The subtask id must be an integer' => 'O ID da subtarefa deve ser um número inteiro', - 'The task id is required' => 'O ID da tarefa é obrigatório', - 'The task id must be an integer' => 'O ID da tarefa deve ser um número inteiro', - 'The user id must be an integer' => 'O ID do usuário deve ser um número inteiro', - 'This value is required' => 'Este valor é obrigatório', - 'This value must be numeric' => 'Este valor deve ser numérico', - 'Unable to create this task.' => 'Não foi possível criar esta tarefa.', - 'Cumulative flow diagram' => 'Fluxograma cumulativo', - 'Cumulative flow diagram for "%s"' => 'Fluxograma cumulativo para "%s"', - 'Daily project summary' => 'Resumo diário do projeto', - 'Daily project summary export' => 'Exportação diária do resumo do projeto', - 'Daily project summary export for "%s"' => 'Exportação diária do resumo do projeto para "%s"', - 'Exports' => 'Exportar', - 'This export contains the number of tasks per column grouped per day.' => 'Esta exportação contém o número de tarefas por coluna agrupada por dia.', - 'Active swimlanes' => 'Ativar swimlanes', - 'Add a new swimlane' => 'Adicionar swimlane', - 'Change default swimlane' => 'Alterar swimlane padrão', - 'Default swimlane' => 'Swimlane padrão', - 'Do you really want to remove this swimlane: "%s"?' => 'Você realmente deseja remover esta swimlane: "%s"?', - 'Inactive swimlanes' => 'Desativar swimlanes', - 'Remove a swimlane' => 'Remover uma swimlane', - 'Show default swimlane' => 'Exibir swimlane padrão', - 'Swimlane modification for the project "%s"' => 'Modificação de swimlane para o projeto "%s"', - 'Swimlane removed successfully.' => 'Swimlane removida com sucesso.', - 'Swimlanes' => 'Swimlanes', - 'Swimlane updated successfully.' => 'Swimlane atualizada com sucesso.', - 'The default swimlane have been updated successfully.' => 'A swimlane padrão foi atualizada com sucesso.', - 'Unable to remove this swimlane.' => 'Não foi possível remover esta swimlane.', - 'Unable to update this swimlane.' => 'Não foi possível atualizar esta swimlane.', - 'Your swimlane have been created successfully.' => 'Sua swimlane foi criada com sucesso.', - 'Example: "Bug, Feature Request, Improvement"' => 'Exemplo: "Bug, Solicitação de Recurso, Melhoria"', - 'Default categories for new projects (Comma-separated)' => 'Categorias padrões para novos projetos (separadas por vírgula)', - 'Integrations' => 'Integrações', - 'Integration with third-party services' => 'Integração com serviços de terceiros', - 'Subtask Id' => 'ID da subtarefa', - 'Subtasks' => 'Subtarefas', - 'Subtasks Export' => 'Exportar subtarefas', - 'Subtasks exportation for "%s"' => 'Subtarefas exportadas para "%s"', - 'Task Title' => 'Título da Tarefa', - 'Untitled' => 'Sem título', - 'Application default' => 'Padrão da aplicação', - 'Language:' => 'Idioma', - 'Timezone:' => 'Fuso horário', - 'All columns' => 'Todas as colunas', - 'Calendar' => 'Calendário', - 'Next' => 'Próximo', - '#%d' => '#%d', - 'All swimlanes' => 'Todas as swimlanes', - 'All colors' => 'Todas as cores', - 'Moved to column %s' => 'Mover para a coluna %s', - 'User dashboard' => 'Painel de Controle do usuário', - 'Allow only one subtask in progress at the same time for a user' => 'Permitir apenas uma subtarefa em andamento ao mesmo tempo para um usuário', - 'Edit column "%s"' => 'Editar a coluna "%s"', - 'Select the new status of the subtask: "%s"' => 'Selecionar um novo status para a subtarefa: "%s"', - 'Subtask timesheet' => 'Gestão de tempo das subtarefas', - 'There is nothing to show.' => 'Não há nada para mostrar.', - 'Time Tracking' => 'Gestão de tempo', - 'You already have one subtask in progress' => 'Você já tem um subtarefa em andamento', - 'Which parts of the project do you want to duplicate?' => 'Quais partes do projeto você deseja duplicar?', - 'Disallow login form' => 'Proibir o formulário de login', - 'Start' => 'Início', - 'End' => 'Fim', - 'Task age in days' => 'Idade da tarefa em dias', - 'Days in this column' => 'Dias nesta coluna', - '%dd' => '%dd', - 'Add a new link' => 'Adicionar uma nova associação', - 'Do you really want to remove this link: "%s"?' => 'Você realmente deseja remover esta associação: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Você realmente deseja remover esta associação com a tarefa #%d?', - 'Field required' => 'Campo requerido', - 'Link added successfully.' => 'Associação criada com sucesso.', - 'Link updated successfully.' => 'Associação atualizada com sucesso.', - 'Link removed successfully.' => 'Associação removida com sucesso.', - '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', - 'Unable to create your link.' => 'Impossível de adicionar sua associação.', - 'Unable to update your link.' => 'Impossível de atualizar sua associação.', - 'Unable to remove this link.' => 'Impossível de remover sua associação.', - 'relates to' => 'é associada com', - 'blocks' => 'bloqueia', - 'is blocked by' => 'está bloqueada por', - 'duplicates' => 'duplica', - 'is duplicated by' => 'é duplicada por', - 'is a child of' => 'é filha de', - 'is a parent of' => 'é mãe de', - 'targets milestone' => 'visa um milestone', - 'is a milestone of' => 'é um milestone de', - 'fixes' => 'corrige', - 'is fixed by' => 'foi corrigida por', - 'This task' => 'Esta tarefa', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Expandir tarefas', - 'Collapse tasks' => 'Contrair tarefas', - 'Expand/collapse tasks' => 'Expandir/Contrair tarefas', - 'Close dialog box' => 'Fechar a caixa de diálogo', - 'Submit a form' => 'Envia o formulário', - 'Board view' => 'Página do painel', - 'Keyboard shortcuts' => 'Atalhos de teclado', - 'Open board switcher' => 'Abrir o comutador de painel', - 'Application' => 'Aplicação', - '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', - 'CAD - Canadian Dollar' => 'CAD - Dólar canadense', - 'CHF - Swiss Francs' => 'CHF - Francos Suíços', - 'Custom Stylesheet' => 'Folha de estilo personalizado', - 'download' => 'baixar', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Libra Esterlina', - 'INR - Indian Rupee' => 'INR - Rúpia indiana', - 'JPY - Japanese Yen' => 'JPY - Iene japonês', - 'NZD - New Zealand Dollar' => 'NZD - Dólar Neozelandês', - 'RSD - Serbian dinar' => 'RSD - Dinar sérvio', - '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', - 'Move the task to another column when assignee is cleared' => 'Mover a tarefa para uma outra coluna quando esta não está atribuída', - 'Source column' => 'Coluna de origem', - 'Transitions' => 'Transições', - 'Executer' => 'Executor(a)', - 'Time spent in the column' => 'Tempo gasto na coluna', - 'Task transitions' => 'Transições das tarefas', - 'Task transitions export' => 'Exportação das transições das tarefas', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Este relatório contém todos os movimentos de coluna para cada tarefa com a data, o usuário e o tempo gasto para cada transição.', - '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.', - 'Webhook URL' => 'URL do webhook', - '%s remove the assignee of the task %s' => '%s removeu a pessoa designada para a tarefa %s', - 'Enable Gravatar images' => 'Ativar imagens do Gravatar', - 'Information' => 'Informações', - 'Check two factor authentication code' => 'Verifique o código de autenticação em duas etapas', - 'The two factor authentication code is not valid.' => 'O código de autenticação em duas etapas não é válido.', - 'The two factor authentication code is valid.' => 'O código de autenticação em duas etapas é válido.', - 'Code' => 'Código', - 'Two factor authentication' => 'Autenticação em duas etapas', - 'This QR code contains the key URI: ' => 'Este Código QR contém a chave URI:', - 'Check my code' => 'Verifique o meu código', - 'Secret key: ' => 'Chave secreta:', - 'Test your device' => 'Teste o seu dispositivo', - 'Assign a color when the task is moved to a specific column' => 'Atribuir uma cor quando a tarefa é movida em uma coluna específica', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Gráfico de Burndown para "%s"', - 'Burndown chart' => 'Gráfico de Burndown', - 'This chart show the task complexity over the time (Work Remaining).' => 'Este gráfico mostra a complexidade da tarefa ao longo do tempo (Trabalho Restante).', - 'Screenshot taken %s' => 'Captura de tela tirada em %s', - 'Add a screenshot' => 'Adicionar uma captura de tela', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Tire uma captura de tela e pressione CTRL + V ou ⌘ + V para colar aqui.', - 'Screenshot uploaded successfully.' => 'Captura de tela enviada com sucesso.', - 'SEK - Swedish Krona' => 'SEK - Coroa sueca', - 'Identifier' => 'Identificador', - 'Disable two factor authentication' => 'Desativar autenticação em duas etapas', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Você realmente deseja desativar a autenticação em duas etapas para este usuário: "%s"?', - 'Edit link' => 'Editar um link', - 'Start to type task title...' => 'Digite o título do trabalho...', - 'A task cannot be linked to itself' => 'Uma tarefa não pode ser vinculada a si própria', - 'The exact same link already exists' => 'Um link idêntico já existe', - 'Recurrent task is scheduled to be generated' => 'A tarefa recorrente está programada para ser criada', - 'Score' => 'Complexidade', - 'The identifier must be unique' => 'O identificador deve ser único', - 'This linked task id doesn\'t exists' => 'O identificador da tarefa associada não existe', - 'This value must be alphanumeric' => 'Este valor deve ser alfanumérico', - 'Edit recurrence' => 'Modificar a recorrência', - 'Generate recurrent task' => 'Gerar uma tarefa recorrente', - 'Trigger to generate recurrent task' => 'Trigger para gerar tarefa recorrente', - 'Factor to calculate new due date' => 'Fator para o cálculo da nova data limite', - 'Timeframe to calculate new due date' => 'Escala de tempo para o cálculo da nova data limite', - 'Base date to calculate new due date' => 'Data a ser utilizada para calcular a nova data limite', - 'Action date' => 'Data da ação', - 'Base date to calculate new due date: ' => 'Data a ser utilizada para calcular a nova data limite: ', - 'This task has created this child task: ' => 'Esta tarefa criou a tarefa filha: ', - 'Day(s)' => 'Dia(s)', - 'Existing due date' => 'Data limite existente', - 'Factor to calculate new due date: ' => 'Fator para calcular a nova data limite: ', - 'Month(s)' => 'Mês(es)', - 'Recurrence' => 'Recorrência', - 'This task has been created by: ' => 'Esta tarefa foi criada por: ', - 'Recurrent task has been generated:' => 'A tarefa recorrente foi gerada:', - 'Timeframe to calculate new due date: ' => 'Escala de tempo para o cálculo da nova data limite: ', - 'Trigger to generate recurrent task: ' => 'Trigger para gerar tarefa recorrente: ', - 'When task is closed' => 'Quando a tarefa é fechada', - 'When task is moved from first column' => 'Quando a tarefa é movida fora da primeira coluna', - 'When task is moved to last column' => 'Quando a tarefa é movida para a última coluna', - 'Year(s)' => 'Ano(s)', - 'Calendar settings' => 'Configurações do calendário', - 'Project calendar view' => 'Vista em modo projeto do calendário', - 'Project settings' => 'Configurações dos projetos', - 'Show subtasks based on the time tracking' => 'Mostrar as subtarefas com base no controle de tempo', - 'Show tasks based on the creation date' => 'Mostrar as tarefas em função da data de criação', - 'Show tasks based on the start date' => 'Mostrar as tarefas em função da data de início', - 'Subtasks time tracking' => 'Monitoramento do tempo comparado as subtarefas', - 'User calendar view' => 'Vista em modo utilizador do calendário', - 'Automatically update the start date' => 'Atualizar automaticamente a data de início', - 'iCal feed' => 'Subscrição iCal', - 'Preferences' => 'Preferências', - 'Security' => 'Segurança', - 'Two factor authentication disabled' => 'Autenticação em duas etapas desativada', - 'Two factor authentication enabled' => 'Autenticação em duas etapas ativada', - 'Unable to update this user.' => 'Impossível de atualizar esse usuário.', - 'There is no user management for private projects.' => 'Não há gerenciamento de usuários para projetos privados.', - 'User that will receive the email' => 'O usuário que vai receber o e-mail', - 'Email subject' => 'Assunto do e-mail', - 'Date' => 'Data', - 'Add a comment log when moving the task between columns' => 'Adicionar um comentário de log quando uma tarefa é movida para uma outra coluna', - 'Move the task to another column when the category is changed' => 'Mover uma tarefa para outra coluna quando a categoria mudou', - 'Send a task by email to someone' => 'Enviar uma tarefa por e-mail a alguém', - 'Reopen a task' => 'Reabrir uma tarefa', - 'Column change' => 'Mudança de coluna', - 'Position change' => 'Mudança de posição', - 'Swimlane change' => 'Mudança de swimlane', - 'Assignee change' => 'Mudança de designação', - '[%s] Overdue tasks' => '[%s] Tarefas atrasadas', - 'Notification' => 'Notificação', - '%s moved the task #%d to the first swimlane' => '%s moveu a tarefa #%d para a primeira swimlane', - '%s moved the task #%d to the swimlane "%s"' => '%s moveu a tarefa #%d para a swimlane "%s"', - 'Swimlane' => 'Swimlane', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s moveu a tarefa %s para a primeira swimlane', - '%s moved the task %s to the swimlane "%s"' => '%s moveu a tarefa %s para a swimlane "%s"', - 'This report contains all subtasks information for the given date range.' => 'Este relatório contém informações de todas as subtarefas para o período selecionado.', - 'This report contains all tasks information for the given date range.' => 'Este relatório contém informações de todas as tarefas para o período selecionado.', - 'Project activities for %s' => 'Atividade do projeto "%s"', - 'view the board on Kanboard' => 'ver o painel no Kanboard', - 'The task have been moved to the first swimlane' => 'A tarefa foi movida para a primeira swimlane', - 'The task have been moved to another swimlane:' => 'A tarefa foi movida para outra swimlane:', - 'New title: %s' => 'Novo título: %s', - 'The task is not assigned anymore' => 'Agora a tarefa não está mais atribuída', - 'New assignee: %s' => 'Novo designado: %s', - 'There is no category now' => 'Agora não tem mais categoria', - 'New category: %s' => 'Nova categoria: %s', - 'New color: %s' => 'Nova cor: %s', - 'New complexity: %d' => 'Nova complexidade: %d', - 'The due date have been removed' => 'A data limite foi retirada', - 'There is no description anymore' => 'Agora não tem mais descrição', - 'Recurrence settings have been modified' => 'As configurações da recorrência foram modificadas', - 'Time spent changed: %sh' => 'O tempo despendido foi mudado: %sh', - 'Time estimated changed: %sh' => 'O tempo estimado foi mudado/ %sh', - 'The field "%s" have been updated' => 'O campo "%s" foi atualizada', - 'The description has been modified:' => 'A descrição foi modificada', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Você realmente deseja finalizar a tarefa "%s" e todas as suas subtarefas?', - 'I want to receive notifications for:' => 'Eu quero receber as notificações para:', - 'All tasks' => 'Todas as tarefas', - 'Only for tasks assigned to me' => 'Somente as tarefas atribuídas a mim', - 'Only for tasks created by me' => 'Apenas as tarefas que eu criei', - 'Only for tasks created by me and assigned to me' => 'Apenas as tarefas que eu criei e aquelas atribuídas a mim', - '%%Y-%%m-%%d' => '%%d/%%m/%%Y', - 'Total for all columns' => 'Total para todas as colunas', - 'You need at least 2 days of data to show the chart.' => 'Você precisa de pelo menos 2 dias de dados para visualizar o gráfico.', - '<15m' => '<15m', - '<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', - 'Reset filters' => 'Redefinir os filtros', - 'My tasks due tomorrow' => 'Minhas tarefas que expiram amanhã', - 'Tasks due today' => 'Tarefas que expiram hoje', - 'Tasks due tomorrow' => 'Tarefas que expiram amanhã', - 'Tasks due yesterday' => 'Tarefas que expiraram ontem', - 'Closed tasks' => 'Tarefas fechadas', - 'Open tasks' => 'Tarefas abertas', - 'Not assigned' => 'Não designada', - 'View advanced search syntax' => 'Ver a sintaxe para pesquisa avançada', - 'Overview' => 'Visão global', - 'Board/Calendar/List view' => 'Vista Painel/Calendário/Lista', - 'Switch to the board view' => 'Mudar para o modo Painel', - 'Switch to the calendar view' => 'Mudar par o modo Calendário', - 'Switch to the list view' => 'Mudar par o modo Lista', - 'Go to the search/filter box' => 'Ir para o campo de pesquisa', - 'There is no activity yet.' => 'Não há nenhuma atividade ainda.', - 'No tasks found.' => 'Nenhuma tarefa encontrada.', - 'Keyboard shortcut: "%s"' => 'Tecla de atalho: "%s"', - 'List' => 'Lista', - 'Filter' => 'Filtro', - 'Advanced search' => 'Pesquisa avançada', - 'Example of query: ' => 'Exemplo de consulta: ', - 'Search by project: ' => 'Pesquisar por projet: ', - 'Search by column: ' => 'Pesquisar por coluna: ', - 'Search by assignee: ' => 'Pesquisar por designado: ', - 'Search by color: ' => 'Pesquisar por cor: ', - 'Search by category: ' => 'Pesquisar por categoria: ', - 'Search by description: ' => 'Pesquisar por descrição: ', - 'Search by due date: ' => 'Pesquisar por data de expiração: ', - 'Lead and Cycle time for "%s"' => 'Lead and Cycle time para "%s"', - 'Average time spent into each column for "%s"' => 'Tempo médio gasto em cada coluna para "%s"', - 'Average time spent into each column' => 'Tempo médio gasto em cada coluna', - 'Average time spent' => 'Tempo médio gasto', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Este gráfico mostra o tempo médio gasto em cada coluna para as %d últimas tarefas.', - 'Average Lead and Cycle time' => 'Tempo médio do Lead and cycle time', - 'Average lead time: ' => 'Lead time medio: ', - 'Average cycle time: ' => 'Cycle time medio: ', - '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.' => 'Este gráfico mostra o tempo médio do Lead and cycle time das últimas %d tarefas.', - 'Average time into each column' => 'Tempo médio de cada coluna', - 'Lead and cycle time' => 'Lead and cycle time', - 'Lead time: ' => 'Lead time: ', - 'Cycle time: ' => 'Cycle time: ', - 'Time spent into each column' => 'Tempo gasto em cada coluna', - 'The lead time is the duration between the task creation and the completion.' => 'O Lead time é o tempo gasto entre a criação da tarefa e a sua conclusão.', - 'The cycle time is the duration between the start date and the completion.' => 'O Cycle time é o tempo gasto entre a data de início e a sua conclusão.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Se a tarefa não está fechada, a hora atual é usada no lugar da data de conclusão.', - 'Set automatically the start date' => 'Definir automaticamente a data de início', - 'Edit Authentication' => 'Modificar a autenticação', - '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.', - 'Trigger automatically subtask time tracking' => 'Ativar automaticamente o monitoramento do tempo para as subtarefas', - 'Include closed tasks in the cumulative flow diagram' => 'Incluir as tarefas fechadas no diagrama de fluxo acumulado', - 'Current swimlane: %s' => 'Swimlane atual: %s', - 'Current column: %s' => 'Coluna atual: %s', - 'Current category: %s' => 'Categoria atual: %s', - 'no category' => 'nenhuma categoria', - 'Current assignee: %s' => 'Designação atual: %s', - 'not assigned' => 'não designado', - 'Author:' => 'Autor:', - 'contributors' => 'contribuidores', - 'License:' => 'Licença:', - 'License' => 'Licença', - 'Enter the text below' => 'Entre o texto abaixo', - 'Gantt chart for %s' => 'Gráfico de Gantt para %s', - 'Sort by position' => 'Ordenar por posição', - 'Sort by date' => 'Ordenar por data', - 'Add task' => 'Adicionar uma tarefa', - 'Start date:' => 'Data de início:', - 'Due date:' => 'Data de expiração:', - 'There is no start date or due date for this task.' => 'Não existe data de início ou data de expiração para esta tarefa.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Mover ou redimensionar uma tarefa irá alterar a data de início e expiração da tarefa.', - 'There is no task in your project.' => 'Não há tarefas em seu projeto.', - 'Gantt chart' => 'Gráfico de Gantt', - 'People who are project managers' => 'Pessoas que são gerente de projeto', - 'People who are project members' => 'Pessoas que são membro de projeto', - 'NOK - Norwegian Krone' => 'NOK - Coroa Norueguesa', - 'Show this column' => 'Mostrar esta coluna', - 'Hide this column' => 'Esconder esta coluna', - 'open file' => 'abrir um arquivo', - 'End date' => 'Data de término', - 'Users overview' => 'Visão geral dos usuários', - 'Members' => 'Membros', - 'Shared project' => 'Projeto compartilhado', - 'Project managers' => 'Gerentes de projeto', - 'Gantt chart for all projects' => 'Gráfico de Gantt para todos os projetos', - 'Projects list' => 'Lista dos projetos', - 'Gantt chart for this project' => 'Gráfico de Gantt para este projeto', - 'Project board' => 'Painel do projeto', - 'End date:' => 'Data de término:', - 'There is no start date or end date for this project.' => 'Não há data de início ou data de término para este projeto.', - 'Projects Gantt chart' => 'Gráfico de Gantt dos projetos', - 'Change task color when using a specific task link' => 'Mudar a cor da tarefa quando um link específico é utilizado', - 'Task link creation or modification' => 'Criação ou modificação de um link em uma tarefa', - 'Milestone' => 'Milestone', - 'Documentation: %s' => 'Documentação: %s', - 'Switch to the Gantt chart view' => 'Mudar para a vista gráfico de Gantt', - 'Reset the search/filter box' => 'Reiniciar o campo de pesquisa', - 'Documentation' => 'Documentação', - 'Table of contents' => 'Índice', - 'Gantt' => 'Gantt', - 'Author' => 'Autor', - 'Version' => 'Versão', - 'Plugins' => 'Extensões', - 'There is no plugin loaded.' => 'Não há extensões carregadas.', - 'Set maximum column height' => 'Definir a altura máxima das colunas', - 'Remove maximum column height' => 'Retirar a altura máxima das colunas', - 'My notifications' => 'Minhas notificações', - 'Custom filters' => 'Filtros personalizados', - 'Your custom filter have been created successfully.' => 'Seu filtro personalizado foi criado com sucesso.', - 'Unable to create your custom filter.' => 'Não foi possível criar seu filtro personalizado.', - 'Custom filter removed successfully.' => 'Filtro personalizado removido com sucesso.', - 'Unable to remove this custom filter.' => 'Não foi possível remover este filtro personalizado.', - 'Edit custom filter' => 'Editar filtro personalizado', - 'Your custom filter have been updated successfully.' => 'Seu filtro personalizado foi atualizado com sucesso.', - 'Unable to update custom filter.' => 'Não foi possível atualizar o filtro personalizado.', - 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Novo anexo na tarefa #%d: %s', - 'New comment on task #%d' => 'Novo comentário na tarefa #%d', - 'Comment updated on task #%d' => 'Comentário atualizado na tarefa #%d', - 'New subtask on task #%d' => 'Nova subtarefa na tarefa #%d', - 'Subtask updated on task #%d' => 'Subtarefa atualizada na tarefa #%d', - 'New task #%d: %s' => 'Nova tarefa #%d: %s', - 'Task updated #%d' => 'Tarefa #%d atualizada', - 'Task #%d closed' => 'Tarefa #%d fechada', - 'Task #%d opened' => 'Tarefa #%d aberta', - 'Column changed for task #%d' => 'Coluna alterada para a tarefa #%d', - 'New position for task #%d' => 'Nova posição para a tarefa #%d', - 'Swimlane changed for task #%d' => 'Swimlane alterada para a tarefa #%d', - 'Assignee changed on task #%d' => 'Designação alterada na tarefa #%d', - '%d overdue tasks' => '%d tarefas atrasadas', - 'Task #%d is overdue' => 'Tarefa #%d está atrasada', - 'No new notifications.' => 'Nenhuma notificação nova.', - 'Mark all as read' => 'Marcar todas como lidas', - 'Mark as read' => 'Marcar como lida', - 'Total number of tasks in this column across all swimlanes' => 'Número total de tarefas nesta coluna através de todas as swimlanes', - 'Collapse swimlane' => 'Contrair swimlane', - 'Expand swimlane' => 'Expandir swimlane', - 'Add a new filter' => 'Adicionar filtro', - 'Share with all project members' => 'Compartilhar com todos os membros do projeto', - 'Shared' => 'Compartilhado', - '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!', - 'Import users from CSV file' => 'Importar usuários a partir de arquivo CSV', - '%d user(s) have been imported successfully.' => '%d usuário(s) importado(s) com sucesso.', - 'Comma' => 'Vírgula', - 'Semi-colon' => 'Ponto e vírgula', - 'Tab' => 'Tab', - 'Vertical bar' => 'Barra vertical', - 'Double Quote' => 'Aspas duplas', - 'Single Quote' => 'Aspas simples', - '%s attached a file to the task #%d' => '%s anexou um arquivo à tarefa #%d', - 'There is no column or swimlane activated in your project!' => 'Não há coluna ou swimlane ativa em seu projeto!', - 'Append filter (instead of replacement)' => 'Adicionar filtro (em vez de substituir)', - 'Append/Replace' => 'Adicionar/Substituir', - 'Append' => 'Adicionar', - 'Replace' => 'Substituir', - 'Import' => 'Importar', - 'change sorting' => 'alterar ordenação', - 'Tasks Importation' => 'Importação de Tarefas', - 'Delimiter' => 'Separador', - 'Enclosure' => 'Delimitador de campos', - 'CSV File' => 'Arquivo CSV', - 'Instructions' => 'Instruções', - 'Your file must use the predefined CSV format' => 'Seu arquivo deve utilizar o formato CSV pré-definido', - 'Your file must be encoded in UTF-8' => 'Seu arquivo deve estar codificado em UTF-8', - 'The first row must be the header' => 'A primeira linha deve ser o cabeçalho', - 'Duplicates are not verified for you' => 'Registros duplicados não são verificados', - 'The due date must use the ISO format: YYYY-MM-DD' => 'A data de vencimento deve utilizar o formato ISO: YYYY-MM-DD', - 'Download CSV template' => 'Baixar modelo de arquivo CSV', - 'No external integration registered.' => 'Nenhuma integração externa registrada.', - 'Duplicates are not imported' => 'Registros duplicados não são importados', - 'Usernames must be lowercase and unique' => 'Nomes de usuário devem ser únicos e em letras minúsculas', - 'Passwords will be encrypted if present' => 'Senhas serão encriptadas, se presentes', - '%s attached a new file to the task %s' => '%s anexou um novo arquivo a tarefa %s', - 'Link type' => 'Tipo de link', - 'Assign automatically a category based on a link' => 'Atribuir automaticamente uma categoria baseada num link', - 'BAM - Konvertible Mark' => 'BAM - Mark conversível', - 'Assignee Username' => 'Usuário designado', - 'Assignee Name' => 'Nome do designado', - 'Groups' => 'Grupos', - 'Members of %s' => 'Membros do %s', - 'New group' => 'Novo grupo', - 'Group created successfully.' => 'Grupo criado com sucesso.', - 'Unable to create your group.' => 'Não foi possível de criar o seu grupo.', - 'Edit group' => 'Editar o grupo', - 'Group updated successfully.' => 'Grupo atualizado com sucesso.', - 'Unable to update your group.' => 'Não foi possível atualizar o seu grupo.', - 'Add group member to "%s"' => 'Adicionar um membro ao grupo "%s"', - 'Group member added successfully.' => 'Membro adicionado com sucesso ao o grupo.', - 'Unable to add group member.' => 'Não foi possivel adicionar esse membro ao grupo.', - 'Remove user from group "%s"' => 'Remover usuário do grupo "%s"', - 'User removed successfully from this group.' => 'Usuário removido com sucesso deste grupo.', - 'Unable to remove this user from the group.' => 'Não foi possivel remover este Usuário do grupo.', - 'Remove group' => 'Remover o grupo', - 'Group removed successfully.' => 'Grupo removido com sucesso.', - 'Unable to remove this group.' => 'Não foi possível remover este grupo.', - 'Project Permissions' => 'Permissões do projeto', - 'Manager' => 'Gerente', - 'Project Manager' => 'Gerente de projeto', - 'Project Member' => 'Membro de projeto', - // 'Project Viewer' => '', - 'Your account is locked for %d minutes' => 'A sua conta está bloqueada por %d minutos', - 'Invalid captcha' => 'Captcha inválido', - 'The name must be unique' => 'O nome deve ser único', - 'View all groups' => 'Ver todos os grupos', - 'View group members' => 'Ver os membros do grupo', - 'There is no user available.' => 'Não há nenhum usuário disponível', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Você realmente deseja remover o usuário "%s" do grupo "%s"?', - 'There is no group.' => 'Não há nenhum grupo.', - 'External Id' => 'Id externo', - 'Add group member' => 'Adicionar um membro ao grupo', - 'Do you really want to remove this group: "%s"?' => 'Você realmente deseja excluir este grupo: "%s"?', - 'There is no user in this group.' => 'Não há usuários neste grupo.', - 'Remove this user' => 'Remover este usuário', - 'Permissions' => 'Permissões', - 'Allowed Users' => 'Usuários autorizados', - 'No user have been allowed specifically.' => 'Nenhum usuário foi especificamente autorizado.', - 'Role' => 'Função', - 'Enter user name...' => 'Digite o nome do usuário...', - 'Allowed Groups' => 'Grupos autorizados', - 'No group have been allowed specifically.' => 'Nenhum grupo foi especificamente autorizado.', - 'Group' => 'Grupo', - 'Group Name' => 'Nome do grupo', - 'Enter group name...' => 'Digite o nome do grupo', - 'Role:' => 'Função:', - 'Project members' => 'Membros de projeto', - 'Compare hours for "%s"' => 'Comparar as horas para "%s"', - '%s mentioned you in the task #%d' => '%s mencionou você na tarefa #%d', - '%s mentioned you in a comment on the task #%d' => '%s mencionou você num comentário da tarefa #%d', - 'You were mentioned in the task #%d' => 'Você foi mencionado na tarefa #%d', - 'You were mentioned in a comment on the task #%d' => 'Você foi mencionado num comentário da tarefa #%d', - 'Mentioned' => 'Mencionado', - 'Compare Estimated Time vs Actual Time' => 'Comparar o tempo estimado e o tempo atual', - 'Estimated hours: ' => 'Horas estimadas: ', - 'Actual hours: ' => 'Horas reais: ', - 'Hours Spent' => 'Horas gastas', - 'Hours Estimated' => 'Horas estimadas', - 'Estimated Time' => 'Tempo estimado', - 'Actual Time' => 'Tempo real', - 'Estimated vs actual time' => 'Tempo estimado vs tempo real', - 'RUB - Russian Ruble' => 'RUB - Rublo russo', - 'Assign the task to the person who does the action when the column is changed' => 'Atribuir a tarefa a pessoa que faz a ação quando a coluna é alterada', - 'Close a task in a specific column' => 'Fechar uma tarefa em uma coluna específica', - 'Time-based One-time Password Algorithm' => 'Senha de uso único baseado no tempo', - 'Two-Factor Provider: ' => 'Provedor de autenticação a dois fatores: ', - 'Disable two-factor authentication' => 'Desativar a autenticação a dois fatores', - 'Enable two-factor authentication' => 'Ativar a autenticação a dois fatores', - 'There is no integration registered at the moment.' => 'Não há nenhuma integração registrada por enquanto.', - 'Password Reset for Kanboard' => 'Redefinir a senha para Kanboard', - 'Forgot password?' => 'Esqueceu a senha?', - 'Enable "Forget Password"' => 'Activar a funcionalidade "Esqueceu a senha"', - 'Password Reset' => 'Redefinir a senha', - 'New password' => 'Nova senha', - 'Change Password' => 'Alterar a senha', - 'To reset your password click on this link:' => 'Para redefinir a sua senha, clique neste link:', - 'Last Password Reset' => 'Última redefinição de senha', - 'The password has never been reinitialized.' => 'A senha nunca foi redifinida.', - 'Creation' => 'Criação', - 'Expiration' => 'Expiração', - 'Password reset history' => 'Histórico da redefinição da senha', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Todas as tarefas da coluna "%s" e da Swimlane "%s" foram fechadas com sucesso.', - 'Do you really want to close all tasks of this column?' => 'Você realmente deseja fechar todas as tarefas desta coluna?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d tarefa(s) na coluna "%s" e na Swimlane "%s" serão fechadas.', - 'Close all tasks of this column' => 'Fechar todas as tarefas desta coluna', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nenhuma extensão tem registado um método de notificação de projecto. Você ainda pode definir notificações individuais em seu perfil de usuário.', - 'My dashboard' => 'Meu Painel', - 'My profile' => 'Meu perfil', - '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', - 'Task priority' => 'Prioridade das tarefas', - 'General' => 'Geral', - 'Dates' => 'Datas', - 'Default priority' => 'Prioridade padrão', - 'Lowest priority' => 'Prioridade baixa', - 'Highest priority' => 'Prioridade alta', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Se você colocar zero para a prioridade alta e baixa, essa funcionalidade será desativada.', - 'Close a task when there is no activity' => 'Fechar uma tarefa sem atividade', - 'Duration in days' => 'Duração em dias', - 'Send email when there is no activity on a task' => 'Enviar um e-mail quando não há nenhuma atividade em uma tarefa', - 'Unable to fetch link information.' => 'Não foi possível obter informações sobre o link.', - 'Daily background job for tasks' => 'Tarefa agendada diariamente para as tarefas', - 'Auto' => 'Auto', - 'Related' => 'Ligado', - 'Attachment' => 'Anexo', - 'Title not found' => 'Título não encontrado', - 'Web Link' => 'Link web', - 'External links' => 'Links externos', - 'Add external link' => 'Adicionar um link externo', - 'Type' => 'Tipo', - 'Dependency' => 'Dependência', - 'Add internal link' => 'Adicionar um link interno', - 'Add a new external link' => 'Adicionar um novo link externo', - 'Edit external link' => 'Editar um link externo', - 'External link' => 'Link externo', - 'Copy and paste your link here...' => 'Copie e cole o link aqui...', - 'URL' => 'URL', - 'Internal links' => 'Link interno', - 'Assign to me' => 'Atribuir-me', - 'Me' => 'Eu', - 'Do not duplicate anything' => 'Não duplique nada', - 'Projects management' => 'Gestão de projetos', - 'Users management' => 'Gestão dos usuários', - 'Groups management' => 'Gestão dos grupos', - 'Create from another project' => 'Criar a partir de outro projeto', - 'open' => 'aberto', - 'closed' => 'fechado', - 'Priority:' => 'Prioridade:', - 'Reference:' => 'Referência:', - 'Complexity:' => 'Complexidade:', - 'Swimlane:' => 'Swimlane:', - 'Column:' => 'Coluna:', - 'Position:' => 'Posição:', - 'Creator:' => 'Criador:', - 'Time estimated:' => 'Tempo estimado:', - '%s hours' => '%s horas', - 'Time spent:' => 'Tempo gasto:', - 'Created:' => 'Criado:', - 'Modified:' => 'Modificado:', - 'Completed:' => 'Completado:', - '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: ', - 'New due date: ' => 'Nova data limite: ', - 'Start date changed: ' => 'Data de início alterada: ', - 'Disable private projects' => 'Desativar os projetos privados', - 'Do you really want to remove this custom filter: "%s"?' => 'Você realmente quer remover este filtro personalizado: "%s"?', - 'Remove a custom filter' => 'Remover um filtro personalizado', - 'User activated successfully.' => 'Usuário ativado com sucesso.', - 'Unable to enable this user.' => 'Impossível de ativar esse usuário.', - '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', - 'Two Factor' => 'Dois fatores', - 'Disable user' => 'Desativar o usuário', - 'Do you really want to disable this user: "%s"?' => 'Você realmente quer desativar este usuário: "%s"?', - 'Enable user' => 'Ativar um usuário', - 'Do you really want to enable this user: "%s"?' => 'Você realmente quer ativar este usuário: "%s"?', - 'Download' => 'Baixar', - 'Uploaded: %s' => 'Enviado: %s', - 'Size: %s' => 'Tamanho: %s', - 'Uploaded by %s' => 'Enviado por %s', - 'Filename' => 'Nome do arquivo', - 'Size' => 'Tamanho', - 'Column created successfully.' => 'A coluna criada com sucesso.', - 'Another column with the same name exists in the project' => 'Uma outra coluna com o mesmo nome já existe no projeto', - 'Default filters' => 'Filtros padrão', - 'Your board doesn\'t have any columns!' => 'O seu painel não tem nenhuma coluna', - 'Change column position' => 'Alterar a posição da coluna', - 'Switch to the project overview' => 'Mudar para a vista geral do projeto', - 'User filters' => 'Filtros dos usuários', - 'Category filters' => 'Filtros das categorias', - 'Upload a file' => 'Enviar um arquivo', - 'View file' => 'Ver um arquivo', - 'Last activity' => 'Últimas atividades', - 'Change subtask position' => 'Alterar a posição da sub-tarefa', - 'This value must be greater than %d' => 'Este valor deve ser maior que %d', - 'Another swimlane with the same name exists in the project' => 'Outra Swimlane existe com o mesmo nome no projeto', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Exemplo: http://exemple.kanboard.net/ (usado para gerar URLs absolutos)', - 'Actions duplicated successfully.' => 'Ações duplicadas com sucesso.', - 'Unable to duplicate actions.' => 'Não foi possível duplicar as ações.', - 'Add a new action' => 'Adicionar uma nova ação', - 'Import from another project' => 'Importar a partir de outro projeto', - 'There is no action at the moment.' => 'Não há nenhuma ação actualmente.', - 'Import actions from another project' => 'Importar ações a partir de outro projeto', - 'There is no available project.' => 'Não há projetos disponíveis.', - 'Local File' => 'Arquivo local', - 'Configuration' => 'Configuração', - 'PHP version:' => 'Versão do PHP:', - 'PHP SAPI:' => 'PHP SAPI:', - 'OS version:' => 'Versão do sistema operacional:', - 'Database version:' => 'Versão do banco de dados:', - 'Browser:' => 'Browser:', - 'Task view' => 'Vista detalhada de uma tarefa', - 'Edit task' => 'Editar a tarefa', - 'Edit description' => 'Editar a descrição', - 'New internal link' => 'Novo link interno', - 'Display list of keyboard shortcuts' => 'Ver a lista dos atalhos de teclado', - 'Menu' => 'Menu', - 'Set start date' => 'Definir a data de início', - 'Avatar' => 'Avatar', - 'Upload my avatar image' => 'Enviar a minha imagem de avatar', - 'Remove my image' => 'Remover a minha imagem', - 'The OAuth2 state parameter is invalid' => 'O parâmetro "state" de OAuth2 não é válido', - // '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' => '', -); diff --git a/sources/app/Locale/pt_PT/translations.php b/sources/app/Locale/pt_PT/translations.php deleted file mode 100644 index d9ea27b..0000000 --- a/sources/app/Locale/pt_PT/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => ' ', - 'None' => 'Nenhum', - 'edit' => 'editar', - 'Edit' => 'Editar', - 'remove' => 'remover', - 'Remove' => 'Remover', - 'Yes' => 'Sim', - 'No' => 'Não', - 'cancel' => 'cancelar', - 'or' => 'ou', - 'Yellow' => 'Amarelo', - 'Blue' => 'Azul', - 'Green' => 'Verde', - 'Purple' => 'Roxo', - 'Red' => 'Vermelho', - 'Orange' => 'Laranja', - 'Grey' => 'Cinza', - 'Brown' => 'Castanho', - 'Deep Orange' => 'Laranja escuro', - 'Dark Grey' => 'Cinza escuro', - 'Pink' => 'Rosa', - 'Teal' => 'Turquesa', - 'Cyan' => 'Azul intenso', - 'Lime' => 'Verde limão', - 'Light Green' => 'Verde claro', - 'Amber' => 'Âmbar', - 'Save' => 'Guardar', - 'Login' => 'Login', - 'Official website:' => 'Site oficial:', - 'Unassigned' => 'Não Atribuída', - 'View this task' => 'Ver esta tarefa', - 'Remove user' => 'Remover utilizador', - 'Do you really want to remove this user: "%s"?' => 'Pretende mesmo remover este utilizador: "%s"?', - 'All users' => 'Todos os utilizadores', - 'Username' => 'Nome de utilizador', - 'Password' => 'Senha', - 'Administrator' => 'Administrador', - 'Sign in' => 'Entrar', - 'Users' => 'Utilizadores', - 'No user' => 'Sem utilizador', - 'Forbidden' => 'Proibido', - 'Access Forbidden' => 'Acesso negado', - 'Edit user' => 'Editar utilizador', - 'Logout' => 'Sair', - 'Bad username or password' => 'Utilizador ou senha inválidos', - 'Edit project' => 'Editar projecto', - 'Name' => 'Nome', - 'Projects' => 'Projectos', - 'No project' => 'Nenhum projecto', - 'Project' => 'Projecto', - 'Status' => 'Estado', - 'Tasks' => 'Tarefas', - 'Board' => 'Quadro', - 'Actions' => 'Acções', - 'Inactive' => 'Inactivo', - 'Active' => 'Activo', - '%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 projecto', - 'Do you really want to remove this project: "%s"?' => 'Tem a certeza que quer remover este projecto: "%s" ?', - 'Remove project' => 'Remover projecto', - 'Edit the board for "%s"' => 'Editar o quadro para "%s"', - 'All projects' => 'Todos os projectos', - 'Add a new column' => 'Adicionar uma nova coluna', - '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!', - 'Settings' => 'Configurações', - 'Application settings' => 'Configurações da aplicação', - 'Language' => 'Idioma', - 'Webhook token:' => 'Token de webhooks:', - 'API token:' => 'API Token:', - 'Database size:' => 'Tamanho da base de dados:', - 'Download the database' => 'Download da base de dados', - 'Optimize the database' => 'Otimizar a base de dados', - '(VACUUM command)' => '(Comando VACUUM)', - '(Gzip compressed Sqlite file)' => '(Arquivo Sqlite comprimido com Gzip)', - 'Close a task' => 'Finalizar uma tarefa', - 'Edit a task' => 'Editar uma tarefa', - 'Column' => 'Coluna', - 'Color' => 'Cor', - 'Assignee' => 'Assignado', - 'Create another task' => 'Criar outra tarefa', - 'New task' => 'Nova tarefa', - 'Open a task' => 'Abrir uma tarefa', - 'Do you really want to open this task: "%s"?' => 'Tem a certeza que quer abrir esta tarefa: "%s"?', - 'Back to the board' => 'Voltar ao quadro', - 'There is nobody assigned' => 'Não há ninguém assignado', - 'Column on the board:' => 'Coluna no quadro:', - 'Close this task' => 'Finalizar esta tarefa', - 'Open this task' => 'Abrir esta tarefa', - 'There is no description.' => 'Não há descrição.', - 'Add a new task' => 'Adicionar uma nova tarefa', - 'The username is required' => 'O nome de utilizador é obrigatório', - 'The maximum length is %d characters' => 'O tamanho máximo é %d caracteres', - 'The minimum length is %d characters' => 'O tamanho mínimo é %d caracteres', - 'The password is required' => 'A senha é obrigatória', - 'This value must be an integer' => 'O valor deve ser um número inteiro', - 'The username must be unique' => 'O nome de utilizador deve ser único', - 'The user id is required' => 'O ID de utilizador é obrigatório', - 'Passwords don\'t match' => 'As senhas não coincidem', - 'The confirmation is required' => 'A confirmação é obrigatória', - 'The project is required' => 'O projecto é obrigatório', - 'The id is required' => 'O ID é obrigatório', - 'The project id is required' => 'O ID do projecto é obrigatório', - 'The project name is required' => 'O nome do projecto é obrigatório', - 'The title is required' => 'O título é obrigatório', - 'Settings saved successfully.' => 'Configurações guardadas com sucesso.', - 'Unable to save your settings.' => 'Não é possível guardar as suas configurações.', - 'Database optimization done.' => 'Otimização da base de dados finalizada.', - 'Your project have been created successfully.' => 'Projecto foi criado com sucesso.', - 'Unable to create your project.' => 'Não é possível criar o projecto.', - 'Project updated successfully.' => 'Projecto actualizado com sucesso.', - 'Unable to update this project.' => 'Não é possível actualizar este projecto.', - 'Unable to remove this project.' => 'Não é possível remover este projecto.', - 'Project removed successfully.' => 'Projecto removido com sucesso.', - 'Project activated successfully.' => 'Projecto activado com sucesso.', - 'Unable to activate this project.' => 'Não é possível activar este projecto.', - 'Project disabled successfully.' => 'Projecto desactivado com sucesso.', - 'Unable to disable this project.' => 'Não é possível desactivar este projecto.', - 'Unable to open this task.' => 'Não é possível abrir esta tarefa.', - 'Task opened successfully.' => 'Tarefa aberta com sucesso.', - 'Unable to close this task.' => 'Não é possível finalizar esta tarefa.', - 'Task closed successfully.' => 'Tarefa finalizada com sucesso.', - 'Unable to update your task.' => 'Não é possível actualizar a sua tarefa.', - 'Task updated successfully.' => 'Tarefa actualizada com sucesso.', - 'Unable to create your task.' => 'Não é possível criar a sua tarefa.', - 'Task created successfully.' => 'Tarefa criada com sucesso.', - 'User created successfully.' => 'Utilizador criado com sucesso.', - 'Unable to create your user.' => 'Não é possível criar o seu Utilizador.', - 'User updated successfully.' => 'Utilizador actualizado com sucesso.', - 'Unable to update your user.' => 'Não é possível actualizar o seu Utilizador.', - 'User removed successfully.' => 'Utilizador removido com sucesso.', - 'Unable to remove this user.' => 'Não é possível remover este Utilizador.', - 'Board updated successfully.' => 'Quadro actualizado com sucesso.', - 'Ready' => 'Pronto', - 'Backlog' => 'Backlog', - 'Work in progress' => 'Em andamento', - 'Done' => 'Finalizado', - 'Application version:' => 'Versão da aplicação:', - 'Id' => 'Id', - '%d closed tasks' => '%d tarefas finalizadas', - 'No task for this project' => 'Não há tarefa para este projecto', - 'Public link' => 'Link público', - 'Timezone' => 'Fuso horário', - 'Sorry, I didn\'t find this information in my database!' => 'Desculpe, não encontrei esta informação na minha base de dados!', - 'Page not found' => 'Página não encontrada', - 'Complexity' => 'Complexidade', - 'Task limit' => 'Limite da tarefa', - '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', - 'Invalid date' => 'Data inválida', - 'Automatic actions' => 'Acções automáticas', - 'Your automatic action have been created successfully.' => 'A sua acção automática foi criada com sucesso.', - 'Unable to create your automatic action.' => 'Não é possível criar a sua acção automática.', - 'Remove an action' => 'Remover uma acção', - 'Unable to remove this action.' => 'Não é possível remover esta acção.', - 'Action removed successfully.' => 'Acção removida com sucesso.', - 'Automatic actions for the project "%s"' => 'Acções automáticas para o projecto "%s"', - 'Add an action' => 'Adicionar Acção', - 'Event name' => 'Nome do evento', - 'Action name' => 'Nome da acção', - 'Action parameters' => 'Parâmetros da acção', - 'Action' => 'Acção', - 'Event' => 'Evento', - 'When the selected event occurs execute the corresponding action.' => 'Quando o evento selecionado ocorrer execute a acção correspondente.', - 'Next step' => 'Próximo passo', - 'Define action parameters' => 'Definir parêmetros da acção', - 'Do you really want to remove this action: "%s"?' => 'Tem a certeza que quer remover esta acção: "%s"?', - 'Remove an automatic action' => 'Remover uma acção automática', - 'Assign the task to a specific user' => 'Designar a tarefa para um utilizador específico', - 'Assign the task to the person who does the action' => 'Designar a tarefa para a pessoa que executa a acção', - 'Duplicate the task to another project' => 'Duplicar a tarefa para um outro projecto', - 'Move a task to another column' => 'Mover a tarefa para outra coluna', - 'Task modification' => 'Modificação de tarefa', - 'Task creation' => 'Criação de tarefa', - 'Closing a task' => 'A finalizar uma tarefa', - 'Assign a color to a specific user' => 'Designar uma cor para um utilizador específico', - 'Column title' => 'Título da coluna', - 'Position' => 'Posição', - 'Duplicate to another project' => 'Duplicar para outro projecto', - 'Duplicate' => 'Duplicar', - 'link' => 'link', - 'Comment updated successfully.' => 'Comentário actualizado com sucesso.', - 'Unable to update your comment.' => 'Não é possível actualizar o seu comentário.', - 'Remove a comment' => 'Remover um comentário', - 'Comment removed successfully.' => 'Comentário removido com sucesso.', - 'Unable to remove this comment.' => 'Não é possível remover este comentário.', - 'Do you really want to remove this comment?' => 'Tem a certeza que quer remover este comentário?', - 'Current password for the user "%s"' => 'Senha atual para o utilizador "%s"', - 'The current password is required' => 'A senha atual é obrigatória', - 'Wrong password' => 'Senha incorreta', - 'Unknown' => 'Desconhecido', - 'Last logins' => 'Últimos logins', - 'Login date' => 'Data de login', - 'Authentication method' => 'Método de autenticação', - 'IP address' => 'Endereço IP', - 'User agent' => 'User Agent', - 'Persistent connections' => 'Conexões persistentes', - 'No session.' => 'Nenhuma sessão.', - 'Expiration date' => 'Data de expiração', - 'Remember Me' => 'Lembre-se de mim', - 'Creation date' => 'Data de criação', - 'Everybody' => 'Todos', - 'Open' => 'Aberto', - 'Closed' => 'Finalizado', - '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', - 'Email address invalid' => 'Endereço de e-mail inválido', - 'Your external account is not linked anymore to your profile.' => 'A sua conta externa já não se encontra vinculada a este perfil', - 'Unable to unlink your external account.' => 'Não foi possivel desvincular a sua conta externa', - 'External authentication failed' => 'Autenticação externa falhou', - 'Your external account is linked to your profile successfully.' => 'A sua conta externa foi vinculada com sucesso ao seu perfil', - 'Email' => 'E-mail', - 'Task removed successfully.' => 'Tarefa removida com sucesso.', - 'Unable to remove this task.' => 'Não foi possível remover esta tarefa.', - 'Remove a task' => 'Remover uma tarefa', - 'Do you really want to remove this task: "%s"?' => 'Tem a certeza que quer remover esta tarefa: "%s"', - 'Assign automatically a color based on a category' => 'Atribuir automaticamente uma cor com base numa categoria', - 'Assign automatically a category based on a color' => 'Atribuir automaticamente uma categoria com base numa cor', - 'Task creation or modification' => 'Criação ou modificação de tarefa', - 'Category' => 'Categoria', - 'Category:' => 'Categoria:', - 'Categories' => 'Categorias', - 'Your category have been created successfully.' => 'A sua categoria foi criada com sucesso.', - 'Unable to create your category.' => 'Não foi possível criar a sua categoria.', - 'Your category have been updated successfully.' => 'A sua categoria foi actualizada com sucesso.', - 'Unable to update your category.' => 'Não foi possível actualizar a sua categoria.', - 'Remove a category' => 'Remover uma categoria', - 'Category removed successfully.' => 'Categoria removida com sucesso.', - 'Unable to remove this category.' => 'Não foi possível remover esta categoria.', - 'Category modification for the project "%s"' => 'Modificação de categoria para o projecto "%s"', - 'Category Name' => 'Nome da Categoria', - 'Add a new category' => 'Adicionar uma nova categoria', - 'Do you really want to remove this category: "%s"?' => 'Tem a certeza que quer remover esta categoria: "%s"', - 'All categories' => 'Todas as categorias', - 'No category' => 'Nenhuma categoria', - 'The name is required' => 'O nome é obrigatório', - 'Remove a file' => 'Remover um arquivo', - 'Unable to remove this file.' => 'Não foi possível remover este arquivo.', - 'File removed successfully.' => 'Arquivo removido com sucesso.', - 'Attach a document' => 'Anexar um documento', - 'Do you really want to remove this file: "%s"?' => 'Tem a certeza que quer remover este arquivo: "%s"', - 'Attachments' => 'Anexos', - 'Edit the task' => 'Editar a tarefa', - 'Add a comment' => 'Adicionar um comentário', - 'Edit a comment' => 'Editar um comentário', - 'Summary' => 'Resumo', - 'Time tracking' => 'Rastreamento de tempo', - 'Estimate:' => 'Estimado:', - 'Spent:' => 'Gasto:', - 'Do you really want to remove this sub-task?' => 'Tem a certeza que quer remover esta subtarefa?', - 'Remaining:' => 'Restante:', - 'hours' => 'horas', - 'spent' => 'gasto', - 'estimated' => 'estimado', - 'Sub-Tasks' => 'Subtarefas', - 'Add a sub-task' => 'Adicionar uma subtarefa', - 'Original estimate' => 'Estimativa original', - 'Create another sub-task' => 'Criar uma outra subtarefa', - 'Time spent' => 'Tempo gasto', - 'Edit a sub-task' => 'Editar uma subtarefa', - 'Remove a sub-task' => 'Remover uma subtarefa', - 'The time must be a numeric value' => 'O tempo deve ser um valor numérico', - 'Todo' => 'A fazer', - 'In progress' => 'Em andamento', - 'Sub-task removed successfully.' => 'Subtarefa removida com sucesso.', - 'Unable to remove this sub-task.' => 'Não foi possível remover esta subtarefa.', - 'Sub-task updated successfully.' => 'Subtarefa atualizada com sucesso.', - 'Unable to update your sub-task.' => 'Não foi possível atualizar a sua subtarefa.', - 'Unable to create your sub-task.' => 'Não é possível criar a sua subtarefa.', - 'Sub-task added successfully.' => 'Subtarefa adicionada com sucesso.', - 'Maximum size: ' => 'Tamanho máximo: ', - 'Unable to upload the file.' => 'Não foi possível carregar o arquivo.', - 'Display another project' => 'Mostrar outro projecto', - 'Created by %s' => 'Criado por %s', - 'Tasks Export' => 'Exportar Tarefas', - 'Tasks exportation for "%s"' => 'As tarefas foram exportadas para "%s"', - 'Start Date' => 'Data inicial', - 'End Date' => 'Data final', - 'Execute' => 'Executar', - 'Task Id' => 'ID da Tarefa', - 'Creator' => 'Criado por', - 'Modification date' => 'Data da modificação', - 'Completion date' => 'Data da finalização', - 'Clone' => 'Clonar', - 'Project cloned successfully.' => 'Projecto clonado com sucesso.', - 'Unable to clone this project.' => 'Não foi possível clonar este projecto.', - 'Enable email notifications' => 'Activar notificações por email', - '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.', - 'Sub-task updated' => 'Subtarefa atualizada', - 'Title:' => 'Título:', - 'Status:' => 'Estado:', - 'Assignee:' => 'Assignado:', - 'Time tracking:' => 'Controle de tempo:', - 'New sub-task' => 'Nova subtarefa', - 'New attachment added "%s"' => 'Novo anexo adicionado "%s"', - 'New comment posted by %s' => 'Novo comentário por %s', - 'New attachment' => 'Novo anexo', - 'New comment' => 'Novo comentário', - 'Comment updated' => 'Comentário actualizado', - 'New subtask' => 'Nova subtarefa', - 'Subtask updated' => 'Subtarefa alterada', - 'Task updated' => 'Tarefa alterada', - 'Task closed' => 'Tarefa finalizada', - 'Task opened' => 'Tarefa aberta', - 'I want to receive notifications only for those projects:' => 'Quero receber notificações apenas destes projectos:', - 'view the task on Kanboard' => 'ver a tarefa no Kanboard', - 'Public access' => 'Acesso público', - 'Active tasks' => 'Tarefas activas', - 'Disable public access' => 'Desactivar o acesso público', - 'Enable public access' => 'Activar o acesso público', - 'Public access disabled' => 'Acesso público desactivado', - 'Do you really want to disable this project: "%s"?' => 'Tem a certeza que quer desactivar este projecto: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Tem a certeza que quer activar este projecto: "%s"?', - 'Project activation' => 'Activação do projecto', - 'Move the task to another project' => 'Mover a tarefa para outro projecto', - 'Move to another project' => 'Mover para outro projecto', - 'Do you really want to duplicate this task?' => 'Tem a certeza que quer duplicar esta tarefa?', - 'Duplicate a task' => 'Duplicar uma tarefa', - 'External accounts' => 'Contas externas', - 'Account type' => 'Tipo de conta', - 'Local' => 'Local', - 'Remote' => 'Remoto', - 'Enabled' => 'Activado', - 'Disabled' => 'Desactivado', - 'Username:' => 'Utilizador:', - 'Name:' => 'Nome:', - 'Email:' => 'E-mail:', - 'Notifications:' => 'Notificações:', - 'Notifications' => 'Notificações', - 'Account type:' => 'Tipo de conta:', - 'Edit profile' => 'Editar perfil', - 'Change password' => 'Alterar senha', - 'Password modification' => 'Alteração de senha', - 'External authentications' => 'Autenticação externa', - 'Never connected.' => 'Nunca conectado.', - 'No external authentication enabled.' => 'Nenhuma autenticação externa activa.', - 'Password modified successfully.' => 'Senha alterada com sucesso.', - 'Unable to change the password.' => 'Não foi possível alterar a senha.', - 'Change category' => 'Mudar categoria', - '%s updated the task %s' => '%s actualizou a tarefa %s', - '%s opened the task %s' => '%s abriu a tarefa %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s moveu a tarefa %s para a posição #%d na coluna "%s"', - '%s moved the task %s to the column "%s"' => '%s moveu a tarefa %s para a coluna "%s"', - '%s created the task %s' => '%s criou a tarefa %s', - '%s closed the task %s' => '%s finalizou a tarefa %s', - '%s created a subtask for the task %s' => '%s criou uma subtarefa para a tarefa %s', - '%s updated a subtask for the task %s' => '%s actualizou uma subtarefa da tarefa %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Designado para %s com tempo estimado de %s/%sh', - 'Not assigned, estimate of %sh' => 'Não assignado, estimado em %sh', - '%s updated a comment on the task %s' => '%s actualizou o comentário na tarefa %s', - '%s commented the task %s' => '%s comentou a tarefa %s', - '%s\'s activity' => 'Atividades de%s', - 'RSS feed' => 'Feed RSS', - '%s updated a comment on the task #%d' => '%s actualizou um comentário sobre a tarefa #%d', - '%s commented on the task #%d' => '%s comentou sobre a tarefa #%d', - '%s updated a subtask for the task #%d' => '%s actualizou uma subtarefa para a tarefa #%d', - '%s created a subtask for the task #%d' => '%s criou uma subtarefa para a tarefa #%d', - '%s updated the task #%d' => '%s actualizou a tarefa #%d', - '%s created the task #%d' => '%s criou a tarefa #%d', - '%s closed the task #%d' => '%s finalizou a tarefa #%d', - '%s open the task #%d' => '%s abriu a tarefa #%d', - '%s moved the task #%d to the column "%s"' => '%s moveu a tarefa #%d para a coluna "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s moveu a tarefa #%d para a posição %d na coluna "%s"', - 'Activity' => 'Actividade', - 'Default values are "%s"' => 'Os valores padrão são "%s"', - 'Default columns for new projects (Comma-separated)' => 'Colunas padrão para novos projectos (Separado por vírgula)', - 'Task assignee change' => 'Mudar assignação da tarefa', - '%s change the assignee of the task #%d to %s' => '%s mudou a assignação da tarefa #%d para %s', - '%s changed the assignee of the task %s to %s' => '%s mudou a assignação da tarefa %s para %s', - 'New password for the user "%s"' => 'Nova senha para o utilizador "%s"', - 'Choose an event' => 'Escolher um evento', - 'Create a task from an external provider' => 'Criar uma tarefa por meio de um serviço externo', - 'Change the assignee based on an external username' => 'Alterar assignação com base num utilizador externo', - 'Change the category based on an external label' => 'Alterar categoria com base num rótulo externo', - 'Reference' => 'Referência', - 'Label' => 'Rótulo', - 'Database' => 'Base de dados', - 'About' => 'Sobre', - 'Database driver:' => 'Driver da base de dados:', - 'Board settings' => 'Configurações do Quadro', - 'Webhook settings' => 'Configurações do Webhook', - 'Reset token' => 'Redefinir token', - 'API endpoint:' => 'API endpoint:', - 'Refresh interval for private board' => 'Intervalo de actualização para um quadro privado', - 'Refresh interval for public board' => 'Intervalo de actualização para um quadro público', - 'Task highlight period' => 'Período de Tarefa em destaque', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Período (em segundos) para considerar que uma tarefa foi modificada recentemente (0 para desactivar, 2 dias por defeito)', - 'Frequency in second (60 seconds by default)' => 'Frequência em segundos (60 segundos por defeito)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frequência em segundos (0 para desactivar este recurso, 10 segundos por defeito)', - 'Application URL' => 'URL da Aplicação', - 'Token regenerated.' => 'Token ', - 'Date format' => 'Formato da data', - 'ISO format is always accepted, example: "%s" and "%s"' => 'O formato ISO é sempre aceite, exemplo: "%s" e "%s"', - 'New private project' => 'Novo projecto privado', - 'This project is private' => 'Este projecto é privado', - 'Add' => 'Adicionar', - 'Start date' => 'Data de início', - 'Time estimated' => 'Tempo estimado', - 'There is nothing assigned to you.' => 'Não há nada assignado a si.', - 'My tasks' => 'As minhas tarefas', - 'Activity stream' => 'Atividades Recentes', - 'Dashboard' => 'Painel de Controlo', - 'Confirmation' => 'Confirmação', - 'Allow everybody to access to this project' => 'Permitir a todos os acesso a este projecto', - 'Everybody have access to this project.' => 'Todos possuem acesso a este projecto.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Criar um comentário por meio de um serviço externo', - 'Project management' => 'Gestão de projectos', - 'My projects' => 'Os meus projectos', - 'Columns' => 'Colunas', - 'Task' => 'Tarefas', - 'Your are not member of any project.' => 'Você não é membro de nenhum projecto.', - 'Percentage' => 'Percentagem', - 'Number of tasks' => 'Número de tarefas', - 'Task distribution' => 'Distribuição de tarefas', - 'Reportings' => 'Relatórios', - 'Task repartition for "%s"' => 'Redistribuição da tarefa para "%s"', - 'Analytics' => 'Estatísticas', - 'Subtask' => 'Subtarefa', - 'My subtasks' => 'As minhas subtarefas', - 'User repartition' => 'Redistribuição de utilizador', - 'User repartition for "%s"' => 'Redistribuição de utilizador para "%s"', - 'Clone this project' => 'Clonar este projecto', - 'Column removed successfully.' => 'Coluna removida com sucesso.', - 'Not enough data to show the graph.' => 'Não há dados suficientes para mostrar o gráfico.', - 'Previous' => 'Anterior', - 'The id must be an integer' => 'O ID deve ser um número inteiro', - 'The project id must be an integer' => 'O ID do projecto deve ser um inteiro', - 'The status must be an integer' => 'O estado deve ser um número inteiro', - 'The subtask id is required' => 'O ID da subtarefa é obrigatório', - 'The subtask id must be an integer' => 'O ID da subtarefa deve ser um número inteiro', - 'The task id is required' => 'O ID da tarefa é obrigatório', - 'The task id must be an integer' => 'O ID da tarefa deve ser um número inteiro', - 'The user id must be an integer' => 'O ID do utilizador deve ser um número inteiro', - 'This value is required' => 'Este valor é obrigatório', - 'This value must be numeric' => 'Este valor deve ser numérico', - 'Unable to create this task.' => 'Não foi possível criar esta tarefa.', - 'Cumulative flow diagram' => 'Fluxograma cumulativo', - 'Cumulative flow diagram for "%s"' => 'Fluxograma cumulativo para "%s"', - 'Daily project summary' => 'Resumo diário do projecto', - 'Daily project summary export' => 'Exportação diária do resumo do projecto', - 'Daily project summary export for "%s"' => 'Exportação diária do resumo do projecto para "%s"', - 'Exports' => 'Exportar', - 'This export contains the number of tasks per column grouped per day.' => 'Esta exportação contém o número de tarefas por coluna agrupada por dia.', - 'Active swimlanes' => 'Activar swimlanes', - 'Add a new swimlane' => 'Adicionar novo swimlane', - 'Change default swimlane' => 'Alterar swimlane padrão', - 'Default swimlane' => 'Swimlane padrão', - 'Do you really want to remove this swimlane: "%s"?' => 'Tem a certeza que quer remover este swimlane: "%s"?', - 'Inactive swimlanes' => 'Desactivar swimlanes', - 'Remove a swimlane' => 'Remover um swimlane', - 'Show default swimlane' => 'Mostrar swimlane padrão', - 'Swimlane modification for the project "%s"' => 'Modificação de swimlane para o projecto "%s"', - 'Swimlane removed successfully.' => 'Swimlane removido com sucesso.', - 'Swimlanes' => 'Swimlanes', - 'Swimlane updated successfully.' => 'Swimlane atualizado com sucesso.', - 'The default swimlane have been updated successfully.' => 'O swimlane padrão foi atualizado com sucesso.', - 'Unable to remove this swimlane.' => 'Não foi possível remover este swimlane.', - 'Unable to update this swimlane.' => 'Não foi possível atualizar este swimlane.', - 'Your swimlane have been created successfully.' => 'Seu swimlane foi criado com sucesso.', - 'Example: "Bug, Feature Request, Improvement"' => 'Exemplo: "Bug, Feature Request, Improvement"', - 'Default categories for new projects (Comma-separated)' => 'Categorias padrão para novos projectos (Separadas por vírgula)', - 'Integrations' => 'Integrações', - 'Integration with third-party services' => 'Integração com serviços de terceiros', - 'Subtask Id' => 'ID da subtarefa', - 'Subtasks' => 'Subtarefas', - 'Subtasks Export' => 'Exportar subtarefas', - 'Subtasks exportation for "%s"' => 'Subtarefas exportadas para "%s"', - 'Task Title' => 'Título da Tarefa', - 'Untitled' => 'Sem título', - 'Application default' => 'Aplicação padrão', - 'Language:' => 'Idioma:', - 'Timezone:' => 'Fuso horário:', - 'All columns' => 'Todas as colunas', - 'Calendar' => 'Calendário', - 'Next' => 'Próximo', - // '#%d' => '', - 'All swimlanes' => 'Todos os swimlane', - 'All colors' => 'Todas as cores', - 'Moved to column %s' => 'Mover para a coluna %s', - 'User dashboard' => 'Painel de Controlo do utilizador', - 'Allow only one subtask in progress at the same time for a user' => 'Permitir apenas uma subtarefa em andamento ao mesmo tempo para um utilizador', - 'Edit column "%s"' => 'Editar a coluna "%s"', - 'Select the new status of the subtask: "%s"' => 'Selecionar um novo estado para a subtarefa: "%s"', - 'Subtask timesheet' => 'Gestão de tempo das subtarefas', - 'There is nothing to show.' => 'Não há nada para mostrar', - 'Time Tracking' => 'Gestão de tempo', - 'You already have one subtask in progress' => 'Já tem uma subtarefa em andamento', - 'Which parts of the project do you want to duplicate?' => 'Quais as partes do projecto que deseja duplicar?', - 'Disallow login form' => 'Desactivar login', - 'Start' => 'Inicio', - 'End' => 'Fim', - 'Task age in days' => 'Idade da tarefa em dias', - 'Days in this column' => 'Dias nesta coluna', - // '%dd' => '', - 'Add a new link' => 'Adicionar uma nova associação', - 'Do you really want to remove this link: "%s"?' => 'Tem a certeza que quer remover esta associação: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Tem a certeza que quer remover esta associação com a tarefa n°%d?', - 'Field required' => 'Campo requerido', - 'Link added successfully.' => 'Associação criada com sucesso.', - 'Link updated successfully.' => 'Associação atualizada com sucesso.', - 'Link removed successfully.' => 'Associação removida com sucesso.', - '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', - 'Unable to create your link.' => 'Impossível de adicionar sua associação.', - 'Unable to update your link.' => 'Impossível de atualizar sua associação.', - 'Unable to remove this link.' => 'Impossível de remover sua associação.', - 'relates to' => 'é associado com', - 'blocks' => 'blocos', - 'is blocked by' => 'está bloqueado por', - 'duplicates' => 'duplica', - 'is duplicated by' => 'é duplicado por', - 'is a child of' => 'é um filho de', - 'is a parent of' => 'é um parente do', - 'targets milestone' => 'visa um objectivo', - 'is a milestone of' => 'é um objectivo de', - 'fixes' => 'corrige', - 'is fixed by' => 'foi corrigido por', - 'This task' => 'Esta tarefa', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Expandir tarefas', - 'Collapse tasks' => 'Contrair tarefas', - 'Expand/collapse tasks' => 'Expandir/Contrair tarefas', - 'Close dialog box' => 'Fechar a caixa de diálogo', - 'Submit a form' => 'Envia o formulário', - 'Board view' => 'Vista do Quadro', - 'Keyboard shortcuts' => 'Atalhos de teclado', - 'Open board switcher' => 'Abrir o comutador de painel', - 'Application' => 'Aplicação', - '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' => 'Projecto privado', - 'AUD - Australian Dollar' => 'AUD - Dólar australiano', - 'CAD - Canadian Dollar' => 'CAD - Dólar canadense', - 'CHF - Swiss Francs' => 'CHF - Francos Suíços', - 'Custom Stylesheet' => 'Folha de estilos personalizada', - 'download' => 'transferir', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Libra Esterlina', - 'INR - Indian Rupee' => 'INR - Rúpia indiana', - 'JPY - Japanese Yen' => 'JPY - Iene japonês', - 'NZD - New Zealand Dollar' => 'NZD - Dólar Neozelandês', - 'RSD - Serbian dinar' => 'RSD - Dinar sérvio', - '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', - 'Move the task to another column when assignee is cleared' => 'Mover a tarefa para uma outra coluna quando esta não está atribuída', - 'Source column' => 'Coluna de origem', - 'Transitions' => 'Transições', - 'Executer' => 'Executor(a)', - 'Time spent in the column' => 'Tempo gasto na coluna', - 'Task transitions' => 'Transições das tarefas', - 'Task transitions export' => 'Exportação das transições das tarefas', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Este relatório contém todos os movimentos de coluna para cada tarefa com a data, o utilizador e o tempo gasto para cada transição.', - '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.', - 'Webhook URL' => 'URL do webhook', - '%s remove the assignee of the task %s' => '%s removeu a pessoa assignada à tarefa %s', - 'Enable Gravatar images' => 'Activar imagem Gravatar', - 'Information' => 'Informações', - 'Check two factor authentication code' => 'Verificação do código de autenticação com factor duplo', - 'The two factor authentication code is not valid.' => 'O código de autenticação com factor duplo não é válido', - 'The two factor authentication code is valid.' => 'O código de autenticação com factor duplo é válido', - 'Code' => 'Código', - 'Two factor authentication' => 'Autenticação com factor duplo', - 'This QR code contains the key URI: ' => 'Este Código QR contém a chave URI: ', - 'Check my code' => 'Verificar o meu código', - 'Secret key: ' => 'Chave secreta: ', - 'Test your device' => 'Teste o seu dispositivo', - 'Assign a color when the task is moved to a specific column' => 'Atribuir uma cor quando a tarefa é movida em uma coluna específica', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Gráfico de Burndown para "%s"', - 'Burndown chart' => 'Gráfico de Burndown', - 'This chart show the task complexity over the time (Work Remaining).' => 'Este gráfico mostra a complexidade da tarefa ao longo do tempo (Trabalho Restante).', - 'Screenshot taken %s' => 'Screenshot tirada a %s', - 'Add a screenshot' => 'Adicionar uma Screenshot', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Tire um screenshot e pressione CTRL + V ou ⌘ + V para colar aqui.', - 'Screenshot uploaded successfully.' => 'Screenshot enviada com sucesso.', - 'SEK - Swedish Krona' => 'SEK - Coroa sueca', - 'Identifier' => 'Identificador', - 'Disable two factor authentication' => 'Desactivar autenticação com dois factores', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Tem a certeza que quer desactivar a autenticação com dois factores para esse utilizador: "%s"?', - 'Edit link' => 'Editar um link', - 'Start to type task title...' => 'Escreva o título do trabalho...', - 'A task cannot be linked to itself' => 'Uma tarefa não pode ser ligada a si própria', - 'The exact same link already exists' => 'Um link idêntico jà existe', - 'Recurrent task is scheduled to be generated' => 'A tarefa recorrente está programada para ser criada', - 'Score' => 'Complexidade', - 'The identifier must be unique' => 'O identificador deve ser único', - 'This linked task id doesn\'t exists' => 'O identificador da tarefa associada não existe', - 'This value must be alphanumeric' => 'Este valor deve ser alfanumérico', - 'Edit recurrence' => 'Modificar a recorrência', - 'Generate recurrent task' => 'Gerar uma tarefa recorrente', - 'Trigger to generate recurrent task' => 'Activador para gerar tarefa recorrente', - 'Factor to calculate new due date' => 'Factor para o cálculo do nova data de vencimento', - 'Timeframe to calculate new due date' => 'Escala de tempo para o cálculo da nova data de vencimento', - 'Base date to calculate new due date' => 'Data a ser utilizada para calcular a nova data de vencimento', - 'Action date' => 'Data da acção', - 'Base date to calculate new due date: ' => 'Data a ser utilizada para calcular a nova data de vencimento: ', - 'This task has created this child task: ' => 'Esta tarefa criou a tarefa filha: ', - 'Day(s)' => 'Dia(s)', - 'Existing due date' => 'Data de vencimento existente', - 'Factor to calculate new due date: ' => 'Factor para calcular a nova data de vencimento: ', - 'Month(s)' => 'Mês(es)', - 'Recurrence' => 'Recorrência', - 'This task has been created by: ' => 'Esta tarefa foi criada por: ', - 'Recurrent task has been generated:' => 'A tarefa recorrente foi gerada:', - 'Timeframe to calculate new due date: ' => 'Escala de tempo para o cálculo da nova data de vencimento: ', - 'Trigger to generate recurrent task: ' => 'Activador para gerar tarefa recorrente: ', - 'When task is closed' => 'Quando a tarefa é fechada', - 'When task is moved from first column' => 'Quando a tarefa é movida fora da primeira coluna', - 'When task is moved to last column' => 'Quando a tarefa é movida para a última coluna', - 'Year(s)' => 'Ano(s)', - 'Calendar settings' => 'Configurações do calendário', - 'Project calendar view' => 'Vista em modo projecto do calendário', - 'Project settings' => 'Configurações dos projectos', - 'Show subtasks based on the time tracking' => 'Mostrar as subtarefas com base no controle de tempo', - 'Show tasks based on the creation date' => 'Mostrar as tarefas em função da data de criação', - 'Show tasks based on the start date' => 'Mostrar as tarefas em função da data de início', - 'Subtasks time tracking' => 'Monitoramento do tempo comparado as subtarefas', - 'User calendar view' => 'Vista em modo utilizador do calendário', - 'Automatically update the start date' => 'Actualizar automaticamente a data de início', - 'iCal feed' => 'Subscrição iCal', - 'Preferences' => 'Preferências', - 'Security' => 'Segurança', - 'Two factor authentication disabled' => 'Autenticação com factor duplo desactivado', - 'Two factor authentication enabled' => 'Autenticação com factor duplo activado', - 'Unable to update this user.' => 'Impossível de actualizar este utilizador.', - 'There is no user management for private projects.' => 'Não há gestão de utilizadores para projectos privados.', - 'User that will receive the email' => 'O utilizador que vai receber o e-mail', - 'Email subject' => 'Assunto do e-mail', - 'Date' => 'Data', - 'Add a comment log when moving the task between columns' => 'Adicionar um comentário de log quando uma tarefa é movida para uma outra coluna', - 'Move the task to another column when the category is changed' => 'Mover uma tarefa para outra coluna quando a categoria mudar', - 'Send a task by email to someone' => 'Enviar uma tarefa por e-mail a alguém', - 'Reopen a task' => 'Reabrir uma tarefa', - 'Column change' => 'Mudança de coluna', - 'Position change' => 'Mudança de posição', - 'Swimlane change' => 'Mudança de swimlane', - 'Assignee change' => 'Mudança de assignação', - '[%s] Overdue tasks' => '[%s] Tarefas atrasadas', - 'Notification' => 'Notificação', - '%s moved the task #%d to the first swimlane' => '%s moveu a tarefa n° %d no primeiro swimlane', - '%s moved the task #%d to the swimlane "%s"' => '%s moveu a tarefa n° %d no swimlane "%s"', - 'Swimlane' => 'Swimlane', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s moveu a tarefa %s no primeiro swimlane', - '%s moved the task %s to the swimlane "%s"' => '%s moveu a tarefa %s no swimlane "%s"', - 'This report contains all subtasks information for the given date range.' => 'Este relatório contém informações de todas as sub-tarefas para o período selecionado.', - 'This report contains all tasks information for the given date range.' => 'Este relatório contém informações de todas as tarefas para o período selecionado.', - 'Project activities for %s' => 'Actividade do projecto "%s"', - 'view the board on Kanboard' => 'ver o painel no Kanboard', - 'The task have been moved to the first swimlane' => 'A tarefa foi movida para o primeiro Swimlane', - 'The task have been moved to another swimlane:' => 'A tarefa foi movida para outro Swimlane:', - 'New title: %s' => 'Novo título: %s', - 'The task is not assigned anymore' => 'Tarefa já não está atribuída', - 'New assignee: %s' => 'Novo assignado: %s', - 'There is no category now' => 'Já não existe categoria', - 'New category: %s' => 'Nova categoria: %s', - 'New color: %s' => 'Nova cor: %s', - 'New complexity: %d' => 'Nova complexidade: %d', - 'The due date have been removed' => 'A data de vencimento foi retirada', - 'There is no description anymore' => 'Já não há descrição', - 'Recurrence settings have been modified' => 'As configurações da recorrência foram modificadas', - 'Time spent changed: %sh' => 'O tempo despendido foi mudado: %sh', - 'Time estimated changed: %sh' => 'O tempo estimado foi mudado/ %sh', - 'The field "%s" have been updated' => 'O campo "%s" foi actualizada', - 'The description has been modified:' => 'A descrição foi modificada', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Tem a certeza que quer fechar a tarefa "%s" e todas as suas sub-tarefas?', - 'I want to receive notifications for:' => 'Eu quero receber as notificações para:', - 'All tasks' => 'Todas as tarefas', - 'Only for tasks assigned to me' => 'Somente as tarefas atribuídas a mim', - 'Only for tasks created by me' => 'Apenas as tarefas que eu criei', - 'Only for tasks created by me and assigned to me' => 'Apenas as tarefas que eu criei e aquelas atribuídas a mim', - '%%Y-%%m-%%d' => '%%d/%%m/%%Y', - 'Total for all columns' => 'Total para todas as colunas', - 'You need at least 2 days of data to show the chart.' => 'Precisa de pelo menos 2 dias de dados para visualizar o gráfico.', - '<15m' => '<15m', - '<30m' => '<30m', - 'Stop timer' => 'Parar temporizador', - 'Start timer' => 'Iniciar temporizador', - 'Add project member' => 'Adicionar um membro ao projecto', - 'My activity stream' => 'O meu feed de actividade', - 'My calendar' => 'A minha agenda', - 'Search tasks' => 'Pesquisar tarefas', - 'Reset filters' => 'Redefinir os filtros', - 'My tasks due tomorrow' => 'A minhas tarefas que expiram amanhã', - 'Tasks due today' => 'Tarefas que expiram hoje', - 'Tasks due tomorrow' => 'Tarefas que expiram amanhã', - 'Tasks due yesterday' => 'Tarefas que expiraram ontem', - 'Closed tasks' => 'Tarefas fechadas', - 'Open tasks' => 'Tarefas abertas', - 'Not assigned' => 'Não assignada', - 'View advanced search syntax' => 'Ver sintaxe avançada de pesquisa', - 'Overview' => 'Visão global', - 'Board/Calendar/List view' => 'Vista Painel/Calendário/Lista', - 'Switch to the board view' => 'Mudar para o modo Painel', - 'Switch to the calendar view' => 'Mudar para o modo Calendário', - 'Switch to the list view' => 'Mudar para o modo Lista', - 'Go to the search/filter box' => 'Ir para o campo de pesquisa', - 'There is no activity yet.' => 'Ainda não há nenhuma actividade.', - 'No tasks found.' => 'Nenhuma tarefa encontrada', - 'Keyboard shortcut: "%s"' => 'Tecla de atalho: "%s"', - 'List' => 'Lista', - 'Filter' => 'Filtro', - 'Advanced search' => 'Pesquisa avançada', - 'Example of query: ' => 'Exemplo de consulta: ', - 'Search by project: ' => 'Pesquisar por projecto: ', - 'Search by column: ' => 'Pesquisar por coluna: ', - 'Search by assignee: ' => 'Pesquisar por assignado: ', - 'Search by color: ' => 'Pesquisar por cor: ', - 'Search by category: ' => 'Pesquisar por categoria: ', - 'Search by description: ' => 'Pesquisar por descrição: ', - 'Search by due date: ' => 'Pesquisar por data de vencimento: ', - 'Lead and Cycle time for "%s"' => 'Tempo de Espera e Ciclo para "%s"', - 'Average time spent into each column for "%s"' => 'Tempo médio gasto em cada coluna para "%s"', - 'Average time spent into each column' => 'Tempo médio gasto em cada coluna', - 'Average time spent' => 'Tempo médio gasto', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Este gráfico mostra o tempo médio gasto em cada coluna nas últimas %d tarefas.', - 'Average Lead and Cycle time' => 'Tempo de Espera e Ciclo médio', - 'Average lead time: ' => 'Tempo médio de Espera: ', - 'Average cycle time: ' => 'Tempo médio de Ciclo: ', - 'Cycle Time' => 'Tempo de Ciclo', - 'Lead Time' => 'Tempo de Espera', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Este gráfico mostra o tempo médio de espera e ciclo para as últimas %d tarefas realizadas.', - 'Average time into each column' => 'Tempo médio em cada coluna', - 'Lead and cycle time' => 'Tempo de Espera e Ciclo', - 'Lead time: ' => 'Tempo de Espera: ', - 'Cycle time: ' => 'Tempo de Ciclo: ', - 'Time spent into each column' => 'Tempo gasto em cada coluna', - 'The lead time is the duration between the task creation and the completion.' => 'O tempo de espera é a duração entre a criação e o fim da tarefa', - 'The cycle time is the duration between the start date and the completion.' => 'O tempo de ciclo é a duração entre a data de inicio e o fim da tarefa', - 'If the task is not closed the current time is used instead of the completion date.' => 'Se a tarefa não estiver fechada o hora actual será usada em vez da hora de conclusão', - 'Set automatically the start date' => 'Definir data de inicio automáticamente', - 'Edit Authentication' => 'Editar Autenticação', - '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á projecto de destino disponivel', - 'Trigger automatically subtask time tracking' => 'Activar automáticamente subtarefa de controlo de tempo', - 'Include closed tasks in the cumulative flow diagram' => 'Incluir tarefas fechadas no diagrama de fluxo acumulado', - 'Current swimlane: %s' => 'Swimlane actual: %s', - 'Current column: %s' => 'Coluna actual: %s', - 'Current category: %s' => 'Categoria actual: %s', - 'no category' => 'sem categoria', - 'Current assignee: %s' => 'Assignado a: %s', - 'not assigned' => 'não assignado', - 'Author:' => 'Autor:', - 'contributors' => 'contribuidores', - 'License:' => 'Licença:', - 'License' => 'Licença', - 'Enter the text below' => 'Escreva o texto em baixo', - 'Gantt chart for %s' => 'Gráfico de Gantt para %s', - 'Sort by position' => 'Ordenar por posição', - 'Sort by date' => 'Ordenar por data', - 'Add task' => 'Adicionar tarefa', - 'Start date:' => 'Data de inicio:', - 'Due date:' => 'Data de vencimento:', - 'There is no start date or due date for this task.' => 'Não existe data de inicio ou data de vencimento para esta tarefa.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Mover ou redimensionar a tarefa irá alterar a data de inicio e vencimento da tarefa.', - 'There is no task in your project.' => 'Não existe tarefa no seu projecto.', - 'Gantt chart' => 'Gráfico de Gantt', - 'People who are project managers' => 'Pessoas que são gestores do projecto', - 'People who are project members' => 'Pessoas que são membros do projecto', - 'NOK - Norwegian Krone' => 'NOK - Coroa Norueguesa', - 'Show this column' => 'Mostrar esta coluna', - 'Hide this column' => 'Esconder esta coluna', - 'open file' => 'abrir ficheiro', - 'End date' => 'Data de fim', - 'Users overview' => 'Visão geral de Utilizadores', - 'Members' => 'Membros', - 'Shared project' => 'Projecto partilhado', - 'Project managers' => 'Gestores do projecto', - 'Gantt chart for all projects' => 'Gráfico de Gantt para todos os projectos', - 'Projects list' => 'Lista de projectos', - 'Gantt chart for this project' => 'Gráfico de Gantt para este projecto', - 'Project board' => 'Quadro de projecto', - 'End date:' => 'Data de fim:', - 'There is no start date or end date for this project.' => 'Não existe data de inicio ou fim para este projecto.', - 'Projects Gantt chart' => 'Gráfico de Gantt dos projectos', - 'Change task color when using a specific task link' => 'Alterar cor da tarefa quando se usar um tipo especifico de ligação de tarefa', - 'Task link creation or modification' => 'Criação ou modificação de ligação de tarefa', - 'Milestone' => 'Objectivo', - 'Documentation: %s' => 'Documentação: %s', - 'Switch to the Gantt chart view' => 'Mudar para vista de gráfico de Gantt', - 'Reset the search/filter box' => 'Repor caixa de procura/filtro', - 'Documentation' => 'Documentação', - 'Table of contents' => 'Tabela de conteúdos', - 'Gantt' => 'Gantt', - 'Author' => 'Autor', - 'Version' => 'Versão', - 'Plugins' => 'Plugins', - 'There is no plugin loaded.' => 'Não existem extras carregados', - 'Set maximum column height' => 'Definir altura máxima da coluna', - 'Remove maximum column height' => 'Remover altura máxima da coluna', - 'My notifications' => 'As minhas notificações', - 'Custom filters' => 'Filtros personalizados', - 'Your custom filter have been created successfully.' => 'O seu filtro personalizado foi criado com sucesso.', - 'Unable to create your custom filter.' => 'Não foi possivel criar o seu filtro personalizado.', - 'Custom filter removed successfully.' => 'Filtro personalizado removido com sucesso.', - 'Unable to remove this custom filter.' => 'Não foi possivel remover este filtro personalizado.', - 'Edit custom filter' => 'Editar filtro personalizado', - 'Your custom filter have been updated successfully.' => 'O seu filtro personalizado foi actualizado com sucesso.', - 'Unable to update custom filter.' => 'Não foi possivel actualizar o filtro personalizado.', - 'Web' => 'Web', - 'New attachment on task #%d: %s' => 'Novo anexo na tarefa #%d: %s', - 'New comment on task #%d' => 'Novo comentário na tarefa #%d', - 'Comment updated on task #%d' => 'Comentário actualizado na tarefa #%d', - 'New subtask on task #%d' => 'Nova sub-tarefa na tarefa #%d', - 'Subtask updated on task #%d' => 'Sub-tarefa actualizada na tarefa #%d', - 'New task #%d: %s' => 'Nova tarefa #%d: %s', - 'Task updated #%d' => 'Tarefa actualizada #%d', - 'Task #%d closed' => 'Tarefa #%d fechada', - 'Task #%d opened' => 'Tarefa #%d aberta', - 'Column changed for task #%d' => 'Coluna alterada para tarefa #%d', - 'New position for task #%d' => 'Nova posição para tarefa #%d', - 'Swimlane changed for task #%d' => 'Swimlane alterado na tarefa #%d', - 'Assignee changed on task #%d' => 'Assignado alterado na tarefa #%d', - '%d overdue tasks' => '%d tarefas em atraso', - 'Task #%d is overdue' => 'Tarefa #%d está em atraso', - 'No new notifications.' => 'Sem novas notificações.', - 'Mark all as read' => 'Marcar tudo como lido', - 'Mark as read' => 'Marcar como lido', - 'Total number of tasks in this column across all swimlanes' => 'Número total de tarefas nesta coluna em todas as swimlanes', - 'Collapse swimlane' => 'Colapsar swimlane', - 'Expand swimlane' => 'Expandir swimlane', - 'Add a new filter' => 'Adicionar um novo filtro', - 'Share with all project members' => 'Partilhar com todos os membros do projecto', - 'Shared' => 'Partilhado', - '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', - 'Import users from CSV file' => 'Importar utilizadores de um ficheiro CSV', - '%d user(s) have been imported successfully.' => '%d utilizadore(s) importados com successo.', - 'Comma' => 'Vírgula', - 'Semi-colon' => 'Ponto e Vírgula', - 'Tab' => 'Tabulação', - 'Vertical bar' => 'Barra vertical', - 'Double Quote' => 'Aspas', - 'Single Quote' => 'Plica', - '%s attached a file to the task #%d' => '%s anexou um ficheiro à tarefa #%d', - 'There is no column or swimlane activated in your project!' => 'Não existe nenhuma coluna ou swimlane activado no seu projecto!', - 'Append filter (instead of replacement)' => 'Acrescentar filtro (em vez de substituir)', - 'Append/Replace' => 'Acrescentar/Substituir', - 'Append' => 'Acrescentar', - 'Replace' => 'Substituir', - 'Import' => 'Importar', - 'change sorting' => 'alterar ordernação', - 'Tasks Importation' => 'Importação de Tarefas', - 'Delimiter' => 'Delimitador', - 'Enclosure' => 'Clausura', - 'CSV File' => 'Ficheiro CSV', - 'Instructions' => 'Instruções', - 'Your file must use the predefined CSV format' => 'O seu ficheiro tem de usar um formato CSV pre-definido', - 'Your file must be encoded in UTF-8' => 'O seu ficheiro tem de estar codificado como UTF-8', - 'The first row must be the header' => 'A primeira linha tem de ser o cabeçalho', - 'Duplicates are not verified for you' => 'Duplicados não são verificados por si', - 'The due date must use the ISO format: YYYY-MM-DD' => 'A data de expiração tem de estar no formato ISO: AAAA-MM-DD', - 'Download CSV template' => 'Descarregar template CSV', - 'No external integration registered.' => 'Nenhuma integração externa registrada.', - 'Duplicates are not imported' => 'Duplicados não são importados', - 'Usernames must be lowercase and unique' => 'Utilizadores tem de estar em letra pequena e ser unicos', - 'Passwords will be encrypted if present' => 'Senhas serão encriptadas se presentes', - '%s attached a new file to the task %s' => '%s anexou um novo ficheiro à tarefa %s', - 'Link type' => 'Tipo de ligação', - 'Assign automatically a category based on a link' => 'Assignar automáticamente a categoria baseada num link', - 'BAM - Konvertible Mark' => 'BAM - Marca Conversível', - 'Assignee Username' => 'Utilizador do Assignado', - 'Assignee Name' => 'Nome do Assignado', - 'Groups' => 'Grupos', - 'Members of %s' => 'Membros de %s', - 'New group' => 'Novo grupo', - 'Group created successfully.' => 'Grupo criado com sucesso.', - 'Unable to create your group.' => 'Não foi possivel criar o seu grupo.', - 'Edit group' => 'Editar grupo', - 'Group updated successfully.' => 'Grupo actualizado com sucesso.', - 'Unable to update your group.' => 'Não foi possivel actualizar o seu grupo.', - 'Add group member to "%s"' => 'Adicionar membro do grupo a "%s"', - 'Group member added successfully.' => 'Membro de grupo adicionado com sucesso.', - 'Unable to add group member.' => 'Não foi possivel adicionar membro de grupo.', - 'Remove user from group "%s"' => 'Remover utilizador do grupo "%s"', - 'User removed successfully from this group.' => 'Utilizador removido com sucesso deste grupo.', - 'Unable to remove this user from the group.' => 'Não foi possivel remover este utilizador do grupo.', - 'Remove group' => 'Remover grupo.', - 'Group removed successfully.' => 'Grupo removido com sucesso.', - 'Unable to remove this group.' => 'Não foi possivel remover este grupo.', - 'Project Permissions' => 'Permissões de Projecto', - 'Manager' => 'Gestor', - 'Project Manager' => 'Gestor de Projecto', - 'Project Member' => 'Membro de Projecto', - 'Project Viewer' => 'Visualizador de Projecto', - 'Your account is locked for %d minutes' => 'A sua conta está bloqueada por %d minutos', - 'Invalid captcha' => 'Captcha inválido', - 'The name must be unique' => 'O nome deve ser único', - 'View all groups' => 'Ver todos os grupos', - 'View group members' => 'Ver membros do grupo', - 'There is no user available.' => 'Não existe utilizador disponivel.', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Tem a certeza que quer remover o utilizador "%s" do grupo "%s"?', - 'There is no group.' => 'Não existe grupo.', - 'External Id' => 'Id externo', - 'Add group member' => 'Adicionar membro de grupo', - 'Do you really want to remove this group: "%s"?' => 'Tem a certeza que quer remover este grupo: "%s"?', - 'There is no user in this group.' => 'Não existe utilizadores neste grupo.', - 'Remove this user' => 'Remover este utilizador', - 'Permissions' => 'Permissões', - 'Allowed Users' => 'Utilizadores Permitidos', - 'No user have been allowed specifically.' => 'Nenhum utilizador foi especificamente permitido.', - 'Role' => 'Função', - 'Enter user name...' => 'Escreva o nome do utilizador...', - 'Allowed Groups' => 'Grupos Permitidos', - 'No group have been allowed specifically.' => 'Nenhum grupo foi especificamente permitido.', - 'Group' => 'Grupo', - 'Group Name' => 'Nome do Grupo', - 'Enter group name...' => 'Escreva o nome do Grupo', - 'Role:' => 'Função:', - 'Project members' => 'Membros do projecto', - 'Compare hours for "%s"' => 'Comparar horas para "%s"', - '%s mentioned you in the task #%d' => '%s mencionou-te na tarefa #%d', - '%s mentioned you in a comment on the task #%d' => '%s mencionou-te num comentário na tarefa #%d', - 'You were mentioned in the task #%d' => 'Foi mencionado na tarefa #%d', - 'You were mentioned in a comment on the task #%d' => 'Foi mencionado num comentário na tarefa #%d', - 'Mentioned' => 'Mencionado', - 'Compare Estimated Time vs Actual Time' => 'Comparar Tempo Estimado vs Tempo Real', - 'Estimated hours: ' => 'Horas estimadas: ', - 'Actual hours: ' => 'Horas reais: ', - 'Hours Spent' => 'Horas Gastas', - 'Hours Estimated' => 'Horas Estimadas', - 'Estimated Time' => 'Tempo Estimado', - 'Actual Time' => 'Tempo Real', - 'Estimated vs actual time' => 'Tempo estimado vs real', - 'RUB - Russian Ruble' => 'RUB - Rublo Russo', - 'Assign the task to the person who does the action when the column is changed' => 'Assignar a tarefa à pessoa que realiza a acção quando a coluna é alterada', - 'Close a task in a specific column' => 'Fechar tarefa numa coluna especifica', - 'Time-based One-time Password Algorithm' => 'Algoritmo de password para uso único baseado em tempo', - 'Two-Factor Provider: ' => 'Provedor de Dois Passos: ', - 'Disable two-factor authentication' => 'Desactivar autenticação de dois passos', - 'Enable two-factor authentication' => 'Activar autenticação de dois passos', - 'There is no integration registered at the moment.' => 'Não existe nenhuma integração registrada até ao momento.', - 'Password Reset for Kanboard' => 'Redefinir Password para Kanboard', - 'Forgot password?' => 'Esqueceu a password?', - 'Enable "Forget Password"' => 'Activar "Esqueceu a password"', - 'Password Reset' => 'Redefinir a Password', - 'New password' => 'Nova Password', - 'Change Password' => 'Alterar Password', - 'To reset your password click on this link:' => 'Para redefinir a sua password click nesta ligação:', - 'Last Password Reset' => 'Última Redefinição da Password', - 'The password has never been reinitialized.' => 'A password nunca foi redefinida.', - 'Creation' => 'Criação', - 'Expiration' => 'Expiração', - 'Password reset history' => 'Histórico da redefinição da password', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Todas as tarefas na coluna "%s" e na swimlane "%s" foram fechadas com successo.', - 'Do you really want to close all tasks of this column?' => 'Tem a certeza que quer fechar todas as tarefas nesta coluna?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d tarefa(s) na coluna "%s" e na swimlane "%s" serão fechadas.', - 'Close all tasks of this column' => 'Fechar todas as tarefas nesta coluna', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Nenhum plugin tem registado um método de notificação do projecto. Pode continuar a configurar notificações individuais no seu perfil de utilizador.', - 'My dashboard' => 'Meu painel', - 'My profile' => 'Meu perfil', - 'Project owner: ' => 'Dono do projecto: ', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'O identificador do projecto é opcional e tem de ser alfa-numerico, exemplo: MEUPROJECTO.', - 'Project owner' => 'Dono do projecto', - 'Those dates are useful for the project Gantt chart.' => 'Estas datas são uteis para o gráfico de Grantt do projecto.', - 'Private projects do not have users and groups management.' => 'Projectos privados não têm gestão de utilizadores nem de grupos.', - 'There is no project member.' => 'Não existe membro do projecto.', - 'Priority' => 'Prioridade', - 'Task priority' => 'Prioridade da Tarefa', - 'General' => 'Geral', - 'Dates' => 'Datas', - 'Default priority' => 'Prioridade por defeito', - 'Lowest priority' => 'Prioridade mais baixa', - 'Highest priority' => 'Prioridade mais alta', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Se colocar zero na prioridade baixa ou alta, essa funcionalidade será desactivada.', - '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', - 'Unable to fetch link information.' => 'Impossivel obter informação da ligação.', - 'Daily background job for tasks' => 'Trabalho diário em segundo plano para tarefas', - 'Auto' => 'Auto', - 'Related' => 'Relacionado', - 'Attachment' => 'Anexo', - 'Title not found' => 'Titulo não encontrado', - 'Web Link' => 'Ligação Web', - 'External links' => 'Ligações externas', - 'Add external link' => 'Adicionar ligação externa', - 'Type' => 'Tipo', - 'Dependency' => 'Dependencia', - 'Add internal link' => 'Adicionar ligação interna', - 'Add a new external link' => 'Adicionar nova ligação externa', - 'Edit external link' => 'Editar ligação externa', - 'External link' => 'Ligação externa', - 'Copy and paste your link here...' => 'Copie e cole a sua ligação aqui...', - 'URL' => 'URL', - 'Internal links' => 'Ligações internas', - 'Assign to me' => 'Assignar a mim', - 'Me' => 'Eu', - 'Do not duplicate anything' => 'Não duplicar nada', - 'Projects management' => 'Gestão de projectos', - 'Users management' => 'Gestão de utilizadores', - 'Groups management' => 'Gestão de grupos', - 'Create from another project' => 'Criar apartir de outro projecto', - 'open' => 'aberto', - 'closed' => 'fechado', - 'Priority:' => 'Prioridade:', - 'Reference:' => 'Referência:', - 'Complexity:' => 'Complexidade:', - 'Swimlane:' => 'Swimlane:', - 'Column:' => 'Coluna:', - 'Position:' => 'Posição:', - 'Creator:' => 'Criador:', - 'Time estimated:' => 'Tempo estimado:', - '%s hours' => '%s horas', - 'Time spent:' => 'Tempo gasto:', - 'Created:' => 'Criado:', - 'Modified:' => 'Modificado:', - 'Completed:' => 'Completado:', - '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: ', - 'New due date: ' => 'Nova data estimada: ', - 'Start date changed: ' => 'Data inicio alterada: ', - 'Disable private projects' => 'Desactivar projectos privados', - 'Do you really want to remove this custom filter: "%s"?' => 'Tem a certeza que quer remover este filtro personalizado: "%s"?', - 'Remove a custom filter' => 'Remover o filtro personalizado', - 'User activated successfully.' => 'Utilizador activado com sucesso.', - 'Unable to enable this user.' => 'Não foi possivel activar este utilizador.', - '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', - 'Two Factor' => 'Dois Factores', - 'Disable user' => 'Desactivar utilizador', - 'Do you really want to disable this user: "%s"?' => 'Tem a certeza que quer desactivar este utilizador: "%s"?', - 'Enable user' => 'Activar utilizador', - 'Do you really want to enable this user: "%s"?' => 'Tem a certeza que quer activar este utilizador: "%s"?', - 'Download' => 'Transferir', - 'Uploaded: %s' => 'Enviado: %s', - 'Size: %s' => 'Tamanho: %s', - 'Uploaded by %s' => 'Enviado por %s', - 'Filename' => 'Nome do ficheiro', - 'Size' => 'Tamanho', - 'Column created successfully.' => 'Coluna criada com sucesso.', - 'Another column with the same name exists in the project' => 'Já existe outra coluna com o mesmo nome no projecto', - 'Default filters' => 'Filtros padrão', - 'Your board doesn\'t have any columns!' => 'O seu quadro não tem nenhuma coluna!', - 'Change column position' => 'Mudar posição da coluna', - 'Switch to the project overview' => 'Mudar para vista geral do projecto', - 'User filters' => 'Filtros de utilizador', - 'Category filters' => 'Filtros de categoria', - 'Upload a file' => 'Enviar um ficheiro', - 'View file' => 'Ver ficheiro', - 'Last activity' => 'Ultima actividade', - 'Change subtask position' => 'Mudar posição da sub-tarefa', - 'This value must be greater than %d' => 'Este valor tem de ser maior que %d', - 'Another swimlane with the same name exists in the project' => 'Já existe outra swimlane com o mesmo nome no projecto', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Exemplo: http://example.kanboard.net/ (usado para gerar URLs absolutos)', - 'Actions duplicated successfully.' => 'Acções duplicadas com sucesso.', - 'Unable to duplicate actions.' => 'Não foi possivel duplicar acções.', - 'Add a new action' => 'Adicionar nova acção', - 'Import from another project' => 'Importar de outro projecto', - 'There is no action at the moment.' => 'De momento não existe acção.', - 'Import actions from another project' => 'Importar acções de outro projecto', - 'There is no available project.' => 'Não existe projecto disponivel.', - 'Local File' => 'Ficheiro Local', - 'Configuration' => 'Configuração', - 'PHP version:' => 'Versão PHP:', - 'PHP SAPI:' => 'SAPI PHP:', - 'OS version:' => 'Versão SO:', - 'Database version:' => 'Versão base de dados:', - 'Browser:' => 'Navegador:', - 'Task view' => 'Vista de Tarefas', - 'Edit task' => 'Editar tarefa', - 'Edit description' => 'Editar descrição', - 'New internal link' => 'Nova ligação interna', - 'Display list of keyboard shortcuts' => 'Mostrar lista de atalhos do teclado', - 'Menu' => 'Menu', - 'Set start date' => 'Definir data de inicio', - 'Avatar' => 'Avatar', - 'Upload my avatar image' => 'Enviar a minha imagem de avatar', - 'Remove my image' => 'Remover a minha imagem', - 'The OAuth2 state parameter is invalid' => 'O parametro de estado do OAuth2 é inválido', - 'User not found.' => 'Utilizador não encontrado.', - 'Search in activity stream' => 'Procurar no fluxo de atividade', - 'My activities' => 'Minhas actividades', - 'Activity until yesterday' => 'Actividade até ontem', - 'Activity until today' => 'Actividade até hoje', - 'Search by creator: ' => 'Procurar por criador: ', - 'Search by creation date: ' => 'Procurar por data de criação: ', - 'Search by task status: ' => 'Procurar por estado da tarefa: ', - 'Search by task title: ' => 'Procurar por titulo da tarefa: ', - 'Activity stream search' => 'Procurar fluxo de actividade', - 'Projects where "%s" is manager' => 'Projectos onde "%s" é gestor', - 'Projects where "%s" is member' => 'Projectos onde "%s" é membro', - 'Open tasks assigned to "%s"' => 'Tarefas abertas assignadas a "%s"', - 'Closed tasks assigned to "%s"' => 'Tarefas fechadas assignadas a "%s"', - 'Assign automatically a color based on a priority' => 'Assignar uma cor automáticamente de acordo com a prioridade', - 'Overdue tasks for the project(s) "%s"' => 'Tarefas em atraso para o(s) projecto(s) "%s"', - 'Upload files' => 'Enviar ficheiros', - 'Installed Plugins' => 'Plugins Instalados', - 'Plugin Directory' => 'Directoria de Plugins', - 'Plugin installed successfully.' => 'Plugin instalado com sucesso.', - 'Plugin updated successfully.' => 'Plugin actualizado com sucesso.', - 'Plugin removed successfully.' => 'Plugin removido com sucesso.', - 'Subtask converted to task successfully.' => 'Sub-tarefa convertida para tarefa com sucesso.', - 'Unable to convert the subtask.' => 'Não foi possivel converter a sub-tarefa.', - 'Unable to extract plugin archive.' => 'Não foi possivel extrair arquivo do plugin.', - 'Plugin not found.' => 'Plugin não encontrado.', - 'You don\'t have the permission to remove this plugin.' => 'Não tem acesso para remover este plugin.', - 'Unable to download plugin archive.' => 'Não foi possivel transferir o arquivo do plugin.', - 'Unable to write temporary file for plugin.' => 'Não foi possivel escrever o ficheiro temporário para o plugin.', - 'Unable to open plugin archive.' => 'Não foi possivel abrir o arquivo do plugin.', - 'There is no file in the plugin archive.' => 'Ficheiro não encontrado dentro do arquivo do plugin.', - 'Create tasks in bulk' => 'Criar tarefas em massa', - 'Your Kanboard instance is not configured to install plugins from the user interface.' => 'Este Kanboard não está configurado para instalar plugins através do interface de utilizador.', - 'There is no plugin available.' => 'Não existe nenhum plugin instalado.', - 'Install' => 'Instalar', - 'Update' => 'Actualizar', - 'Up to date' => 'Actualizado', - 'Not available' => 'Não disponivel', - 'Remove plugin' => 'Remover plugin', - 'Do you really want to remove this plugin: "%s"?' => 'Tem a certeza que pretende remover este plugin: "%s%"?', - 'Uninstall' => 'Desinstalar', - 'Listing' => 'A Listar', - 'Metadata' => 'Metadata', - 'Manage projects' => 'Gerir projectos', - 'Convert to task' => 'Converter para tarefa', - 'Convert sub-task to task' => 'Converter sub-tarefa para tarefa', - 'Do you really want to convert this sub-task to a task?' => 'Tem a certeza que pretende converter esta sub-tarefa para tarefa?', - 'My task title' => 'Titulo da minha tarefa', - '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', - 'Webhook token' => 'Token do Webhook', - 'Imports' => 'Importados', - 'Project tags management' => 'Gestão de etiquetas do Projecto', - 'Tag created successfully.' => 'Etiqueta criada com sucesso.', - 'Unable to create this tag.' => 'Não foi possivel criar esta etiqueta.', - 'Tag updated successfully.' => 'Etiqueta actualizada com sucesso.', - 'Unable to update this tag.' => 'Não foi possivel actualizar esta etiqueta.', - 'Tag removed successfully.' => 'Etiqueta removida com sucesso.', - 'Unable to remove this tag.' => 'Não foi possivel remover esta etiqueta.', - 'Global tags management' => 'Gestão de etiquetas globais', - 'Tags' => 'Etiquetas', - 'Tags management' => 'Gestão de Etiquetas', - 'Add new tag' => 'Adicionar etiqueta nova', - 'Edit a tag' => 'Editar a etiqueta', - 'Project tags' => 'Etiquetas do Projecto', - 'There is no specific tag for this project at the moment.' => 'De momento não existe nenhuma etiqueta para este projecto.', - 'Tag' => 'Etiqueta', - 'Remove a tag' => 'Remover etiqueta', - 'Do you really want to remove this tag: "%s"?' => 'Tem a certeza que pretende remover esta etiqueta: "%s"?', - 'Global tags' => 'Etiquetas globais', - 'There is no global tag at the moment.' => 'De momento não existe nenhuma etiqueta global.', - // 'This field cannot be empty' => '', -); diff --git a/sources/app/Locale/ru_RU/translations.php b/sources/app/Locale/ru_RU/translations.php deleted file mode 100644 index 3b5e09d..0000000 --- a/sources/app/Locale/ru_RU/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => 'Отсутствует', - 'edit' => 'изменить', - 'Edit' => 'Изменить', - 'remove' => 'удалить', - 'Remove' => 'Удалить', - 'Yes' => 'Да', - 'No' => 'Нет', - 'cancel' => 'Отменить', - 'or' => 'или', - 'Yellow' => 'Желтый', - 'Blue' => 'Синий', - 'Green' => 'Зеленый', - 'Purple' => 'Фиолетовый', - 'Red' => 'Красный', - 'Orange' => 'Оранжевый', - 'Grey' => 'Серый', - 'Brown' => 'Коричневый', - 'Deep Orange' => 'Темно-оранжевый', - 'Dark Grey' => 'Темно-серый', - 'Pink' => 'Розовый', - 'Teal' => 'Бирюзовый', - 'Cyan' => 'Голубой', - 'Lime' => 'Лимонный', - 'Light Green' => 'Светло-зеленый', - 'Amber' => 'Янтарный', - 'Save' => 'Сохранить', - 'Login' => 'Вход', - 'Official website:' => 'Официальный сайт:', - 'Unassigned' => 'Не назначена', - 'View this task' => 'Посмотреть задачу', - 'Remove user' => 'Удалить пользователя', - 'Do you really want to remove this user: "%s"?' => 'Вы точно хотите удалить пользователя: « %s » ?', - 'All users' => 'Все пользователи', - 'Username' => 'Имя пользователя', - 'Password' => 'Пароль', - 'Administrator' => 'Администратор', - 'Sign in' => 'Войти', - 'Users' => 'Пользователи', - 'No user' => 'Нет пользователя', - 'Forbidden' => 'Запрещено', - 'Access Forbidden' => 'Доступ запрещен', - 'Edit user' => 'Изменить пользователя', - 'Logout' => 'Выйти', - 'Bad username or password' => 'Неверное имя пользователя или пароль', - 'Edit project' => 'Изменить проект', - 'Name' => 'Имя', - 'Projects' => 'Проекты', - 'No project' => 'Нет проекта', - 'Project' => 'Проект', - 'Status' => 'Статус', - 'Tasks' => 'Задачи', - 'Board' => 'Доска', - 'Actions' => 'Действия', - 'Inactive' => 'Неактивен', - 'Active' => 'Активен', - '%d tasks on the board' => '%d задач на доске', - '%d tasks in total' => 'всего %d задач', - 'Unable to update this board.' => 'Не удалось обновить эту доску.', - 'Edit board' => 'Изменить доску', - 'Disable' => 'Выключить', - 'Enable' => 'Включить', - 'New project' => 'Новый проект', - 'Do you really want to remove this project: "%s"?' => 'Вы точно хотите удалить проект: "%s"?', - 'Remove project' => 'Удалить проект', - 'Edit the board for "%s"' => 'Изменить доску для "%s"', - 'All projects' => 'Все проекты', - 'Add a new column' => 'Добавить новую колонку', - 'Title' => 'Название', - 'Assigned to %s' => 'Назначено %s', - 'Remove a column' => 'Удалить колонку', - 'Remove a column from a board' => 'Удалить колонку с доски', - 'Unable to remove this column.' => 'Не удалось удалить эту колонку.', - 'Do you really want to remove this column: "%s"?' => 'Вы точно хотите удалить эту колонку: "%s" ?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'Вы УДАЛИТЕ ВСЕ ЗАДАЧИ находящиеся в этой колонке!', - 'Settings' => 'Настройки', - 'Application settings' => 'Настройки приложения', - 'Language' => 'Язык', - 'Webhook token:' => 'Webhooks токен :', - 'API token:' => 'API токен :', - 'Database size:' => 'Размер базы данных :', - 'Download the database' => 'Скачать базу данных', - 'Optimize the database' => 'Оптимизировать базу данных', - '(VACUUM command)' => '(Команда VACUUM)', - '(Gzip compressed Sqlite file)' => '(Сжать GZip файл SQLite)', - 'Close a task' => 'Закрыть задачу', - 'Edit a task' => 'Изменить задачу', - 'Column' => 'Колонка', - 'Color' => 'Цвет', - 'Assignee' => 'Назначена', - 'Create another task' => 'Создать другую задачу', - 'New task' => 'Новая задача', - 'Open a task' => 'Открыть задачу', - 'Do you really want to open this task: "%s"?' => 'Вы уверены что хотите открыть задачу: "%s" ?', - 'Back to the board' => 'Вернуться на доску', - 'There is nobody assigned' => 'Никто не назначен', - 'Column on the board:' => 'Колонка на доске: ', - 'Close this task' => 'Закрыть задачу', - 'Open this task' => 'Открыть задачу', - 'There is no description.' => 'Нет описания.', - 'Add a new task' => 'Добавить новую задачу', - 'The username is required' => 'Необходимо имя пользователя', - 'The maximum length is %d characters' => 'Максимальная длина - %d знаков', - 'The minimum length is %d characters' => 'Минимальная длина - %d знаков', - 'The password is required' => 'Необходим пароль', - 'This value must be an integer' => 'Это значение должно быть целым числом', - 'The username must be unique' => 'Имя пользователя должно быть уникально', - 'The user id is required' => 'Необходим ID пользователя', - 'Passwords don\'t match' => 'Пароли не совпадают', - 'The confirmation is required' => 'Необходимо подтверждение', - 'The project is required' => 'Необходимо указать проект', - 'The id is required' => 'Необходим ID', - 'The project id is required' => 'Необходим ID проекта', - 'The project name is required' => 'Необходимо имя проекта', - 'The title is required' => 'Необходим заголовок', - 'Settings saved successfully.' => 'Параметры успешно сохранены.', - 'Unable to save your settings.' => 'Невозможно сохранить параметры.', - 'Database optimization done.' => 'База данных оптимизирована.', - 'Your project have been created successfully.' => 'Ваш проект успешно создан.', - 'Unable to create your project.' => 'Не удалось создать проект.', - 'Project updated successfully.' => 'Проект успешно обновлен.', - 'Unable to update this project.' => 'Не удалось обновить проект.', - 'Unable to remove this project.' => 'Не удалось удалить проект.', - 'Project removed successfully.' => 'Проект удален.', - 'Project activated successfully.' => 'Проект активирован.', - 'Unable to activate this project.' => 'Невозможно активировать проект.', - 'Project disabled successfully.' => 'Проект успешно деактивирован.', - 'Unable to disable this project.' => 'Не удалось деактивировать проект.', - 'Unable to open this task.' => 'Не удалось открыть задачу.', - 'Task opened successfully.' => 'Задача открыта.', - 'Unable to close this task.' => 'Не удалось закрыть задачу.', - 'Task closed successfully.' => 'Задача закрыта.', - 'Unable to update your task.' => 'Не удалось обновить задачу.', - 'Task updated successfully.' => 'Задача обновлена.', - 'Unable to create your task.' => 'Не удалось создать задачу.', - 'Task created successfully.' => 'Задача создана.', - 'User created successfully.' => 'Пользователь создан.', - 'Unable to create your user.' => 'Не удалось создать пользователя.', - 'User updated successfully.' => 'Пользователь обновлен.', - 'Unable to update your user.' => 'Не удалось обновить пользователя.', - 'User removed successfully.' => 'Пользователь удален.', - 'Unable to remove this user.' => 'Не удалось удалить пользователя.', - 'Board updated successfully.' => 'Доска успешно обновлена.', - 'Ready' => 'Готовые', - 'Backlog' => 'Ожидающие', - 'Work in progress' => 'В процессе', - 'Done' => 'Выполнено', - 'Application version:' => 'Версия приложения:', - 'Id' => 'ID', - '%d closed tasks' => '%d завершенных задач', - 'No task for this project' => 'Нет задач для этого проекта', - 'Public link' => 'Ссылка для просмотра', - 'Timezone' => 'Часовой пояс', - 'Sorry, I didn\'t find this information in my database!' => 'К сожалению, информация в базе данных не найдена !', - 'Page not found' => 'Страница не найдена', - 'Complexity' => 'Сложность', - 'Task limit' => 'Лимит задач', - 'Task count' => 'Количество задач', - 'User' => 'Пользователь', - 'Comments' => 'Комментарии', - 'Leave a comment' => 'Оставить комментарий', - 'Comment is required' => 'Нужен комментарий', - 'Leave a description' => 'Напишите описание', - 'Comment added successfully.' => 'Комментарий успешно добавлен.', - 'Unable to create your comment.' => 'Невозможно создать комментарий.', - 'Due Date' => 'Сделать до', - 'Invalid date' => 'Неверная дата', - 'Automatic actions' => 'Автоматические действия', - 'Your automatic action have been created successfully.' => 'Автоматизированное действие успешно настроено.', - 'Unable to create your automatic action.' => 'Не удалось создать автоматизированное действие.', - 'Remove an action' => 'Удалить действие', - 'Unable to remove this action.' => 'Не удалось удалить действие', - 'Action removed successfully.' => 'Действие удалено.', - 'Automatic actions for the project "%s"' => 'Автоматические действия для проекта « %s »', - 'Add an action' => 'Добавить действие', - 'Event name' => 'Имя события', - 'Action name' => 'Имя действия', - 'Action parameters' => 'Параметры действия', - 'Action' => 'Действие', - 'Event' => 'Событие', - 'When the selected event occurs execute the corresponding action.' => 'Когда случится ВЫБРАННОЕ событие выполняется СООТВЕТСТВУЮЩЕЕ действие.', - 'Next step' => 'Следующий шаг', - 'Define action parameters' => 'Задать параметры действия', - 'Do you really want to remove this action: "%s"?' => 'Вы точно хотите удалить это действие: « %s » ?', - 'Remove an automatic action' => 'Удалить автоматическое действие', - 'Assign the task to a specific user' => 'Назначить задачу определенному пользователю', - 'Assign the task to the person who does the action' => 'Назначить задачу тому кто выполнит действие', - 'Duplicate the task to another project' => 'Создать дубликат задачи в другом проекте', - 'Move a task to another column' => 'Переместить задачу в другую колонку', - 'Task modification' => 'Изменение задачи', - 'Task creation' => 'Создание задачи', - 'Closing a task' => 'Завершение задачи', - 'Assign a color to a specific user' => 'Назначить определенный цвет пользователю', - 'Column title' => 'Название колонки', - 'Position' => 'Расположение', - 'Duplicate to another project' => 'Клонировать в другой проект', - 'Duplicate' => 'Клонировать', - 'link' => 'ссылка', - 'Comment updated successfully.' => 'Комментарий обновлен.', - 'Unable to update your comment.' => 'Не удалось обновить ваш комментарий.', - 'Remove a comment' => 'Удалить комментарий', - 'Comment removed successfully.' => 'Комментарий удален.', - 'Unable to remove this comment.' => 'Не удалось удалить этот комментарий.', - 'Do you really want to remove this comment?' => 'Вы точно хотите удалить этот комментарий?', - 'Current password for the user "%s"' => 'Текущий пароль для пользователя « %s »', - 'The current password is required' => 'Требуется текущий пароль', - 'Wrong password' => 'Неверный пароль', - 'Unknown' => 'Неизвестно', - 'Last logins' => 'Последние посещения', - 'Login date' => 'Дата входа', - 'Authentication method' => 'Способ аутентификации', - 'IP address' => 'IP адрес', - 'User agent' => 'User agent', - 'Persistent connections' => 'Постоянные соединения', - 'No session.' => 'Нет сеанса', - 'Expiration date' => 'Дата окончания', - 'Remember Me' => 'Запомнить меня', - 'Creation date' => 'Дата создания', - 'Everybody' => 'Все', - 'Open' => 'Открытый', - 'Closed' => 'Закрытый', - 'Search' => 'Поиск', - 'Nothing found.' => 'Ничего не найдено.', - 'Due date' => 'Срок', - 'Others formats accepted: %s and %s' => 'Другой формат приемлем: %s и %s', - 'Description' => 'Описание', - '%d comments' => '%d комментариев', - '%d comment' => '%d комментарий', - 'Email address invalid' => 'Некорректный e-mail адрес', - 'Your external account is not linked anymore to your profile.' => 'Ваш внешний аккаунт больше не связан с Вашим профилем.', - 'Unable to unlink your external account.' => 'Не удалось отвязать Ваш внешний аккаунт.', - 'External authentication failed' => 'Внешняя авторизация не удалась', - 'Your external account is linked to your profile successfully.' => 'Ваш внешний аккаунт успешно подключен к профилю.', - 'Email' => 'E-mail', - 'Task removed successfully.' => 'Задача удалена.', - 'Unable to remove this task.' => 'Не удалось удалить эту задачу.', - 'Remove a task' => 'Удалить задачу', - 'Do you really want to remove this task: "%s"?' => 'Вы точно хотите удалить эту задачу « %s » ?', - 'Assign automatically a color based on a category' => 'Автоматически назначать цвет по категории', - 'Assign automatically a category based on a color' => 'Автоматически назначать категорию по цвету', - 'Task creation or modification' => 'Создание или изменение задачи', - 'Category' => 'Категория', - 'Category:' => 'Категория:', - 'Categories' => 'Категории', - 'Your category have been created successfully.' => 'Категория создана.', - 'Unable to create your category.' => 'Не удалось создать категорию.', - 'Your category have been updated successfully.' => 'Категория обновлена.', - 'Unable to update your category.' => 'Не удалось обновить категорию.', - 'Remove a category' => 'Удалить категорию', - 'Category removed successfully.' => 'Категория удалена.', - 'Unable to remove this category.' => 'Не удалось удалить категорию.', - 'Category modification for the project "%s"' => 'Изменение категории для проекта « %s »', - 'Category Name' => 'Название категории', - 'Add a new category' => 'Добавить новую категорию', - 'Do you really want to remove this category: "%s"?' => 'Вы точно хотите удалить категорию « %s » ?', - 'All categories' => 'Все категории', - 'No category' => 'Нет категории', - 'The name is required' => 'Требуется название', - 'Remove a file' => 'Удалить файл', - 'Unable to remove this file.' => 'Не удалось удалить файл.', - 'File removed successfully.' => 'Файл удален.', - 'Attach a document' => 'Прикрепить файл', - 'Do you really want to remove this file: "%s"?' => 'Вы точно хотите удалить этот файл « %s » ?', - 'Attachments' => 'Вложения', - 'Edit the task' => 'Изменить задачу', - 'Add a comment' => 'Добавить комментарий', - 'Edit a comment' => 'Изменить комментарий', - 'Summary' => 'Сводка', - 'Time tracking' => 'Отслеживание времени', - 'Estimate:' => 'Запланировано:', - 'Spent:' => 'Затрачено:', - 'Do you really want to remove this sub-task?' => 'Вы точно хотите удалить подзадачу?', - 'Remaining:' => 'Осталось:', - 'hours' => 'часов', - 'spent' => 'затрачено', - 'estimated' => 'расчетное', - 'Sub-Tasks' => 'Подзадачи', - 'Add a sub-task' => 'Добавить подзадачу', - 'Original estimate' => 'Заплан.', - 'Create another sub-task' => 'Создать другую подзадачу', - 'Time spent' => 'Времени затрачено', - 'Edit a sub-task' => 'Изменить подзадачу', - 'Remove a sub-task' => 'Удалить подзадачу', - 'The time must be a numeric value' => 'Время должно быть числом!', - 'Todo' => 'К исполнению', - 'In progress' => 'В процессе', - 'Sub-task removed successfully.' => 'Подзадача удалена.', - 'Unable to remove this sub-task.' => 'Не удалось удалить подзадачу.', - 'Sub-task updated successfully.' => 'Подзадача обновлена.', - 'Unable to update your sub-task.' => 'Не удалось обновить подзадачу.', - 'Unable to create your sub-task.' => 'Не удалось создать подзадачу.', - 'Sub-task added successfully.' => 'Подзадача добавлена.', - 'Maximum size: ' => 'Максимальный размер: ', - 'Unable to upload the file.' => 'Не удалось загрузить файл.', - 'Display another project' => 'Показать другой проект', - 'Created by %s' => 'Создано %s', - 'Tasks Export' => 'Экспорт задач', - 'Tasks exportation for "%s"' => 'Задача экспортирована для « %s »', - 'Start Date' => 'Дата начала', - 'End Date' => 'Дата завершения', - 'Execute' => 'Выполнить', - 'Task Id' => 'ID задачи', - 'Creator' => 'Автор', - 'Modification date' => 'Дата изменения', - 'Completion date' => 'Дата завершения', - 'Clone' => 'Клонировать', - 'Project cloned successfully.' => 'Проект клонирован.', - 'Unable to clone this project.' => 'Не удалось клонировать проект.', - 'Enable email notifications' => 'Включить уведомления по e-mail', - 'Task position:' => 'Позиция задачи:', - 'The task #%d have been opened.' => 'Задача #%d была открыта.', - 'The task #%d have been closed.' => 'Задача #%d была закрыта.', - 'Sub-task updated' => 'Подзадача обновлена', - 'Title:' => 'Название:', - 'Status:' => 'Статус:', - 'Assignee:' => 'Назначена:', - 'Time tracking:' => 'Отслеживание времени:', - 'New sub-task' => 'Новая подзадача', - 'New attachment added "%s"' => 'Добавлено вложение « %s »', - 'New comment posted by %s' => 'Новый комментарий написан « %s »', - 'New attachment' => 'Новое вложение', - 'New comment' => 'Новый комментарий', - 'Comment updated' => 'Комментарий обновлен', - 'New subtask' => 'Новая подзадача', - 'Subtask updated' => 'Подзадача обновлена', - 'Task updated' => 'Задача обновлена', - 'Task closed' => 'Задача закрыта', - 'Task opened' => 'Задача открыта', - 'I want to receive notifications only for those projects:' => 'Я хочу получать уведомления только по этим проектам:', - 'view the task on Kanboard' => 'посмотреть задачу на Kanboard', - 'Public access' => 'Общий доступ', - 'Active tasks' => 'Активные задачи', - 'Disable public access' => 'Отключить общий доступ', - 'Enable public access' => 'Включить общий доступ', - 'Public access disabled' => 'Общий доступ отключен', - 'Do you really want to disable this project: "%s"?' => 'Вы точно хотите деактивировать проект: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Вы точно хотите активировать проект: "%s"?', - 'Project activation' => 'Активация проекта', - 'Move the task to another project' => 'Переместить задачу в другой проект', - 'Move to another project' => 'Переместить в другой проект', - 'Do you really want to duplicate this task?' => 'Вы точно хотите клонировать задачу?', - 'Duplicate a task' => 'Клонировать задачу', - 'External accounts' => 'Внешняя аутентификация', - 'Account type' => 'Тип профиля', - 'Local' => 'Локальный', - 'Remote' => 'Удаленный', - 'Enabled' => 'Включен', - 'Disabled' => 'Выключены', - 'Username:' => 'Имя пользователя:', - 'Name:' => 'Имя:', - 'Email:' => 'E-mail:', - 'Notifications:' => 'Уведомления:', - 'Notifications' => 'Уведомления', - 'Account type:' => 'Тип профиля:', - 'Edit profile' => 'Редактировать профиль', - 'Change password' => 'Сменить пароль', - 'Password modification' => 'Изменение пароля', - 'External authentications' => 'Внешняя аутентификация', - 'Never connected.' => 'Ранее не соединялось.', - 'No external authentication enabled.' => 'Нет активной внешней аутентификации.', - 'Password modified successfully.' => 'Пароль изменен.', - 'Unable to change the password.' => 'Не удалось сменить пароль.', - 'Change category' => 'Смена категории', - '%s updated the task %s' => '%s обновил задачу %s', - '%s opened the task %s' => '%s открыл задачу %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s переместил задачу %s на позицию #%d в колонке "%s"', - '%s moved the task %s to the column "%s"' => '%s переместил задачу %s в колонку "%s"', - '%s created the task %s' => '%s создал задачу %s', - '%s closed the task %s' => '%s закрыл задачу %s', - '%s created a subtask for the task %s' => '%s создал подзадачу для задачи %s', - '%s updated a subtask for the task %s' => '%s обновил подзадачу для задачи %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Назначено %s с окончанием %s/%sh', - 'Not assigned, estimate of %sh' => 'Не назначено, окончание %sh', - '%s updated a comment on the task %s' => '%s обновил комментарий к задаче %s', - '%s commented the task %s' => '%s прокомментировал задачу %s', - '%s\'s activity' => '%s активность', - 'RSS feed' => 'RSS лента', - '%s updated a comment on the task #%d' => '%s обновил комментарий задачи #%d', - '%s commented on the task #%d' => '%s прокомментировал задачу #%d', - '%s updated a subtask for the task #%d' => '%s обновил подзадачу задачи #%d', - '%s created a subtask for the task #%d' => '%s создал подзадачу для задачи #%d', - '%s updated the task #%d' => '%s обновил задачу #%d', - '%s created the task #%d' => '%s создал задачу #%d', - '%s closed the task #%d' => '%s закрыл задачу #%d', - '%s open the task #%d' => '%s открыл задачу #%d', - '%s moved the task #%d to the column "%s"' => '%s переместил задачу #%d в колонку "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s переместил задачу #%d на позицию %d в колонке "%s"', - 'Activity' => 'Активность', - 'Default values are "%s"' => 'Колонки по умолчанию: "%s"', - 'Default columns for new projects (Comma-separated)' => 'Колонки по умолчанию для новых проектов (разделять запятой)', - 'Task assignee change' => 'Изменен назначенный', - '%s change the assignee of the task #%d to %s' => '%s сменил назначенного для задачи #%d на %s', - '%s changed the assignee of the task %s to %s' => '%s сменил назначенного для задачи %s на %s', - 'New password for the user "%s"' => 'Новый пароль для пользователя "%s"', - 'Choose an event' => 'Выберите событие', - 'Create a task from an external provider' => 'Создать задачу из внешнего источника', - 'Change the assignee based on an external username' => 'Изменить назначенного основываясь на внешнем имени пользователя', - 'Change the category based on an external label' => 'Изменить категорию основываясь на внешнем ярлыке', - 'Reference' => 'Ссылка', - 'Label' => 'Ярлык', - 'Database' => 'База данных', - 'About' => 'Информация', - 'Database driver:' => 'Драйвер базы данных', - 'Board settings' => 'Настройки доски', - 'Webhook settings' => 'Параметры Webhook', - 'Reset token' => 'Перезагрузить токен', - 'API endpoint:' => 'API endpoint:', - '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)' => 'Период (в секундах) в течении которого задача считается недавно измененной (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' => 'Формат даты', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Время должно быть в ISO-формате, например: "%s" или "%s"', - 'New private project' => 'Новый проект с ограниченным доступом', - 'This project is private' => 'Это проект с ограниченным доступом', - 'Add' => 'Добавить', - 'Start date' => 'Дата начала', - 'Time estimated' => 'Запланировано', - 'There is nothing assigned to you.' => 'Вам ничего не назначено', - 'My tasks' => 'Мои задачи', - 'Activity stream' => 'Текущая активность', - 'Dashboard' => 'Инфопанель', - 'Confirmation' => 'Подтверждение пароля', - 'Allow everybody to access to this project' => 'Разрешить любому', - 'Everybody have access to this project.' => 'Любой может получить доступ к этому проекту.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Создать комментарий из внешнего источника', - 'Project management' => 'Управление проектом', - 'My projects' => 'Мои проекты', - 'Columns' => 'Колонки', - 'Task' => 'Задача', - 'Your are not member of any project.' => 'Вы не состоите ни в одном проекте.', - 'Percentage' => 'Процент', - 'Number of tasks' => 'Количество задач', - 'Task distribution' => 'Распределение задач', - 'Reportings' => 'Отчетность', - 'Task repartition for "%s"' => 'Распределение задач для "%s"', - 'Analytics' => 'Аналитика', - 'Subtask' => 'Подзадача', - 'My subtasks' => 'Мои подзадачи', - 'User repartition' => 'Перераспределение пользователей', - 'User repartition for "%s"' => 'Перераспределение пользователей для "%s"', - 'Clone this project' => 'Клонировать проект', - 'Column removed successfully.' => 'Колонка успешно удалена.', - 'Not enough data to show the graph.' => 'Недостаточно данных, чтобы показать график.', - 'Previous' => 'Предыдущий', - 'The id must be an integer' => 'Этот id должен быть целочисленным', - 'The project id must be an integer' => 'Id проекта должен быть целочисленным', - 'The status must be an integer' => 'Статус должен быть целочисленным', - 'The subtask id is required' => 'Id подзадачи обязателен', - 'The subtask id must be an integer' => 'Id подзадачи должен быть целочисленным', - 'The task id is required' => 'Id задачи обязателен', - 'The task id must be an integer' => 'Id задачи должен быть целочисленным', - 'The user id must be an integer' => 'Id пользователя должен быть целочисленным', - 'This value is required' => 'Это значение обязательно', - 'This value must be numeric' => 'Это значение должно быть цифровым', - 'Unable to create this task.' => 'Невозможно создать задачу.', - 'Cumulative flow diagram' => 'Накопительная диаграма', - 'Cumulative flow diagram for "%s"' => 'Накопительная диаграма для "%s"', - 'Daily project summary' => 'Ежедневное состояние проекта', - 'Daily project summary export' => 'Экспорт ежедневного резюме проекта', - 'Daily project summary export for "%s"' => 'Экспорт ежедневного резюме проекта "%s"', - 'Exports' => 'Экспорт', - 'This export contains the number of tasks per column grouped per day.' => 'Этот экспорт содержит ряд задач в колонках, сгруппированные по дням.', - 'Active swimlanes' => 'Активные дорожки', - 'Add a new swimlane' => 'Добавить новую дорожку', - 'Change default swimlane' => 'Сменить стандартную дорожку', - 'Default swimlane' => 'Стандартная дорожка', - 'Do you really want to remove this swimlane: "%s"?' => 'Вы действительно хотите удалить дорожку "%s"?', - 'Inactive swimlanes' => 'Неактивные дорожки', - 'Remove a swimlane' => 'Удалить дорожку', - 'Show default swimlane' => 'Показать стандартную дорожку', - 'Swimlane modification for the project "%s"' => 'Редактирование дорожки для проекта "%s"', - 'Swimlane removed successfully.' => 'Дорожка успешно удалена', - 'Swimlanes' => 'Дорожки', - 'Swimlane updated successfully.' => 'Дорожка успешно обновлена.', - 'The default swimlane have been updated successfully.' => 'Стандартная swimlane был успешно обновлен.', - 'Unable to remove this swimlane.' => 'Невозможно удалить дорожку.', - 'Unable to update this swimlane.' => 'Невозможно обновить дорожку.', - 'Your swimlane have been created successfully.' => 'Ваша дорожка была успешно создан.', - 'Example: "Bug, Feature Request, Improvement"' => 'Например: "Баг, Фича, Улучшение"', - 'Default categories for new projects (Comma-separated)' => 'Стандартные категории для нового проекта (разделяются запятыми)', - 'Integrations' => 'Интеграции', - 'Integration with third-party services' => 'Интеграция со сторонними сервисами', - 'Subtask Id' => 'Id подзадачи', - 'Subtasks' => 'Подзадачи', - 'Subtasks Export' => 'Экспортировать подзадачи', - 'Subtasks exportation for "%s"' => 'Экспорт подзадач для "%s"', - 'Task Title' => 'Загловок задачи', - 'Untitled' => 'Заголовок отсутствует', - 'Application default' => 'Приложение по умолчанию', - 'Language:' => 'Язык:', - 'Timezone:' => 'Временная зона:', - 'All columns' => 'Все колонки', - 'Calendar' => 'Календарь', - 'Next' => 'Следующий', - '#%d' => '#%d', - 'All swimlanes' => 'Все дорожки', - 'All colors' => 'Все цвета', - 'Moved to column %s' => 'Перемещена в колонку %s', - '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"', - 'Subtask timesheet' => 'Табель времени подзадач', - 'There is nothing to show.' => 'Здесь ничего нет.', - 'Time Tracking' => 'Учет времени', - 'You already have one subtask in progress' => 'У вас уже есть одна задача в разработке', - 'Which parts of the project do you want to duplicate?' => 'Какие части проекта должны быть дублированы?', - 'Disallow login form' => 'Запретить форму входа', - 'Start' => 'Начало', - 'End' => 'Конец', - 'Task age in days' => 'Возраст задачи в днях', - 'Days in this column' => 'Дней в этой колонке', - '%dd' => '%dd', - 'Add a new link' => 'Добавление новой ссылки', - 'Do you really want to remove this link: "%s"?' => 'Вы уверены что хотите удалить ссылку: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Вы уверены что хотите удалить ссылку вместе с задачей #%d?', - 'Field required' => 'Поле обязательно для заполнения', - 'Link added successfully.' => 'Ссылка успешно добавлена', - 'Link updated successfully.' => 'Ссылка успешно обновлена', - 'Link removed successfully.' => 'Ссылка успешно удалена', - 'Link labels' => 'Метки для ссылки', - 'Link modification' => 'Обновление ссылки', - 'Links' => 'Ссылки', - 'Link settings' => 'Настройки ссылки', - 'Opposite label' => 'Ярлык напротив', - 'Remove a link' => 'Удалить ссылку', - 'Task\'s links' => 'Ссылки задачи', - 'The labels must be different' => 'Ярлыки должны быть разными', - 'There is no link.' => 'Это не ссылка', - 'This label must be unique' => 'Этот ярлык должен быть уникальным ', - 'Unable to create your link.' => 'Не удается создать эту ссылку.', - 'Unable to update your link.' => 'Не удается обновить эту ссылку.', - 'Unable to remove this link.' => 'Не удается удалить эту ссылку.', - 'relates to' => 'относится к', - 'blocks' => 'блокирована', - 'is blocked by' => 'блокирует', - 'duplicates' => 'дублирована', - 'is duplicated by' => 'дублирует', - 'is a child of' => 'является продолжением', - 'is a parent of' => 'является началом для', - 'targets milestone' => 'часть вехи', - 'is a milestone of' => 'является вехой для', - 'fixes' => 'исправлено', - 'is fixed by' => 'исправляет', - 'This task' => 'Эта задача', - '<1h' => '<1ч', - '%dh' => '%dh', - 'Expand tasks' => 'Развернуть задачи', - 'Collapse tasks' => 'Свернуть задачи', - 'Expand/collapse tasks' => 'Развернуть/свернуть задачи', - 'Close dialog box' => 'Закрыть диалог', - 'Submit a form' => 'Отправить форму', - 'Board view' => 'Просмотр доски', - 'Keyboard shortcuts' => 'Горячие клавиши', - 'Open board switcher' => 'Открыть переключатель доски', - 'Application' => 'Приложение', - 'Compact view' => 'Компактный вид', - 'Horizontal scrolling' => 'Широкий вид', - 'Compact/wide view' => 'Компактный/широкий вид', - 'No results match:' => 'Отсутствуют результаты:', - 'Currency' => 'Валюта', - 'Private project' => 'Приватный проект', - 'AUD - Australian Dollar' => 'AUD - Австралийский доллар', - 'CAD - Canadian Dollar' => 'CAD - Канадский доллар', - 'CHF - Swiss Francs' => 'CHF - Швейцарский франк', - 'Custom Stylesheet' => 'Пользовательский стиль', - 'download' => 'загрузить', - 'EUR - Euro' => 'EUR - Евро', - 'GBP - British Pound' => 'GBP - Британский фунт', - 'INR - Indian Rupee' => 'INR - Индийский рупий', - 'JPY - Japanese Yen' => 'JPY - Японскай йена', - 'NZD - New Zealand Dollar' => 'NZD - Новозеландский доллар', - 'RSD - Serbian dinar' => 'RSD - Сербский динар', - 'USD - US Dollar' => 'USD - доллар США', - 'Destination column' => 'Колонка назначения', - 'Move the task to another column when assigned to a user' => 'Переместить задачу в другую колонку, когда она назначена пользователю', - 'Move the task to another column when assignee is cleared' => 'Переместить задачу в другую колонку, когда назначение снято ', - 'Source column' => 'Исходная колонка', - 'Transitions' => 'Перемещения', - 'Executer' => 'Исполнитель', - 'Time spent in the column' => 'Время проведенное в колонке', - 'Task transitions' => 'Перемещения задач', - 'Task transitions export' => 'Экспорт перемещений задач', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Этот отчет содержит все перемещения задач в колонках с датой, пользователем и времени, затраченным для каждого перемещения.', - 'Currency rates' => 'Курсы валют', - 'Rate' => 'Курс', - 'Change reference currency' => 'Изменить справочник валют', - 'Add a new currency rate' => 'Добавить новый валютный курс', - 'Reference currency' => 'Справочник валют', - 'The currency rate have been added successfully.' => 'Курс валюты был успешно добавлен.', - 'Unable to add this currency rate.' => 'Невозможно добавить этот курс валюты.', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s удалить назначенную задачу %s', - 'Enable Gravatar images' => 'Включить Gravatar изображения', - 'Information' => 'Информация', - 'Check two factor authentication code' => 'Проверка кода двухфакторной авторизации', - 'The two factor authentication code is not valid.' => 'Код двухфакторной авторизации не валиден', - 'The two factor authentication code is valid.' => 'Код двухфакторной авторизации валиден', - 'Code' => 'Код', - 'Two factor authentication' => 'Двухфакторная авторизация', - 'This QR code contains the key URI: ' => 'Это QR-код содержит ключевую URI:', - 'Check my code' => 'Проверить мой код', - 'Secret key: ' => 'Секретный ключ: ', - 'Test your device' => 'Проверьте свое устройство', - 'Assign a color when the task is moved to a specific column' => 'Назначить цвет, когда задача перемещается в определенную колонку', - '%s via Kanboard' => '%s через Канборд', - 'Burndown chart for "%s"' => 'Диаграмма сгорания для « %s »', - 'Burndown chart' => 'Диаграмма сгорания', - 'This chart show the task complexity over the time (Work Remaining).' => 'Эта диаграмма показывают сложность задачи по времени (оставшейся работы).', - 'Screenshot taken %s' => 'Принято скриншотов %s', - 'Add a screenshot' => 'Прикрепить картинку', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Сделайте скриншот и нажмите CTRL+V или ⌘+V для вложения', - 'Screenshot uploaded successfully.' => 'Скриншет успешно загружен', - 'SEK - Swedish Krona' => 'SEK - Шведская крона', - 'Identifier' => 'Идентификатор', - 'Disable two factor authentication' => 'Выключить двухфакторную авторизацию', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Вы действительно хотите выключить двухфакторную авторизацию для пользователя "%s"?', - 'Edit link' => 'Редактировать ссылку', - 'Start to type task title...' => 'Начните вводить название задачи...', - 'A task cannot be linked to itself' => 'Задача не может быть связана с собой же', - 'The exact same link already exists' => 'Такая ссылка уже существует', - 'Recurrent task is scheduled to be generated' => 'Периодическая задача запланирована к созданию', - 'Score' => 'Оценка', - 'The identifier must be unique' => 'Идентификатор должен быть уникальным', - 'This linked task id doesn\'t exists' => 'Этот ID звязанной задачи не существует', - 'This value must be alphanumeric' => 'Это значение должно быть буквенно-цифровым', - 'Edit recurrence' => 'Редактировать повторы', - 'Generate recurrent task' => 'Создать повторяющуюся задачу', - 'Trigger to generate recurrent task' => 'Триггер для генерации периодической задачи', - 'Factor to calculate new due date' => 'Коэффициент для рассчета новой даты', - 'Timeframe to calculate new due date' => 'Вычисление для рассчета новой даты', - 'Base date to calculate new due date' => 'Базовая дата вычисления новой даты', - 'Action date' => 'Дата действия', - 'Base date to calculate new due date: ' => 'Базовая дата вычисления новой даты: ', - 'This task has created this child task: ' => 'Эта задача создала эту дочернюю задачу:', - 'Day(s)' => 'День(й)', - 'Existing due date' => 'Существующий срок', - 'Factor to calculate new due date: ' => 'Коэффициент для рассчета новой даты: ', - 'Month(s)' => 'Месяц(а)', - 'Recurrence' => 'Повторение', - 'This task has been created by: ' => 'Эта задача была создана: ', - 'Recurrent task has been generated:' => 'Периодическая задача была сформирована:', - 'Timeframe to calculate new due date: ' => 'Вычисление для рассчета новой даты: ', - 'Trigger to generate recurrent task: ' => 'Триггер для генерации периодической задачи: ', - 'When task is closed' => 'Когда задача закрывается', - 'When task is moved from first column' => 'Когда задача перемещается из первой колонки', - 'When task is moved to last column' => 'Когда задача перемещается в последнюю колонку', - 'Year(s)' => 'Год(а)', - 'Calendar settings' => 'Настройки календаря', - 'Project calendar view' => 'Вид календаря проекта', - 'Project settings' => 'Настройки проекта', - 'Show subtasks based on the time tracking' => 'Показать подзадачи, основанные на отслеживании времени', - 'Show tasks based on the creation date' => 'Показать задачи в зависимости от даты создания', - 'Show tasks based on the start date' => 'Показать задачи в зависимости от даты начала', - 'Subtasks time tracking' => 'Отслеживание времени подзадач', - 'User calendar view' => 'Просмотреть календарь пользователя', - 'Automatically update the start date' => 'Автоматическое обновление даты начала', - 'iCal feed' => 'iCal данные', - 'Preferences' => 'Предпочтения', - 'Security' => 'Безопасность', - 'Two factor authentication disabled' => 'Двухфакторная аутентификация отключена', - 'Two factor authentication enabled' => 'Включена двухфакторная аутентификация', - 'Unable to update this user.' => 'Не удается обновить этого пользователя.', - 'There is no user management for private projects.' => 'Для приватных проектов управление пользователями не предусмотрено.', - 'User that will receive the email' => 'Пользователь, который будет получать e-mail', - 'Email subject' => 'Тема e-mail', - 'Date' => 'Дата', - 'Add a comment log when moving the task between columns' => 'Добавлять запись при перемещении задачи между колонками', - 'Move the task to another column when the category is changed' => 'Переносить задачи в другую колонку при изменении категории', - 'Send a task by email to someone' => 'Отправить задачу по email', - 'Reopen a task' => 'Переоткрыть задачу', - 'Column change' => 'Изменение колонки', - 'Position change' => 'Позиция изменена', - 'Swimlane change' => 'Дорожка изменена', - 'Assignee change' => 'Назначенный пользователь изменен', - '[%s] Overdue tasks' => '[%s] просроченные задачи', - 'Notification' => 'Уведомления', - '%s moved the task #%d to the first swimlane' => '%s задач перемещено #%d в первой дорожке', - '%s moved the task #%d to the swimlane "%s"' => '%s задач перемещено #%d в дорожке "%s"', - 'Swimlane' => 'Дорожки', - 'Gravatar' => 'Граватар', - '%s moved the task %s to the first swimlane' => '%s переместил задачу %s на первую дорожку', - '%s moved the task %s to the swimlane "%s"' => '%s переместил задачу %s на дорожку "%s"', - 'This report contains all subtasks information for the given date range.' => 'Этот отчет содержит всю информацию подзадач в заданном диапазоне дат.', - 'This report contains all tasks information for the given date range.' => 'Этот отчет содержит всю информацию для задачи в заданном диапазоне дат.', - 'Project activities for %s' => 'Активность проекта для %s', - 'view the board on Kanboard' => 'посмотреть доску на Kanboard', - 'The task have been moved to the first swimlane' => 'Эта задача была перемещена в первую дорожку', - 'The task have been moved to another swimlane:' => 'Эта задача была перемещена в другую дорожку:', - 'New title: %s' => 'Новый заголовок: %s', - 'The task is not assigned anymore' => 'Задача больше не назначена', - 'New assignee: %s' => 'Новый назначенный: %s', - 'There is no category now' => 'В настоящее время здесь нет категорий', - 'New category: %s' => 'Новая категория: %s', - 'New color: %s' => 'Новый цвет: %s', - 'New complexity: %d' => 'Новая сложность: %d', - 'The due date have been removed' => 'Дата завершения была удалена', - 'There is no description anymore' => 'Здесь больше нет описания', - 'Recurrence settings have been modified' => 'Настройки повтора были изменены', - 'Time spent changed: %sh' => 'Изменение количества затраченного времени: %sh', - 'Time estimated changed: %sh' => 'Ожидаемый срок изменен: %sh', - 'The field "%s" have been updated' => 'Поле "%s" ,было изменено', - 'The description has been modified:' => 'Описание было изменено', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Вы действительно хотите закрыть задачу "%s", а также все подзадачи?', - 'I want to receive notifications for:' => 'Я хочу получать уведомления для:', - 'All tasks' => 'Все задачи', - 'Only for tasks assigned to me' => 'Только для задач, назначенных на меня', - 'Only for tasks created by me' => 'Только для задач, созданных мной', - 'Only for tasks created by me and assigned to me' => 'Только для задач, созданных мной и назначенных мной', - '%%Y-%%m-%%d' => '%%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' => 'Поиск задачи', - 'Reset filters' => 'Сбросить фильтры', - 'My tasks due tomorrow' => 'Мои задачи на завтра', - 'Tasks due today' => 'Задачи, завершающиеся сегодня', - 'Tasks due tomorrow' => 'Задачи, завершающиеся завтра', - 'Tasks due yesterday' => 'Задачи, завершившиеся вчера', - 'Closed tasks' => 'Закрытые задачи', - 'Open tasks' => 'Открытые задачи', - 'Not assigned' => 'Не назначенные', - 'View advanced search syntax' => 'Просмотр расширенного синтаксиса поиска', - 'Overview' => 'Обзор', - 'Board/Calendar/List view' => 'Просмотр Доска/Календарь/Список', - 'Switch to the board view' => 'Переключиться в режим доски', - 'Switch to the calendar view' => 'Переключиться в режим календаря', - 'Switch to the list view' => 'Переключиться в режим списка', - 'Go to the search/filter box' => 'Перейти в поиск/фильтр', - 'There is no activity yet.' => 'Активности еще не было', - 'No tasks found.' => 'Задач не найдено.', - 'Keyboard shortcut: "%s"' => 'Сочетание клавиш: "%s"', - 'List' => 'Список', - 'Filter' => 'Фильтр', - 'Advanced search' => 'Расширенный поиск', - 'Example of query: ' => 'Пример запроса: ', - 'Search by project: ' => 'Поиск по проекту: ', - 'Search by column: ' => 'Поиск по колонкам: ', - 'Search by assignee: ' => 'Поису по назначенному: ', - 'Search by color: ' => 'Поиск по цвету: ', - 'Search by category: ' => 'Поиск по категориям: ', - 'Search by description: ' => 'Поиск по описанию: ', - 'Search by due date: ' => 'Поиск по дате завершения: ', - 'Lead and Cycle time for "%s"' => 'Затраченное время и время цикла для "%s"', - 'Average time spent into each column for "%s"' => 'Затрачено времени в среднем в каждой колонке для "%s"', - 'Average time spent into each column' => 'Затрачено времени в среднем в каждой колонке', - 'Average time spent' => 'Затрачено времени в среднем', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Эта диаграмма показывает среднее время, проведенное задачами в каждой колонке за последний %d.', - 'Average Lead and Cycle time' => 'Среднее время выполнения и цикла', - 'Average lead time: ' => 'Среднее время выполнения: ', - 'Average cycle time: ' => 'Среднее время цикла: ', - 'Cycle Time' => 'Время цикла', - 'Lead Time' => 'Время выполнения', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Эта диаграма показывает среднее время выполнения и цикла задачь в последние %d.', - 'Average time into each column' => 'Среднее время в каждом столбце', - 'Lead and cycle time' => 'Время выполнения и цикла', - 'Lead time: ' => 'Время выполнения:', - 'Cycle time: ' => 'Время цикла:', - 'Time spent into each column' => 'Время, проведенное в каждой колонке', - 'The lead time is the duration between the task creation and the completion.' => 'Время выполнения - период между созданием задачи и завершения.', - 'The cycle time is the duration between the start date and the completion.' => 'Время цикла - период времени между датой начала и завершения.', - '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 не будут сохранены в 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.' => 'Нет доступного для назначения проекта.', - 'Trigger automatically subtask time tracking' => 'Триггер автоматического отслеживания времени подзадач', - 'Include closed tasks in the cumulative flow diagram' => 'Включить в диаграмму закрытые задачи', - 'Current swimlane: %s' => 'Текущая дорожка: %s', - 'Current column: %s' => 'Текущая колонка: %s', - 'Current category: %s' => 'Текущая категория: %s', - 'no category' => 'без категории', - 'Current assignee: %s' => 'Текущее назначенное лицо: %s', - 'not assigned' => 'не назначен', - 'Author:' => 'Автор:', - 'contributors' => 'соавторы', - 'License:' => 'Лицензия:', - 'License' => 'Лицензия', - 'Enter the text below' => 'Введите текст ниже', - 'Gantt chart for %s' => 'Диаграмма Ганта для %s', - 'Sort by position' => 'Сортировать по позиции', - 'Sort by date' => 'Сортировать по дате', - 'Add task' => 'Добавить задачу', - 'Start date:' => 'Дата начала:', - 'Due date:' => 'Дата завершения:', - 'There is no start date or due date for this task.' => 'Для этой задачи нет даты начала или завершения.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Изменение или перемещение задачи повлечет изменение даты начала завершения задачи.', - 'There is no task in your project.' => 'В Вашем проекте задач нет.', - 'Gantt chart' => 'Диаграмма Ганта', - 'People who are project managers' => 'Люди, которые менеджеры проекта', - 'People who are project members' => 'Люди, которые участники проекта', - 'NOK - Norwegian Krone' => 'НК - Норвежская крона', - 'Show this column' => 'Показать эту колонку', - 'Hide this column' => 'Спрятать эту колонку', - 'open file' => 'открыть файл', - 'End date' => 'Дата завершения', - 'Users overview' => 'Обзор пользователей', - 'Members' => 'Участники', - 'Shared project' => 'Общие/публичные проекты', - 'Project managers' => 'Менеджер проекта', - 'Gantt chart for all projects' => 'Диаграмма Ганта для всех проектов', - 'Projects list' => 'Список проектов', - 'Gantt chart for this project' => 'Диаграмма Ганта для этого проекта', - 'Project board' => 'Доска проекта', - 'End date:' => 'Дата завершения:', - 'There is no start date or end date for this project.' => 'В проекте не указаны дата начала или завершения.', - 'Projects Gantt chart' => 'Диаграмма Ганта проектов', - 'Change task color when using a specific task link' => 'Изменение цвета задач при использовании ссылки на определенные задачи', - 'Task link creation or modification' => 'Ссылка на создание или модификацию задачи', - 'Milestone' => 'Веха', - 'Documentation: %s' => 'Документация: %s', - 'Switch to the Gantt chart view' => 'Переключиться в режим диаграммы Ганта', - 'Reset the search/filter box' => 'Сбросить поиск/фильтр', - 'Documentation' => 'Документация', - 'Table of contents' => 'Содержание', - 'Gantt' => 'Гант', - 'Author' => 'Автор', - 'Version' => 'Версия', - 'Plugins' => 'Плагины', - 'There is no plugin loaded.' => 'Нет установленных плагинов.', - 'Set maximum column height' => 'Установить максимальную высоту колонки', - 'Remove maximum column height' => 'Сбросить максимальную высоту колонки', - 'My notifications' => 'Мои уведомления', - 'Custom filters' => 'Пользовательские фильтры', - 'Your custom filter have been created successfully.' => 'Фильтр был успешно создан.', - 'Unable to create your custom filter.' => 'Невозможно создать фильтр.', - 'Custom filter removed successfully.' => 'Пользовательский фильтр был успешно удален.', - 'Unable to remove this custom filter.' => 'Невозможно удалить фильтр.', - 'Edit custom filter' => 'Изменить пользовательский фильтр', - 'Your custom filter have been updated successfully.' => 'Пользовательский фильтр был успешно обновлен.', - 'Unable to update custom filter.' => 'Невозможно обновить фильтр.', - 'Web' => 'Интернет', - 'New attachment on task #%d: %s' => 'Новое вложение для задачи #%d: %s', - 'New comment on task #%d' => 'Новый комментарий для задачи #%d', - 'Comment updated on task #%d' => 'Обновлен комментарий у задачи #%d', - 'New subtask on task #%d' => 'Новая подзадача у задачи #%d', - 'Subtask updated on task #%d' => 'Подзадача обновлена у задачи #%d', - 'New task #%d: %s' => 'Новая задача #%d: %s', - 'Task updated #%d' => 'Обновлена задача #%d', - 'Task #%d closed' => 'Задача #%d закрыта', - 'Task #%d opened' => 'Задача #%d открыта', - 'Column changed for task #%d' => 'Обновлена колонка у задачи #%d', - 'New position for task #%d' => 'Новая позиция для задачи #%d', - 'Swimlane changed for task #%d' => 'Изменена дорожка у задачи #%d', - 'Assignee changed on task #%d' => 'Изменен назначенный у задачи #%d', - '%d overdue tasks' => '%d просроченных задач', - 'Task #%d is overdue' => 'Задача #%d просрочена', - 'No new notifications.' => 'Нет новых уведомлений.', - 'Mark all as read' => 'Пометить все прочитанными', - 'Mark as read' => 'Пометить прочитанным', - 'Total number of tasks in this column across all swimlanes' => 'Общее число задач в этой колонке на всех дорожках', - 'Collapse swimlane' => 'Свернуть дорожку', - 'Expand swimlane' => 'Развернуть дорожку', - 'Add a new filter' => 'Добавить новый фильтр', - 'Share with all project members' => 'Сделать общим для всех участников проекта', - 'Shared' => 'Общие', - 'Owner' => 'Владелец', - 'Unread notifications' => 'Непрочитанные уведомления', - 'Notification methods:' => 'Способы уведомления:', - 'Import tasks from CSV file' => 'Импорт задач из CSV-файла', - 'Unable to read your file' => 'Невозможно прочитать файл', - '%d task(s) have been imported successfully.' => '%d задач было успешно импортировано.', - 'Nothing have been imported!' => 'Ничего не было импортировано!', - 'Import users from CSV file' => 'Импорт пользователей из CSV-файла', - '%d user(s) have been imported successfully.' => '%d пользователей было успешно импортировано.', - 'Comma' => 'Запятая', - 'Semi-colon' => 'Точка с запятой', - 'Tab' => 'Пробел (Tab)', - 'Vertical bar' => 'Вертикальная черта (|)', - 'Double Quote' => 'Одинарные кавычки', - 'Single Quote' => 'Двойные кавычки', - '%s attached a file to the task #%d' => '%s добавил файл к задаче #%d', - 'There is no column or swimlane activated in your project!' => 'В вашей задаче нет активных колонок или дорожек!', - 'Append filter (instead of replacement)' => 'Добавляющий фильтр (не заменяющий)', - 'Append/Replace' => 'Добавление/Замена', - 'Append' => 'Добавление', - 'Replace' => 'Замена', - 'Import' => 'Импорт', - 'change sorting' => 'изменить сортировку', - 'Tasks Importation' => 'Импортирование задач', - 'Delimiter' => 'Разделитель', - 'Enclosure' => 'Тип кавычек', - 'CSV File' => 'CSV-файл', - 'Instructions' => 'Инструкции', - 'Your file must use the predefined CSV format' => 'Ваш файл должен использовать структуру формата CSV', - 'Your file must be encoded in UTF-8' => 'Ваш файл должен иметь кодировку UTF-8', - 'The first row must be the header' => 'В первой строке должны быть заголовки столбцов', - 'Duplicates are not verified for you' => 'Проверка на дубликаты не осуществляется', - 'The due date must use the ISO format: YYYY-MM-DD' => 'Дата просрочки должна быть в формате ISO: ГГГГ-ММ-ДД', - 'Download CSV template' => 'Скачать шаблон CSV-файла', - 'No external integration registered.' => 'Нет зарегистрированных внешних интеграций.', - 'Duplicates are not imported' => 'Дубликаты не импортируются', - 'Usernames must be lowercase and unique' => 'Логины пользователей должны быть строчными и уникальными', - 'Passwords will be encrypted if present' => 'Пароли будут зашифрованы (если указаны)', - '%s attached a new file to the task %s' => '%s добавил новый файл к задаче %s', - 'Link type' => 'Тип ссылки', - 'Assign automatically a category based on a link' => 'Автоматически назначать категории на основе ссылки', - 'BAM - Konvertible Mark' => 'BAM - Конвертируемая марка', - 'Assignee Username' => 'Логин назначенного', - 'Assignee Name' => 'Имя назначенного', - 'Groups' => 'Группы', - 'Members of %s' => 'Участник группы %s', - 'New group' => 'Новая группа', - 'Group created successfully.' => 'Группа успешно создана.', - 'Unable to create your group.' => 'Невозможно создать группу.', - 'Edit group' => 'Именить группу', - 'Group updated successfully.' => 'Группы успешно обновлена.', - 'Unable to update your group.' => 'Невозможно обновить группу.', - 'Add group member to "%s"' => 'Добавить участника в "%s"', - 'Group member added successfully.' => 'Участник группы успешно добавлен.', - 'Unable to add group member.' => 'Невозможно добавить участника.', - 'Remove user from group "%s"' => 'Удалить пользователя из группы "%s"', - 'User removed successfully from this group.' => 'Пользователь успешно удален из группы.', - 'Unable to remove this user from the group.' => 'Невозможно удалить пользователя из группы.', - 'Remove group' => 'Удалить группу', - 'Group removed successfully.' => 'Группа успешно удалена.', - 'Unable to remove this group.' => 'Невозможно удалить группу.', - 'Project Permissions' => 'Разрешения проекта', - 'Manager' => 'Менеджер', - 'Project Manager' => 'Менеджер проекта', - 'Project Member' => 'Участник проекта', - 'Project Viewer' => 'Наблюдатель проекта', - 'Your account is locked for %d minutes' => 'Ваш аккаунт заблокирован на %d минут', - 'Invalid captcha' => 'Неверный код подтверждения', - 'The name must be unique' => 'Имя должно быть уникальным', - 'View all groups' => 'Просмотр всех групп', - 'View group members' => 'Просмотр участников группы', - 'There is no user available.' => 'Нет доступных пользователей.', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'Вы действительно хотите удалить пользователя "%s" из группы "%s"?', - 'There is no group.' => 'Нет созданных групп.', - 'External Id' => 'Внешний Id', - 'Add group member' => 'Добавить участника в группу', - 'Do you really want to remove this group: "%s"?' => 'Вы действительно хотите удалить группу "%s"?', - 'There is no user in this group.' => 'В этой группе нет участников.', - 'Remove this user' => 'Удалить пользователя.', - 'Permissions' => 'Разрешения', - 'Allowed Users' => 'Разрешенные пользователи', - 'No user have been allowed specifically.' => 'Нет заданных разрешений для пользователей.', - 'Role' => 'Роль', - 'Enter user name...' => 'Введите имя пользователя...', - 'Allowed Groups' => 'Разрешенные группы', - 'No group have been allowed specifically.' => 'Нет заданных разрешений для групп.', - 'Group' => 'Группа', - 'Group Name' => 'Имя группы', - 'Enter group name...' => 'Введите имя группы...', - 'Role:' => 'Роль:', - 'Project members' => 'Участники проекта', - 'Compare hours for "%s"' => 'Сравнить часы для "%s"', - '%s mentioned you in the task #%d' => '%s упомянул вас в задаче #%d', - '%s mentioned you in a comment on the task #%d' => '%s упомянул вас в комментарии к задаче #%d', - 'You were mentioned in the task #%d' => 'Вы упомянуты в задаче #%d', - 'You were mentioned in a comment on the task #%d' => 'Вы упомянуты в комментарии к задаче #%d', - 'Mentioned' => 'Упоминания', - 'Compare Estimated Time vs Actual Time' => 'Сравнить запланированное время и реальное', - 'Estimated hours: ' => 'Запланировано часов: ', - 'Actual hours: ' => 'Реально затрачено часов: ', - 'Hours Spent' => 'Затрачено часов', - 'Hours Estimated' => 'Запланировано часов', - 'Estimated Time' => 'Запланировано времени', - 'Actual Time' => 'Затрачено времени', - 'Estimated vs actual time' => 'Запланировано и реально затрачено времени', - 'RUB - Russian Ruble' => 'Руб - Российский рубль', - 'Assign the task to the person who does the action when the column is changed' => 'Назначить задачу пользователю, который произвел изменение в колонке', - 'Close a task in a specific column' => 'Закрыть задачу в выбранной колонке', - 'Time-based One-time Password Algorithm' => 'Зависимый от времени, одноразовый алгоритм пароля', - 'Two-Factor Provider: ' => 'Провайдер двух-факторной авторизации: ', - 'Disable two-factor authentication' => 'Отключить двух-факторную авторизацию', - 'Enable two-factor authentication' => 'Включить двух-факторную авторизацию', - 'There is no integration registered at the moment.' => 'Интеграции в данный момент не зарегистрированы.', - 'Password Reset for Kanboard' => 'Сброс пароля для Kanboard', - 'Forgot password?' => 'Забыли пароль?', - 'Enable "Forget Password"' => 'Включить возможность восстановления пароля', - 'Password Reset' => 'Сброс пароля', - 'New password' => 'Новый пароль', - 'Change Password' => 'Изменить пароль', - 'To reset your password click on this link:' => 'Чтобы изменить пароль нажмите на эту ссылку:', - 'Last Password Reset' => 'Последний сброс пароля', - 'The password has never been reinitialized.' => 'Пароль никогда не был сброшен.', - 'Creation' => 'Создан', - 'Expiration' => 'Истекает', - 'Password reset history' => 'История сброса пароля', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'Все задачи для колонки "%s" и дорожки "%s" были успешно закрыты.', - 'Do you really want to close all tasks of this column?' => 'Вы действительно хотите закрыть все задачи из этой колонки?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d задач в колонке "%s" и дорожке "%s" будут закрыты.', - 'Close all tasks of this column' => 'Закрыть все задачи в этой колонке', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'Нет плагинов уведомлений проекта. Вы можете настроить индивидуальные уведомления в вашем профиле пользователя.', - 'My dashboard' => 'Мой кабинет', - 'My profile' => 'Мой профиль', - 'Project owner: ' => 'Владелец проекта:', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'Идентификатор проекта не обязателен и должен содержать буквенно-цифровые символы, пример: MYPROJECT', - 'Project owner' => 'Владелец проекта', - 'Those dates are useful for the project Gantt chart.' => 'Эти даты используются для диаграммы Ганта проекта.', - 'Private projects do not have users and groups management.' => 'Приватные проекты не имеют управления пользователями и группами.', - 'There is no project member.' => 'Нет участников проекта.', - 'Priority' => 'Приоритет', - 'Task priority' => 'Приоритет задачи', - 'General' => 'Общее', - 'Dates' => 'Даты', - 'Default priority' => 'Приоритет по-умолчанию', - 'Lowest priority' => 'Наименьший приоритет', - 'Highest priority' => 'Наивысший приоритет', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'Если Вы введете 0 для наименьшего и наивысшего приоритета, этот функционал будет отключен.', - 'Close a task when there is no activity' => 'Закрывать задачу, когда нет активности', - 'Duration in days' => 'Длительность в днях', - 'Send email when there is no activity on a task' => 'Отправлять email, когда активность по задаче отсутствует', - 'Unable to fetch link information.' => 'Не удалось получить информацию о ссылке', - 'Daily background job for tasks' => 'Ежедневные фоновые работы для задач', - 'Auto' => 'Авто', - 'Related' => 'Связано', - 'Attachment' => 'Вложение', - 'Title not found' => 'Заголовок не найден', - 'Web Link' => 'Web-ссылка', - 'External links' => 'Внешние ссылки', - 'Add external link' => 'Добавить внешнюю ссылку', - 'Type' => 'Тип', - 'Dependency' => 'Зависимость', - 'Add internal link' => 'Добавить внутреннюю ссылку', - 'Add a new external link' => 'Добавить новую внешнюю ссылку', - 'Edit external link' => 'Изменить внешнюю ссылку', - 'External link' => 'Внешняя ссылка', - 'Copy and paste your link here...' => 'Скопируйте и вставьте вашу ссылку здесь', - 'URL' => 'URL', - 'Internal links' => 'Внутренние ссылки', - 'Assign to me' => 'Связать со мной', - 'Me' => 'Мне', - 'Do not duplicate anything' => 'Не дублировать ничего', - 'Projects management' => 'Управление проектами', - 'Users management' => 'Управление пользователями', - 'Groups management' => 'Управление группами', - 'Create from another project' => 'Создать из другого проекта', - 'open' => 'открыто', - 'closed' => 'закрыто', - 'Priority:' => 'Приоритет:', - 'Reference:' => 'Ссылка:', - 'Complexity:' => 'Сложность:', - 'Swimlane:' => 'Дорожка:', - 'Column:' => 'Столбец:', - 'Position:' => 'Позиция:', - 'Creator:' => 'Создатель:', - 'Time estimated:' => 'Оценочное время:', - '%s hours' => '%s часов', - 'Time spent:' => 'Времени потрачено:', - 'Created:' => 'Создана:', - 'Modified:' => 'Изменена:', - 'Completed:' => 'Завершена:', - 'Started:' => 'Начата:', - 'Moved:' => 'Перемещена:', - 'Task #%d' => 'Задача #%d', - 'Date and time format' => 'Формат даты и времени', - 'Time format' => 'Формат времени', - 'Start date: ' => 'Дата начала:', - 'End date: ' => 'Дата окончания:', - 'New due date: ' => 'Новая дата исполнения:', - 'Start date changed: ' => 'Дата начала изменена:', - 'Disable private projects' => 'Выключить приватные проекты', - 'Do you really want to remove this custom filter: "%s"?' => 'Вы точно ходите удалить этот пользовательский фильтр: "%s"?', - 'Remove a custom filter' => 'Удалить пользовательский фильтр', - 'User activated successfully.' => 'Пользователь успешно активирован.', - 'Unable to enable this user.' => 'Не удалось включить этого пользователя.', - 'User disabled successfully.' => 'Пользователь был успешно выключен.', - 'Unable to disable this user.' => 'Не удалось выключить пользователя.', - 'All files have been uploaded successfully.' => 'Все файлы были успешно загружены.', - 'View uploaded files' => 'Просмотр загруженных файлов', - 'The maximum allowed file size is %sB.' => 'Максимально допустимый размер файла: %sB.', - 'Choose files again' => 'Выбрать файлы повторно', - 'Drag and drop your files here' => 'Переместите ваши файлы сюда', - 'choose files' => 'выбор файлов', - 'View profile' => 'Просмотр профиля', - 'Two Factor' => 'Двухфакторный', - 'Disable user' => 'Выключить пользователя', - 'Do you really want to disable this user: "%s"?' => 'Вы точно хотите выключить этого пользователя: "%s"?', - 'Enable user' => 'Включить пользователя', - 'Do you really want to enable this user: "%s"?' => 'Вы точно хотите включить этого пользователя: "%s"?', - 'Download' => 'Загрузка', - 'Uploaded: %s' => 'Загружено: %s', - 'Size: %s' => 'Размер: %s', - 'Uploaded by %s' => 'Загружено пользователем: %s', - 'Filename' => 'Имя файла', - 'Size' => 'Размер', - 'Column created successfully.' => 'Столбец успешно создан', - 'Another column with the same name exists in the project' => 'Столбец с таким именем уже существует в этом проекте', - 'Default filters' => 'Стандартные фильтры', - 'Your board doesn\'t have any 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' => 'Это значение должно быть больше чем %d', - 'Another swimlane with the same name exists in the project' => 'Другая дорожка с таким же именем уже существует в этом проекте', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => 'Пример: http://example.kanboard.net/ (используется для генерации абсолютных URLs)', - 'Actions duplicated successfully.' => 'Дублирование действий прошло успешно', - 'Unable to duplicate actions.' => 'Дублирование действий закончилось неудачно', - 'Add a new action' => 'Добавить новое действие', - 'Import from another project' => 'Импорт из другого проекта', - 'There is no action at the moment.' => 'Действия на данный момент отсутствуют', - 'Import actions from another project' => 'Импорт действий из другого проекта', - 'There is no available project.' => 'Нет доступного проекта', - 'Local File' => 'Локальный файл', - 'Configuration' => 'Конфигурация', - 'PHP version:' => 'Версия PHP:', - 'PHP SAPI:' => 'PHP SAPI:', - 'OS version:' => 'Версия ОС:', - 'Database version:' => 'Версия БД:', - 'Browser:' => 'Браузер:', - 'Task view' => 'Просмотр задачи', - 'Edit task' => 'Изменение задачи', - 'Edit description' => 'Изменение описания', - 'New internal link' => 'Новая внутренняя ссылка', - 'Display list of keyboard shortcuts' => 'Показать список клавиатурных сокращений', - 'Menu' => 'Меню', - 'Set start date' => 'Установить дату начала', - 'Avatar' => 'Аватар', - 'Upload my avatar image' => 'Загрузить моё изображение для аватара', - 'Remove my image' => 'Удалить моё изображение', - 'The OAuth2 state parameter is invalid' => 'Параметр состояние 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"' => '', - // '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' => '', -); diff --git a/sources/app/Locale/sr_Latn_RS/translations.php b/sources/app/Locale/sr_Latn_RS/translations.php deleted file mode 100644 index 00e607f..0000000 --- a/sources/app/Locale/sr_Latn_RS/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => 'None', - 'edit' => 'izmeni', - 'Edit' => 'Izmeni', - 'remove' => 'ukloni', - 'Remove' => 'Ukloni', - 'Yes' => 'Da', - 'No' => 'Ne', - 'cancel' => 'odustani', - 'or' => 'ili', - 'Yellow' => 'Žuta', - 'Blue' => 'Plava', - 'Green' => 'Zelena', - 'Purple' => 'Ljubičasta', - 'Red' => 'Crvena', - 'Orange' => 'Narandžasta', - 'Grey' => 'Siva', - // 'Brown' => '', - // 'Deep Orange' => '', - // 'Dark Grey' => '', - // 'Pink' => '', - // 'Teal' => '', - // 'Cyan' => '', - // 'Lime' => '', - // 'Light Green' => '', - // 'Amber' => '', - 'Save' => 'Snimi', - 'Login' => 'Prijava', - 'Official website:' => 'Zvanična strana:', - 'Unassigned' => 'Nedodeljen', - 'View this task' => 'Pregledaj zadatak', - 'Remove user' => 'Ukloni korisnika', - 'Do you really want to remove this user: "%s"?' => 'Da li zaista želiš da ukloniš korisnika: "%s"?', - 'All users' => 'Svi korisnici', - 'Username' => 'Korisnik', - 'Password' => 'Lozinka', - 'Administrator' => 'Administrator', - 'Sign in' => 'Odjava', - 'Users' => 'Korisnik', - 'No user' => 'Ne', - 'Forbidden' => 'Zabranjeno', - 'Access Forbidden' => 'Zabranjen prostup', - 'Edit user' => 'Izmeni korisnika', - 'Logout' => 'Odjava', - 'Bad username or password' => 'Loše korisničko ime ili lozinka', - 'Edit project' => 'Izmeni projekat', - 'Name' => 'Ime', - 'Projects' => 'Projekti', - 'No project' => 'Bez projekta', - 'Project' => 'Projekat', - 'Status' => 'Status', - 'Tasks' => 'Zadatak', - 'Board' => 'Tabla', - 'Actions' => 'Akcje', - 'Inactive' => 'Neaktivan', - 'Active' => 'Aktivan', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Da li želiš da ukloniš projekat: "%s"?', - 'Remove project' => 'Ukloni projekat', - 'Edit the board for "%s"' => 'Izmeni tablu za "%s"', - 'All projects' => 'Svi projekti', - 'Add a new column' => 'Dodaj novu kolonu', - '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!', - 'Settings' => 'Podešavanja', - 'Application settings' => 'Podešavanja aplikacije', - 'Language' => 'Jezik', - 'Webhook token:' => 'Token :', - 'API token:' => 'Token za API', - 'Database size:' => 'Veličina baze :', - 'Download the database' => 'Preuzmi bazu', - 'Optimize the database' => 'Optimizuj bazu', - '(VACUUM command)' => '(komanda VACUUM)', - '(Gzip compressed Sqlite file)' => '(Sqlite baza spakovana Gzip-om)', - 'Close a task' => 'Zatvori zadatak', - 'Edit a task' => 'Izmeni zadatak', - 'Column' => 'Kolona', - 'Color' => 'Boja', - 'Assignee' => 'Dodeli', - 'Create another task' => 'Dodaj zadatak', - 'New task' => 'Novi zadatak', - 'Open a task' => 'Otvori zadatak', - 'Do you really want to open this task: "%s"?' => 'Da li zaista želiš da otvoriš zadatak: "%s"?', - 'Back to the board' => 'Nazad na tablu', - 'There is nobody assigned' => 'Niko nije dodeljen!', - 'Column on the board:' => 'Kolona na tabli:', - 'Close this task' => 'Zatvori ovaj zadatak', - 'Open this task' => 'Otvori ovaj zadatak', - 'There is no description.' => 'Bez opisa.', - 'Add a new task' => 'Dodaj zadatak', - 'The username is required' => 'Korisničko ime je obavezno', - 'The maximum length is %d characters' => 'Maksimalna dužina je %d znakova', - 'The minimum length is %d characters' => 'Minimalna dužina je %d znakova', - 'The password is required' => 'Lozinka je obavezna', - 'This value must be an integer' => 'Mora biti ceo broj', - 'The username must be unique' => 'Korisničko ime mora biti jedinstveno', - 'The user id is required' => 'ID korisnika je obavezan', - 'Passwords don\'t match' => 'Lozinke se ne podudaraju', - 'The confirmation is required' => 'Potvrda je obavezna', - 'The project is required' => 'Projekat je obavezan', - 'The id is required' => 'ID je obavezan', - 'The project id is required' => 'ID projekta je obavezan', - 'The project name is required' => 'Naziv projekta je obavezan', - 'The title is required' => 'Naslov je obavezan', - 'Settings saved successfully.' => 'Podešavanja uspešno snimljena.', - 'Unable to save your settings.' => 'Nemoguće snimanje podešavanja.', - 'Database optimization done.' => 'Optimizacija baze je završena.', - 'Your project have been created successfully.' => 'Projekat je uspešno napravljen.', - 'Unable to create your project.' => 'Nemoguće kreiranje projekta.', - 'Project updated successfully.' => 'Projekt je uspešno ažuriran.', - 'Unable to update this project.' => 'Nemoguće ažuriranje projekta.', - 'Unable to remove this project.' => 'Nemoguće uklanjanje projekta.', - 'Project removed successfully.' => 'Projekat uspešno uklonjen.', - 'Project activated successfully.' => 'Projekt uspešno aktiviran.', - 'Unable to activate this project.' => 'Nemoguće aktiviranje projekta.', - 'Project disabled successfully.' => 'Projekat uspešno deaktiviran.', - 'Unable to disable this project.' => 'nemoguće deaktiviranje projekta.', - 'Unable to open this task.' => 'Nemoguće otvaranje zadatka.', - 'Task opened successfully.' => 'Zadatak uspešno otvoren.', - 'Unable to close this task.' => 'Nije moguće zatvaranje ovog zadatka.', - 'Task closed successfully.' => 'Zadatak uspešno zatvoren.', - 'Unable to update your task.' => 'Nije moguće ažuriranje zadatka.', - 'Task updated successfully.' => 'Zadatak uspešno ažuriran.', - 'Unable to create your task.' => 'Nije moguće kreiranje zadatka.', - 'Task created successfully.' => 'Zadatak uspešno kreiran.', - 'User created successfully.' => 'Korisnik uspešno kreiran', - 'Unable to create your user.' => 'Nije uspelo kreiranje korisnika.', - 'User updated successfully.' => 'Korisnik uspešno ažuriran.', - 'Unable to update your user.' => 'Nije moguće ažuriranje korisnika.', - 'User removed successfully.' => 'Korisnik uspešno uklonjen.', - 'Unable to remove this user.' => 'Nije moguće uklanjanje korisnika.', - 'Board updated successfully.' => 'Tabla uspešno ažurirana.', - 'Ready' => 'Spreman', - 'Backlog' => 'Log', - 'Work in progress' => 'U radu', - 'Done' => 'Gotovo', - 'Application version:' => 'Verzija aplikacije:', - 'Id' => 'Id', - '%d closed tasks' => '%d zatvorenih zadataka', - 'No task for this project' => 'Nema dodeljenih zadataka ovom projektu', - 'Public link' => 'Javni link', - 'Timezone' => 'Vremenska zona', - 'Sorry, I didn\'t find this information in my database!' => 'Na žalost, nije pronađena informacija u bazi', - 'Page not found' => 'Strana nije pronađena', - 'Complexity' => 'Složenost', - 'Task limit' => 'Ograničenje zadatka', - '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', - 'Invalid date' => 'Loš datum', - 'Automatic actions' => 'Automatske akcije', - 'Your automatic action have been created successfully.' => 'Uspešno kreirana automatska akcija', - 'Unable to create your automatic action.' => 'Nemoguće kreiranje automatske akcije', - 'Remove an action' => 'Obriši akciju', - 'Unable to remove this action.' => 'Nije moguće obrisati akciju', - 'Action removed successfully.' => 'Akcija obrisana', - 'Automatic actions for the project "%s"' => 'Akcje za automatizaciju projekta "%s"', - 'Add an action' => 'dodaj akcju', - 'Event name' => 'Naziv događaja', - 'Action name' => 'Naziv akcije', - 'Action parameters' => 'Parametri akcije', - 'Action' => 'Akcija', - 'Event' => 'Događaj', - 'When the selected event occurs execute the corresponding action.' => 'Kad se događaj desi izvrši odgovarajuću akciju', - 'Next step' => 'Sledeći korak', - 'Define action parameters' => 'Definiši parametre akcije', - 'Do you really want to remove this action: "%s"?' => 'Da li da obrišem akciju "%s"?', - 'Remove an automatic action' => 'Obriši automatsku akciju', - 'Assign the task to a specific user' => 'Dodeli zadatak određenom korisniku', - 'Assign the task to the person who does the action' => 'Dodeli zadatak korisniku koji je izvršio akciju', - 'Duplicate the task to another project' => 'Kopiraj akciju u drugi projekat', - 'Move a task to another column' => 'Premesti zadatak u drugu kolonu', - 'Task modification' => 'Izman zadatka', - 'Task creation' => 'Kreiranje zadatka', - 'Closing a task' => 'Zatvaranja zadatka', - 'Assign a color to a specific user' => 'Dodeli boju korisniku', - 'Column title' => 'Naslov kolone', - 'Position' => 'Pozicija', - 'Duplicate to another project' => 'Kopiraj u drugi projekat', - 'Duplicate' => 'Napravi kopiju', - 'link' => 'link', - 'Comment updated successfully.' => 'Komentar uspešno ažuriran.', - 'Unable to update your comment.' => 'Neuspešno ažuriranje komentara.', - 'Remove a comment' => 'Obriši komentar', - 'Comment removed successfully.' => 'Komentar je uspešno obrisan.', - 'Unable to remove this comment.' => 'Neuspešno brisanje komentara.', - 'Do you really want to remove this comment?' => 'Da li da obrišem ovaj komentar?', - 'Current password for the user "%s"' => 'Trenutna lozinka za korisnika "%s"', - 'The current password is required' => 'Trenutna lozinka je obavezna', - 'Wrong password' => 'Pogrešna lozinka', - 'Unknown' => 'Nepoznat', - 'Last logins' => 'Poslednja prijava', - 'Login date' => 'Datum prijave', - 'Authentication method' => 'Metod autentikacije', - 'IP address' => 'IP adresa', - 'User agent' => 'Browser', - 'Persistent connections' => 'Stalna konekcija', - 'No session.' => 'Bez sesjie', - 'Expiration date' => 'Ističe', - 'Remember Me' => 'Zapamti me', - 'Creation date' => 'Datum kreiranja', - 'Everybody' => 'Svi', - 'Open' => 'Otvoreni', - 'Closed' => 'Zatvoreni', - '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', - 'Email address invalid' => 'Pogrešan e-mail', - // 'Your external account is not linked anymore to your profile.' => '', - // 'Unable to unlink your external account.' => '', - // 'External authentication failed' => '', - // 'Your external account is linked to your profile successfully.' => '', - 'Email' => 'E-mail', - 'Task removed successfully.' => 'Zadatak uspešno uklonjen.', - 'Unable to remove this task.' => 'Nemoguće uklanjanje zadatka.', - 'Remove a task' => 'Ukloni zadatak', - 'Do you really want to remove this task: "%s"?' => 'Da li da obrišem zadatak "%s"?', - 'Assign automatically a color based on a category' => 'Automatski dodeli boju po kategoriji', - 'Assign automatically a category based on a color' => 'Automatski dodeli kategoriju po boji', - 'Task creation or modification' => 'Kreiranje ili izmena zadatka', - 'Category' => 'Kategorija', - 'Category:' => 'Kategorija:', - 'Categories' => 'Kategorije', - 'Your category have been created successfully.' => 'Uspešno kreirana kategorija.', - 'Unable to create your category.' => 'Nije moguće kreirati kategoriju.', - 'Your category have been updated successfully.' => 'Kategorija je uspešno izmenjena', - 'Unable to update your category.' => 'Nemoguće izmeniti kategoriju', - 'Remove a category' => 'Obriši kategoriju', - 'Category removed successfully.' => 'Kategorija uspešno uklonjena.', - 'Unable to remove this category.' => 'Nije moguće ukloniti kategoriju.', - 'Category modification for the project "%s"' => 'Izmena kategorije za projekat "%s"', - 'Category Name' => 'Naziv kategorije', - 'Add a new category' => 'Dodaj novu kategoriju', - 'Do you really want to remove this category: "%s"?' => 'Da li zaista želiš da ukloniš kategoriju: "%s"?', - 'All categories' => 'Sve kategorije', - 'No category' => 'Bez kategorije', - 'The name is required' => 'Naziv je obavezan', - 'Remove a file' => 'Ukloni fajl', - 'Unable to remove this file.' => 'Fajl nije moguće ukloniti.', - 'File removed successfully.' => 'Uspešno uklonjen fajl.', - 'Attach a document' => 'Prikači dokument', - 'Do you really want to remove this file: "%s"?' => 'Da li da uklonim fajl: "%s"?', - 'Attachments' => 'Prilozi', - 'Edit the task' => 'Izmena Zadatka', - 'Add a comment' => 'Dodaj komentar', - 'Edit a comment' => 'Izmeni komentar', - 'Summary' => 'Pregled', - 'Time tracking' => 'Praćenje vremena', - 'Estimate:' => 'Procena:', - 'Spent:' => 'Potrošeno:', - 'Do you really want to remove this sub-task?' => 'Da li da uklonim pod-zdadatak?', - 'Remaining:' => 'Preostalo:', - 'hours' => 'sati', - 'spent' => 'potrošeno', - 'estimated' => 'procenjeno', - 'Sub-Tasks' => 'Pod-zadaci', - 'Add a sub-task' => 'Dodaj pod-zadatak', - 'Original estimate' => 'Originalna procena', - 'Create another sub-task' => 'Dodaj novi pod-zadatak', - 'Time spent' => 'Utrošeno vreme', - 'Edit a sub-task' => 'Izmeni pod-zadatak', - 'Remove a sub-task' => 'Ukloni pod-zadatak', - 'The time must be a numeric value' => 'Vreme mora biti broj', - 'Todo' => 'Za rad', - 'In progress' => 'U radu', - 'Sub-task removed successfully.' => 'Pod-zadatak uspešno uklonjen.', - 'Unable to remove this sub-task.' => 'Nie można usunąć tego pod-zadania.', - 'Sub-task updated successfully.' => 'Pod-zadatak zaktualizowane pomyślnie.', - 'Unable to update your sub-task.' => 'Nie można zaktalizować tego pod-zadania.', - 'Unable to create your sub-task.' => 'Nie można utworzyć tego pod-zadania.', - 'Sub-task added successfully.' => 'Pod-zadatak utworzone pomyślnie', - 'Maximum size: ' => 'Maksimalna veličina: ', - 'Unable to upload the file.' => 'Nije moguće snimiti fajl.', - 'Display another project' => 'Prikaži drugi projekat', - 'Created by %s' => 'Kreirao %s', - 'Tasks Export' => 'Izvoz zadataka', - 'Tasks exportation for "%s"' => 'Izvoz zadataka za "%s"', - 'Start Date' => 'Početni datum', - 'End Date' => 'Krajni datum', - 'Execute' => 'Izvrši', - 'Task Id' => 'Identifikator Zadatka', - 'Creator' => 'Autor', - 'Modification date' => 'Datum izmene', - 'Completion date' => 'Datum kompletiranja', - 'Clone' => 'Iskopiraj', - 'Project cloned successfully.' => 'Projekat uspešno iskopiran.', - 'Unable to clone this project.' => 'Nije moguće iskopirati projekat.', - 'Enable email notifications' => 'Omogući obaveštenja e-mailom', - 'Task position:' => 'Pozicija zadatka:', - 'The task #%d have been opened.' => 'Zadatak #%d je otvoren.', - 'The task #%d have been closed.' => 'Zadatak #%d je zatvoren.', - 'Sub-task updated' => 'Pod-zadatak izmenjen', - 'Title:' => 'Naslov:', - // 'Status:' => '', - 'Assignee:' => 'Dodeli:', - 'Time tracking:' => 'Praćenje vremena: ', - 'New sub-task' => 'Novi Pod-zadatak', - 'New attachment added "%s"' => 'Novi prilog ubačen "%s"', - 'New comment posted by %s' => 'Novi komentar ostavio %s', - // 'New attachment' => '', - // 'New comment' => '', - 'Comment updated' => 'Komentar izmenjen', - // 'New subtask' => '', - // 'Subtask updated' => '', - // 'Task updated' => '', - 'Task closed' => 'Zadatak je zatvoren', - 'Task opened' => 'Zadatak je otvoren', - 'I want to receive notifications only for those projects:' => 'Želim obaveštenja samo za ovaj projekat:', - 'view the task on Kanboard' => 'Pregledaj zadatke', - 'Public access' => 'Javni pristup', - 'Active tasks' => 'Aktivni zadaci', - 'Disable public access' => 'Zabrani javni pristup', - 'Enable public access' => 'Dozvoli javni pristup', - 'Public access disabled' => 'Javni pristup onemogućen!', - 'Do you really want to disable this project: "%s"?' => 'Da li zaista želiš da deaktiviraš projekat: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Da li zaista želiš da aktiviraš projekat: "%s"?', - 'Project activation' => 'Aktivacija projekta', - 'Move the task to another project' => 'Premesti zadatak u drugi projekat', - 'Move to another project' => 'Premesti u drugi projekat', - 'Do you really want to duplicate this task?' => 'Da li da napravim kopiju ovog projekta?', - 'Duplicate a task' => 'Kopiraj zadatak', - 'External accounts' => 'Spoljni nalozi', - 'Account type' => 'Tip naloga', - 'Local' => 'Lokalno', - 'Remote' => 'Udaljno', - 'Enabled' => 'Omogući', - 'Disabled' => 'Onemogući', - 'Username:' => 'Korisničko ime:', - 'Name:' => 'Ime i Prezime', - 'Email:' => 'Email: ', - 'Notifications:' => 'Obaveštenja: ', - 'Notifications' => 'Obaveštenja', - 'Account type:' => 'Vrsta naloga:', - 'Edit profile' => 'Izmeni profil', - 'Change password' => 'Izmeni lozinku', - 'Password modification' => 'Izmena lozinke', - 'External authentications' => 'Spoljne akcije', - 'Never connected.' => 'Bez konekcija.', - 'No external authentication enabled.' => 'Bez omogućenih spoljnih autentikacija.', - 'Password modified successfully.' => 'Uspešna izmena lozinke.', - 'Unable to change the password.' => 'Nije moguće izmeniti lozinku.', - 'Change category' => 'Izmeni kategoriju', - '%s updated the task %s' => '%s izmeni zadatak %s', - '%s opened the task %s' => '%s aktivni zadaci %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s premešten zadatak %s na poziciju #%d u koloni "%s"', - '%s moved the task %s to the column "%s"' => '%s premešten zadatak %s u kolonu "%s"', - '%s created the task %s' => '%s kreirao zadatak %s', - '%s closed the task %s' => '%s zatvorio zadatak %s', - '%s created a subtask for the task %s' => '%s kreiran pod-zadatak zadatka %s', - '%s updated a subtask for the task %s' => '%s izmenjen pod-zadatak zadatka %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Dodeljen korisniku %s uz procenu vremena %s/%sh', - 'Not assigned, estimate of %sh' => 'Ne dodeljen, procenjeno vreme %sh', - '%s updated a comment on the task %s' => '%s izmenjen komentar zadatka %s', - '%s commented the task %s' => '%s komentarisao zadatak %s', - '%s\'s activity' => 'Aktivnosti %s', - 'RSS feed' => 'RSS kanal', - '%s updated a comment on the task #%d' => '%s izmenjen komentar zadatka #%d', - '%s commented on the task #%d' => '%s komentarisao zadatak #%d', - '%s updated a subtask for the task #%d' => '%s izmenjen pod-zadatak zadatka #%d', - '%s created a subtask for the task #%d' => '%s kreirao pod-zadatak zadatka #%d', - '%s updated the task #%d' => '%s izmenjen zadatak #%d', - '%s created the task #%d' => '%s kreirao zadatak #%d', - '%s closed the task #%d' => '%s zatvorio zadatak #%d', - '%s open the task #%d' => '%s otvorio zadatak #%d', - '%s moved the task #%d to the column "%s"' => '%s premestio zadatak #%d u kolonu "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s premestio zadatak #%d na pozycję %d w kolmnie "%s"', - 'Activity' => 'Aktivnosti', - 'Default values are "%s"' => 'Osnovne vrednosti su: "%s"', - 'Default columns for new projects (Comma-separated)' => 'Osnovne kolone za novi projekat (Odvojeni zarezom)', - 'Task assignee change' => 'Zmień osobę odpowiedzialną', - '%s change the assignee of the task #%d to %s' => '%s zamena dodele za zadatak #%d na %s', - '%s changed the assignee of the task %s to %s' => '%s zamena dodele za zadatak %s na %s', - 'New password for the user "%s"' => 'Nova lozinka za korisnika "%s"', - 'Choose an event' => 'Izaberi događaj', - 'Create a task from an external provider' => 'Kreiraj zadatak preko posrednika', - 'Change the assignee based on an external username' => 'Zmień osobę odpowiedzialną na podstawie zewnętrznej nazwy użytkownika', - 'Change the category based on an external label' => 'Zmień kategorię na podstawie zewnętrzenj etykiety', - // 'Reference' => '', - 'Label' => 'Etikieta', - 'Database' => 'Baza', - 'About' => 'Informacje', - 'Database driver:' => 'Database driver:', - 'Board settings' => 'Podešavanje table', - // 'Webhook settings' => '', - 'Reset token' => 'Resetuj token', - // 'API endpoint:' => '', - 'Refresh interval for private board' => 'Interval osvežavanja privatnih tabli', - 'Refresh interval for public board' => 'Interval osvežavanja javnih tabli', - 'Task highlight period' => 'Task highlight period', - // 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '', - // 'Frequency in second (60 seconds by default)' => '', - // 'Frequency in second (0 to disable this feature, 10 seconds by default)' => '', - 'Application URL' => 'Adres URL aplikacji', - 'Token regenerated.' => 'Token wygenerowany ponownie.', - 'Date format' => 'Format daty', - 'ISO format is always accepted, example: "%s" and "%s"' => 'Format ISO je uvek prihvatljiv, primer: "%s", "%s"', - 'New private project' => 'Novi privatni projekat', - 'This project is private' => 'Ovaj projekat je privatan', - 'Add' => 'Dodaj', - 'Start date' => 'Datum početka', - 'Time estimated' => 'Procenjeno vreme', - 'There is nothing assigned to you.' => 'Ništa vam nije dodeljeno', - 'My tasks' => 'Moji zadaci', - 'Activity stream' => 'Spisak aktinosti', - 'Dashboard' => 'Panel', - 'Confirmation' => 'Potvrda', - 'Allow everybody to access to this project' => 'Dozvoli svima pristup projektu', - 'Everybody have access to this project.' => 'Svima je dozvoljen pristup.', - // 'Webhooks' => '', - // 'API' => '', - // 'Create a comment from an external provider' => '', - 'Project management' => 'Uređivanje projekata', - 'My projects' => 'Moji projekti', - 'Columns' => 'Kolone', - 'Task' => 'Zadaci', - 'Your are not member of any project.' => 'Nisi član ni jednog projekta', - 'Percentage' => 'Procenat', - 'Number of tasks' => 'Broj zadataka', - 'Task distribution' => 'Podela zadataka', - 'Reportings' => 'Izveštaji', - 'Task repartition for "%s"' => 'Zaduženja zadataka za "%s"', - 'Analytics' => 'Analiza', - 'Subtask' => 'Pod-zadatak', - 'My subtasks' => 'Moji pod-zadaci', - 'User repartition' => 'Zaduženja korisnika', - 'User repartition for "%s"' => 'Zaduženja korisnika za "%s"', - 'Clone this project' => 'Kopiraj projekat', - 'Column removed successfully.' => 'Kolumna usunięta pomyslnie.', - 'Not enough data to show the graph.' => 'Nedovoljno podataka za grafikon.', - 'Previous' => 'Prethodni', - 'The id must be an integer' => 'ID musi być liczbą całkowitą', - 'The project id must be an integer' => 'ID projektu musi być liczbą całkowitą', - 'The status must be an integer' => 'Status musi być liczbą całkowitą', - 'The subtask id is required' => 'ID pod-zadatak jest wymagane', - 'The subtask id must be an integer' => 'ID pod-zadania musi być liczbą całkowitą', - 'The task id is required' => 'ID zadania jest wymagane', - 'The task id must be an integer' => 'ID zadatka mora biti broj', - 'The user id must be an integer' => 'ID korisnika mora biti broj', - 'This value is required' => 'Vrednost je obavezna', - 'This value must be numeric' => 'Vrednost mora biti broj', - 'Unable to create this task.' => 'Nije moguće kreirati zadatak.', - 'Cumulative flow diagram' => 'Zbirni dijagram toka', - 'Cumulative flow diagram for "%s"' => 'Zbirni dijagram toka za "%s"', - 'Daily project summary' => 'Zbirni pregled po danima', - 'Daily project summary export' => 'Izvoz zbirnog pregleda po danima', - 'Daily project summary export for "%s"' => 'Izvoz zbirnig pregleda po danima za "%s"', - 'Exports' => 'Izvoz', - // 'This export contains the number of tasks per column grouped per day.' => '', - 'Active swimlanes' => 'Aktivni razdelnik', - 'Add a new swimlane' => 'Dodaj razdelnik', - 'Change default swimlane' => 'Zameni osnovni razdelnik', - 'Default swimlane' => 'Osnovni razdelnik', - 'Do you really want to remove this swimlane: "%s"?' => 'Da li da uklonim razdelnik: "%s"?', - 'Inactive swimlanes' => 'Neaktivni razdelniki', - 'Remove a swimlane' => 'Ukloni razdelnik', - 'Show default swimlane' => 'Prikaži osnovni razdelnik', - 'Swimlane modification for the project "%s"' => 'Izmena razdelnika za projekat "%s"', - 'Swimlane removed successfully.' => 'Razdelnik uspešno uklonjen.', - 'Swimlanes' => 'Razdelnici', - 'Swimlane updated successfully.' => 'Razdelnik zaktualizowany pomyślnie.', - // 'The default swimlane have been updated successfully.' => '', - // 'Unable to remove this swimlane.' => '', - // 'Unable to update this swimlane.' => '', - 'Your swimlane have been created successfully.' => 'Razdelnik je uspešno kreiran.', - 'Example: "Bug, Feature Request, Improvement"' => 'Npr: "Greška, Zahtev za izmenama, Poboljšanje"', - 'Default categories for new projects (Comma-separated)' => 'Osnovne kategorije za projekat', - 'Integrations' => 'Integracje', - 'Integration with third-party services' => 'Integracja sa uslugama spoljnih servisa', - 'Subtask Id' => 'ID pod-zadania', - 'Subtasks' => 'Pod-zadataka', - 'Subtasks Export' => 'Eksport pod-zadań', - 'Subtasks exportation for "%s"' => 'Izvoz pod-zadań dla "%s"', - 'Task Title' => 'Naslov zadatka', - 'Untitled' => 'Bez naslova', - 'Application default' => 'Postavke aplikacje', - 'Language:' => 'Jezik:', - 'Timezone:' => 'Vremenska zona:', - 'All columns' => 'Sve kolone', - 'Calendar' => 'Kalendar', - 'Next' => 'Sledeći', - // '#%d' => '', - 'All swimlanes' => 'Svi razdelniki', - 'All colors' => 'Sve boje', - 'Moved to column %s' => 'Premešten u kolonu %s', - 'User dashboard' => 'Korisnički panel', - // 'Allow only one subtask in progress at the same time for a user' => '', - // 'Edit column "%s"' => '', - // 'Select the new status of the subtask: "%s"' => '', - // 'Subtask timesheet' => '', - 'There is nothing to show.' => 'Nema podataka', - 'Time Tracking' => 'Praćenje vremena', - // 'You already have one subtask in progress' => '', - 'Which parts of the project do you want to duplicate?' => 'Koje delove projekta želite da kopirate', - // 'Disallow login form' => '', - // 'Start' => '', - // 'End' => '', - // 'Task age in days' => '', - // 'Days in this column' => '', - // '%dd' => '', - // 'Add a new link' => '', - // 'Do you really want to remove this link: "%s"?' => '', - // 'Do you really want to remove this link with task #%d?' => '', - // 'Field required' => '', - // 'Link added successfully.' => '', - // 'Link updated successfully.' => '', - // 'Link removed successfully.' => '', - // 'Link labels' => '', - // 'Link modification' => '', - // 'Links' => '', - // 'Link settings' => '', - // 'Opposite label' => '', - // 'Remove a link' => '', - // 'Task\'s links' => '', - // 'The labels must be different' => '', - // 'There is no link.' => '', - // 'This label must be unique' => '', - // 'Unable to create your link.' => '', - // 'Unable to update your link.' => '', - // 'Unable to remove this link.' => '', - // 'relates to' => '', - // 'blocks' => '', - // 'is blocked by' => '', - // 'duplicates' => '', - // 'is duplicated by' => '', - // 'is a child of' => '', - // 'is a parent of' => '', - // 'targets milestone' => '', - // 'is a milestone of' => '', - // 'fixes' => '', - // 'is fixed by' => '', - // 'This task' => '', - // '<1h' => '', - // '%dh' => '', - // 'Expand tasks' => '', - // 'Collapse tasks' => '', - // 'Expand/collapse tasks' => '', - // 'Close dialog box' => '', - // 'Submit a form' => '', - // 'Board view' => '', - // 'Keyboard shortcuts' => '', - // 'Open board switcher' => '', - // 'Application' => '', - // 'Compact view' => '', - // 'Horizontal scrolling' => '', - // 'Compact/wide view' => '', - // 'No results match:' => '', - // 'Currency' => '', - // 'Private project' => '', - // 'AUD - Australian Dollar' => '', - // 'CAD - Canadian Dollar' => '', - // 'CHF - Swiss Francs' => '', - // 'Custom Stylesheet' => '', - // 'download' => '', - // 'EUR - Euro' => '', - // 'GBP - British Pound' => '', - // 'INR - Indian Rupee' => '', - // 'JPY - Japanese Yen' => '', - // 'NZD - New Zealand Dollar' => '', - // 'RSD - Serbian dinar' => '', - // 'USD - US Dollar' => '', - // 'Destination column' => '', - // 'Move the task to another column when assigned to a user' => '', - // 'Move the task to another column when assignee is cleared' => '', - // 'Source column' => '', - // 'Transitions' => '', - // 'Executer' => '', - // 'Time spent in the column' => '', - // 'Task transitions' => '', - // 'Task transitions export' => '', - // 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '', - // 'Currency rates' => '', - // 'Rate' => '', - // 'Change reference currency' => '', - // 'Add a new currency rate' => '', - // 'Reference currency' => '', - // 'The currency rate have been added successfully.' => '', - // 'Unable to add this currency rate.' => '', - // 'Webhook URL' => '', - // '%s remove the assignee of the task %s' => '', - // 'Enable Gravatar images' => '', - // 'Information' => '', - // 'Check two factor authentication code' => '', - // 'The two factor authentication code is not valid.' => '', - // 'The two factor authentication code is valid.' => '', - // 'Code' => '', - // 'Two factor authentication' => '', - // 'This QR code contains the key URI: ' => '', - // 'Check my code' => '', - // 'Secret key: ' => '', - // 'Test your device' => '', - // 'Assign a color when the task is moved to a specific column' => '', - // '%s via Kanboard' => '', - // 'Burndown chart for "%s"' => '', - // 'Burndown chart' => '', - // 'This chart show the task complexity over the time (Work Remaining).' => '', - // 'Screenshot taken %s' => '', - // 'Add a screenshot' => '', - // 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '', - // 'Screenshot uploaded successfully.' => '', - // 'SEK - Swedish Krona' => '', - // 'Identifier' => '', - // 'Disable two factor authentication' => '', - // 'Do you really want to disable the two factor authentication for this user: "%s"?' => '', - // 'Edit link' => '', - // 'Start to type task title...' => '', - // 'A task cannot be linked to itself' => '', - // 'The exact same link already exists' => '', - // 'Recurrent task is scheduled to be generated' => '', - // 'Score' => '', - // 'The identifier must be unique' => '', - // 'This linked task id doesn\'t exists' => '', - // 'This value must be alphanumeric' => '', - // 'Edit recurrence' => '', - // 'Generate recurrent task' => '', - // 'Trigger to generate recurrent task' => '', - // 'Factor to calculate new due date' => '', - // 'Timeframe to calculate new due date' => '', - // 'Base date to calculate new due date' => '', - // 'Action date' => '', - // 'Base date to calculate new due date: ' => '', - // 'This task has created this child task: ' => '', - // 'Day(s)' => '', - // 'Existing due date' => '', - // 'Factor to calculate new due date: ' => '', - // 'Month(s)' => '', - // 'Recurrence' => '', - // 'This task has been created by: ' => '', - // 'Recurrent task has been generated:' => '', - // 'Timeframe to calculate new due date: ' => '', - // 'Trigger to generate recurrent task: ' => '', - // 'When task is closed' => '', - // 'When task is moved from first column' => '', - // 'When task is moved to last column' => '', - // 'Year(s)' => '', - // 'Calendar settings' => '', - // 'Project calendar view' => '', - // 'Project settings' => '', - // 'Show subtasks based on the time tracking' => '', - // 'Show tasks based on the creation date' => '', - // 'Show tasks based on the start date' => '', - // 'Subtasks time tracking' => '', - // 'User calendar view' => '', - // 'Automatically update the start date' => '', - // 'iCal feed' => '', - // 'Preferences' => '', - // 'Security' => '', - // 'Two factor authentication disabled' => '', - // 'Two factor authentication enabled' => '', - // 'Unable to update this user.' => '', - // 'There is no user management for private projects.' => '', - // 'User that will receive the email' => '', - // 'Email subject' => '', - // 'Date' => '', - // 'Add a comment log when moving the task between columns' => '', - // 'Move the task to another column when the category is changed' => '', - // 'Send a task by email to someone' => '', - // 'Reopen a task' => '', - // 'Column change' => '', - // 'Position change' => '', - // 'Swimlane change' => '', - // 'Assignee change' => '', - // '[%s] Overdue tasks' => '', - // 'Notification' => '', - // '%s moved the task #%d to the first swimlane' => '', - // '%s moved the task #%d to the swimlane "%s"' => '', - // 'Swimlane' => '', - // 'Gravatar' => '', - // '%s moved the task %s to the first swimlane' => '', - // '%s moved the task %s to the swimlane "%s"' => '', - // 'This report contains all subtasks information for the given date range.' => '', - // 'This report contains all tasks information for the given date range.' => '', - // 'Project activities for %s' => '', - // 'view the board on Kanboard' => '', - // 'The task have been moved to the first swimlane' => '', - // 'The task have been moved to another swimlane:' => '', - // 'New title: %s' => '', - // 'The task is not assigned anymore' => '', - // 'New assignee: %s' => '', - // 'There is no category now' => '', - // 'New category: %s' => '', - // 'New color: %s' => '', - // 'New complexity: %d' => '', - // 'The due date have been removed' => '', - // 'There is no description anymore' => '', - // 'Recurrence settings have been modified' => '', - // 'Time spent changed: %sh' => '', - // 'Time estimated changed: %sh' => '', - // 'The field "%s" have been updated' => '', - // 'The description has been modified:' => '', - // 'Do you really want to close the task "%s" as well as all subtasks?' => '', - // 'I want to receive notifications for:' => '', - // 'All tasks' => '', - // 'Only for tasks assigned to me' => '', - // 'Only for tasks created by me' => '', - // 'Only for tasks created by me and assigned to me' => '', - // '%%Y-%%m-%%d' => '', - // 'Total for all columns' => '', - // 'You need at least 2 days of data to show the chart.' => '', - // '<15m' => '', - // '<30m' => '', - // 'Stop timer' => '', - // 'Start timer' => '', - // 'Add project member' => '', - // 'My activity stream' => '', - // 'My calendar' => '', - // 'Search tasks' => '', - // 'Reset filters' => '', - // 'My tasks due tomorrow' => '', - // 'Tasks due today' => '', - // 'Tasks due tomorrow' => '', - // 'Tasks due yesterday' => '', - // 'Closed tasks' => '', - // 'Open tasks' => '', - // 'Not assigned' => '', - // 'View advanced search syntax' => '', - // 'Overview' => '', - // 'Board/Calendar/List view' => '', - // 'Switch to the board view' => '', - // 'Switch to the calendar view' => '', - // 'Switch to the list view' => '', - // 'Go to the search/filter box' => '', - // 'There is no activity yet.' => '', - // 'No tasks found.' => '', - // 'Keyboard shortcut: "%s"' => '', - // 'List' => '', - // 'Filter' => '', - // 'Advanced search' => '', - // 'Example of query: ' => '', - // 'Search by project: ' => '', - // 'Search by column: ' => '', - // 'Search by assignee: ' => '', - // 'Search by color: ' => '', - // 'Search by category: ' => '', - // 'Search by description: ' => '', - // 'Search by due date: ' => '', - // 'Lead and Cycle time for "%s"' => '', - // 'Average time spent into each column for "%s"' => '', - // 'Average time spent into each column' => '', - // 'Average time spent' => '', - // 'This chart show the average time spent into each column for the last %d tasks.' => '', - // 'Average Lead and Cycle time' => '', - // 'Average lead time: ' => '', - // 'Average cycle time: ' => '', - // 'Cycle Time' => '', - // 'Lead Time' => '', - // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', - // 'Average time into each column' => '', - // 'Lead and cycle time' => '', - // 'Lead time: ' => '', - // 'Cycle time: ' => '', - // 'Time spent into each column' => '', - // 'The lead time is the duration between the task creation and the completion.' => '', - // 'The cycle time is the duration between the start date and the completion.' => '', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - // 'Set automatically the start date' => '', - // 'Edit Authentication' => '', - // 'Remote user' => '', - // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', - // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - // 'New remote user' => '', - // 'New local user' => '', - // 'Default task color' => '', - // 'This feature does not work with all browsers.' => '', - // 'There is no destination project available.' => '', - // 'Trigger automatically subtask time tracking' => '', - // 'Include closed tasks in the cumulative flow diagram' => '', - // 'Current swimlane: %s' => '', - // 'Current column: %s' => '', - // 'Current category: %s' => '', - // 'no category' => '', - // 'Current assignee: %s' => '', - // 'not assigned' => '', - // 'Author:' => '', - // 'contributors' => '', - // 'License:' => '', - // 'License' => '', - // 'Enter the text below' => '', - // 'Gantt chart for %s' => '', - // 'Sort by position' => '', - // 'Sort by date' => '', - // 'Add task' => '', - // 'Start date:' => '', - // 'Due date:' => '', - // 'There is no start date or due date for this task.' => '', - // 'Moving or resizing a task will change the start and due date of the task.' => '', - // 'There is no task in your project.' => '', - // 'Gantt chart' => '', - // 'People who are project managers' => '', - // 'People who are project members' => '', - // 'NOK - Norwegian Krone' => '', - // 'Show this column' => '', - // 'Hide this column' => '', - // 'open file' => '', - // 'End date' => '', - // 'Users overview' => '', - // 'Members' => '', - // 'Shared project' => '', - // 'Project managers' => '', - // 'Gantt chart for all projects' => '', - // 'Projects list' => '', - // 'Gantt chart for this project' => '', - // 'Project board' => '', - // 'End date:' => '', - // 'There is no start date or end date for this project.' => '', - // 'Projects Gantt chart' => '', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - // 'Milestone' => '', - // 'Documentation: %s' => '', - // 'Switch to the Gantt chart view' => '', - // 'Reset the search/filter box' => '', - // 'Documentation' => '', - // 'Table of contents' => '', - // 'Gantt' => '', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - // 'Link type' => '', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - // 'Project members' => '', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/sv_SE/translations.php b/sources/app/Locale/sv_SE/translations.php deleted file mode 100644 index 88db5d6..0000000 --- a/sources/app/Locale/sv_SE/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => ',', - 'number.thousands_separator' => '.', - 'None' => 'Ingen', - 'edit' => 'redigera', - 'Edit' => 'Redigera', - 'remove' => 'ta bort', - 'Remove' => 'Ta bort', - 'Yes' => 'Ja', - 'No' => 'Nej', - 'cancel' => 'avbryt', - 'or' => 'eller', - 'Yellow' => 'Gul', - 'Blue' => 'Blå', - 'Green' => 'Grön', - 'Purple' => 'Lila', - 'Red' => 'Röd', - 'Orange' => 'Orange', - 'Grey' => 'Grå', - 'Brown' => 'Brun', - 'Deep Orange' => 'Mörkorange', - 'Dark Grey' => 'Mörkgrå', - 'Pink' => 'Rosa', - 'Teal' => 'Grönblå', - 'Cyan' => 'Cyan', - 'Lime' => 'Lime', - 'Light Green' => 'Ljusgrön', - 'Amber' => 'Bärnsten', - 'Save' => 'Spara', - 'Login' => 'Login', - 'Official website:' => 'Officiell webbsida:', - 'Unassigned' => 'Ej tilldelad', - 'View this task' => 'Se denna uppgift', - 'Remove user' => 'Ta bort användare', - 'Do you really want to remove this user: "%s"?' => 'Vill du verkligen ta bort användaren: "%s"?', - 'All users' => 'Alla användare', - 'Username' => 'Användarnamn', - 'Password' => 'Lösenord', - 'Administrator' => 'Administratör', - 'Sign in' => 'Logga in', - 'Users' => 'Användare', - 'No user' => 'Ingen användare', - 'Forbidden' => 'Ej tillåten', - 'Access Forbidden' => 'Ej tillåten', - 'Edit user' => 'Ändra användare', - 'Logout' => 'Logga ut', - 'Bad username or password' => 'Fel användarnamn eller lösenord', - 'Edit project' => 'Ändra projekt', - 'Name' => 'Namn', - 'Projects' => 'Projekt', - 'No project' => 'Inget projekt', - 'Project' => 'Tavlor för projekt och planering', - 'Status' => 'Status', - 'Tasks' => 'Uppgifter', - 'Board' => 'Tavla', - 'Actions' => 'Åtgärder', - 'Inactive' => 'Inaktiv', - 'Active' => 'Aktiv', - '%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', - 'Do you really want to remove this project: "%s"?' => 'Vill du verkligen ta bort projektet: "%s" ?', - 'Remove project' => 'Ta bort projekt', - 'Edit the board for "%s"' => 'Ändra tavlan för "%s"', - 'All projects' => 'Alla projekt', - 'Add a new column' => 'Lägg till ny kolumn', - '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!', - 'Settings' => 'Inställningar', - 'Application settings' => 'Applikationsinställningar', - 'Language' => 'Språk', - 'Webhook token:' => 'Token för webhooks:', - 'API token:' => 'API token:', - 'Database size:' => 'Databasstorlek:', - 'Download the database' => 'Ladda ner databasen', - 'Optimize the database' => 'Optimera databasen', - '(VACUUM command)' => '(Vacuum kommando)', - '(Gzip compressed Sqlite file)' => '(Gzip komprimera Sqlite filen)', - 'Close a task' => 'Stäng en uppgift', - 'Edit a task' => 'Ändra en uppgift', - 'Column' => 'Kolumn', - 'Color' => 'Färg', - 'Assignee' => 'Uppdragsinnehavare', - 'Create another task' => 'Skapa ännu en uppgift', - 'New task' => 'Ny uppgift', - 'Open a task' => 'Öppna en uppgift', - 'Do you really want to open this task: "%s"?' => 'Vill du verkligen öppna denna uppgift: "%s"?', - 'Back to the board' => 'Tillbaka till tavlan', - 'There is nobody assigned' => 'Det finns ingen tilldelad', - 'Column on the board:' => 'Kolumn på tavlan:', - 'Close this task' => 'Stäng uppgiften', - 'Open this task' => 'Öppna uppgiften', - 'There is no description.' => 'Det finns ingen beskrivning.', - 'Add a new task' => 'Lägg till en ny uppgift', - 'The username is required' => 'Användarnamnet måste anges', - 'The maximum length is %d characters' => 'Max antal bokstäver %d', - 'The minimum length is %d characters' => 'Minst antal bokstäver %d', - 'The password is required' => 'Lösenordet måste anges.', - 'This value must be an integer' => 'Detta värde måste vara ett heltal.', - 'The username must be unique' => 'Användarnamnet måste vara unikt', - 'The user id is required' => 'Användar-ID måste anges', - 'Passwords don\'t match' => 'Lösenorden matchar inte', - 'The confirmation is required' => 'Bekräftelse behövs.', - 'The project is required' => 'Projektet måste anges', - 'The id is required' => 'Aktuellt ID måste anges', - 'The project id is required' => 'Projekt-ID måste anges', - 'The project name is required' => 'Ett projektnamn måste anges', - 'The title is required' => 'En titel måste anges.', - 'Settings saved successfully.' => 'Inställningarna har sparats.', - 'Unable to save your settings.' => 'Kunde inte spara dina ändringar', - 'Database optimization done.' => 'Databasen har optimerats.', - 'Your project have been created successfully.' => 'Ditt projekt har skapats.', - 'Unable to create your project.' => 'Kunde inte skapa ditt projekt.', - 'Project updated successfully.' => 'Projektet har uppdaterats.', - 'Unable to update this project.' => 'Kunde inte uppdatera detta projekt.', - 'Unable to remove this project.' => 'Kunde inte ta bort detta projekt.', - 'Project removed successfully.' => 'Projektet har tagits bort.', - 'Project activated successfully.' => 'Projektet har aktiverats.', - 'Unable to activate this project.' => 'Kunde inte aktivera detta projekt.', - 'Project disabled successfully.' => 'Projektet har stängts.', - 'Unable to disable this project.' => 'Kunde inte stänga detta projekt.', - 'Unable to open this task.' => 'Kunde inte öppna denna uppgift.', - 'Task opened successfully.' => 'Uppgiften har öppnats.', - 'Unable to close this task.' => 'Kunde inte stänga denna uppgift.', - 'Task closed successfully.' => 'Uppgiften har stängts.', - 'Unable to update your task.' => 'Kunde inte uppdatera din uppgift.', - 'Task updated successfully.' => 'Uppgiften har uppdaterats.', - 'Unable to create your task.' => 'Kunde inte skapa din uppgift.', - 'Task created successfully.' => 'Uppgiften har skapats.', - 'User created successfully.' => 'Användaren har skapats.', - 'Unable to create your user.' => 'Kunde inte skapa din användare.', - 'User updated successfully.' => 'Användaren har updaterats.', - 'Unable to update your user.' => 'Kunde inte uppdatera din användare.', - 'User removed successfully.' => 'Användaren har tagits bort.', - 'Unable to remove this user.' => 'Kunde inte ta bort denna användare.', - 'Board updated successfully.' => 'Tavlan uppdaterad.', - 'Ready' => 'Denna månad', - 'Backlog' => 'Att göra', - 'Work in progress' => 'Pågående', - 'Done' => 'Slutfört', - 'Application version:' => 'Version:', - 'Id' => 'ID', - '%d closed tasks' => '%d stängda uppgifter', - 'No task for this project' => 'Inga uppgifter i detta projekt', - 'Public link' => 'Publik länk', - 'Timezone' => 'Tidszon', - 'Sorry, I didn\'t find this information in my database!' => 'Informationen kunde inte hittas i databasen.', - 'Page not found' => 'Sidan hittas inte', - 'Complexity' => 'Komplexitet', - 'Task limit' => 'Uppgiftsbegränsning', - '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', - 'Invalid date' => 'Ej tillåtet datum', - 'Automatic actions' => 'Automatiska åtgärder', - 'Your automatic action have been created successfully.' => 'Din automatiska åtgärd har skapats.', - 'Unable to create your automatic action.' => 'Kunde inte skapa din automatiska åtgärd.', - 'Remove an action' => 'Ta bort en åtgärd', - 'Unable to remove this action.' => 'Kunde inte ta bort denna åtgärd.', - 'Action removed successfully.' => 'Åtgärden har tagits bort.', - 'Automatic actions for the project "%s"' => 'Automatiska åtgärder för projektet "%s"', - 'Add an action' => 'Lägg till en åtgärd', - 'Event name' => 'Händelsenamn', - 'Action name' => 'Åtgärdsnamn', - 'Action parameters' => 'Åtgärdsparametrar', - 'Action' => 'Åtgärd', - 'Event' => 'Händelse', - 'When the selected event occurs execute the corresponding action.' => 'När händelsen inträffar, kör inställd åtgärd.', - 'Next step' => 'Nästa steg', - 'Define action parameters' => 'Definiera upp händelseparametrar', - 'Do you really want to remove this action: "%s"?' => 'Vill du verkligen ta bort denna åtgärd: "%s"?', - 'Remove an automatic action' => 'Ta bort en automatiskt åtgärd', - 'Assign the task to a specific user' => 'Tilldela uppgiften till en specifik användare', - 'Assign the task to the person who does the action' => 'Tilldela uppgiften till personen som skapar den', - 'Duplicate the task to another project' => 'Kopiera uppgiften till ett annat projekt', - 'Move a task to another column' => 'Flytta en uppgift till en annan kolumn', - 'Task modification' => 'Ändra uppgift', - 'Task creation' => 'Skapa uppgift', - 'Closing a task' => 'Stänger en uppgift', - 'Assign a color to a specific user' => 'Tilldela en färg till en specifik användare', - 'Column title' => 'Kolumnens titel', - 'Position' => 'Position', - 'Duplicate to another project' => 'Kopiera till ett annat projekt', - 'Duplicate' => 'Kopiera uppgiften', - 'link' => 'länk', - 'Comment updated successfully.' => 'Kommentaren har uppdaterats.', - 'Unable to update your comment.' => 'Kunde inte uppdatera din kommentar.', - 'Remove a comment' => 'Ta bort en kommentar', - 'Comment removed successfully.' => 'Kommentaren har tagits bort.', - 'Unable to remove this comment.' => 'Kunde inte ta bort denna kommentar.', - 'Do you really want to remove this comment?' => 'Är du säker på att du vill ta bort denna kommentar?', - 'Current password for the user "%s"' => 'Nuvarande lösenord för användaren %s"', - 'The current password is required' => 'Det nuvarande lösenordet måste anges', - 'Wrong password' => 'Fel lösenord', - 'Unknown' => 'Okänd', - 'Last logins' => 'Senaste inloggningarna', - 'Login date' => 'Inloggningsdatum', - 'Authentication method' => 'Autentiseringsmetoder', - 'IP address' => 'IP-adress', - 'User agent' => 'Användaragent/webbläsare', - 'Persistent connections' => 'Beständiga anslutningar', - 'No session.' => 'Ingen session.', - 'Expiration date' => 'Förfallodatum', - 'Remember Me' => 'Kom ihåg mig', - 'Creation date' => 'Skapatdatum', - 'Everybody' => 'Alla', - 'Open' => 'Öppen', - 'Closed' => 'Stängd', - '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', - 'Email address invalid' => 'Epost-adressen ogiltig', - 'Your external account is not linked anymore to your profile.' => 'Ditt externa konto är inte längre länkad till din profil.', - 'Unable to unlink your external account.' => 'Kunde inte koppla från ditt externa konto.', - 'External authentication failed' => 'Extern autentisering misslyckades', - 'Your external account is linked to your profile successfully.' => 'Ditt externa konto länkades till din profil.', - 'Email' => 'Epost', - 'Task removed successfully.' => 'Uppgiften har tagits bort', - 'Unable to remove this task.' => 'Kunde inte ta bort denna uppgift', - 'Remove a task' => 'Ta bort en uppgift', - 'Do you really want to remove this task: "%s"?' => 'Vill du verkligen ta bort denna uppgift: "%s"?', - 'Assign automatically a color based on a category' => 'Tilldela automatiskt en färg baserad på en kategori', - 'Assign automatically a category based on a color' => 'Tilldela automatiskt en kategori baserad på en färg', - 'Task creation or modification' => 'Skapa eller ändra uppgift', - 'Category' => 'Kategori', - 'Category:' => 'Kategori:', - 'Categories' => 'Ange kategorier', - 'Your category have been created successfully.' => 'Din kategori har skapats', - 'Unable to create your category.' => 'Kunde inte skapa din kategori', - 'Your category have been updated successfully.' => 'Din kategori har uppdaterats', - 'Unable to update your category.' => 'Kunde inte uppdatera din kategori', - 'Remove a category' => 'Ta bort en kategori', - 'Category removed successfully.' => 'Kategorin har tagits bort', - 'Unable to remove this category.' => 'Kunde inte ta bort denna kategori', - 'Category modification for the project "%s"' => 'Ändring av kategori för projektet "%s"', - 'Category Name' => 'Kategorinamn', - 'Add a new category' => 'Lägg till en kategori', - 'Do you really want to remove this category: "%s"?' => 'Vill du verkligen ta bort denna kategori: "%s"?', - 'All categories' => 'Alla kategorier', - 'No category' => 'Ingen kategori', - 'The name is required' => 'Namnet måste anges', - 'Remove a file' => 'Ta bort en fil', - 'Unable to remove this file.' => 'Kunde inte ta bort denna fil', - 'File removed successfully.' => 'Filen har tagits bort', - 'Attach a document' => 'Bifoga ett dokument', - 'Do you really want to remove this file: "%s"?' => 'Vill du verkligen ta bort denna fil:"%s"?', - 'Attachments' => 'Bifogade filer', - 'Edit the task' => 'Ändra uppgiften', - 'Add a comment' => 'Lägg till kommentar', - 'Edit a comment' => 'Ändra en kommentar', - 'Summary' => 'Sammanfattning', - 'Time tracking' => 'Tidsåtgång', - 'Estimate:' => 'Uppskattning', - 'Spent:' => 'Nedlagd tid', - 'Do you really want to remove this sub-task?' => 'Vill du verkligen ta bort deluppgiften?', - 'Remaining:' => 'Återstående:', - 'hours' => 'timmar', - 'spent' => 'nedlagt', - 'estimated' => 'uppskattat', - 'Sub-Tasks' => 'Deluppgifter', - 'Add a sub-task' => 'Lägg till deluppgift', - 'Original estimate' => 'Ursprunglig uppskattning', - 'Create another sub-task' => 'Skapa en till deluppgift', - 'Time spent' => 'Nedlagd tid', - 'Edit a sub-task' => 'Ändra en deluppgift', - 'Remove a sub-task' => 'Ta bort en deluppgift', - 'The time must be a numeric value' => 'Tiden måste ha ett numeriskt värde', - 'Todo' => 'Att göra', - 'In progress' => 'Pågående', - 'Sub-task removed successfully.' => 'Deluppgiften har tagits bort.', - 'Unable to remove this sub-task.' => 'Kunde inte ta bort denna deluppgift.', - 'Sub-task updated successfully.' => 'Deluppgiften har uppdaterats.', - 'Unable to update your sub-task.' => 'Kunde inte uppdatera din deluppgift.', - 'Unable to create your sub-task.' => 'Kunde inte skapa din deluppgift.', - 'Sub-task added successfully.' => 'Deluppgiften har lagts till.', - 'Maximum size: ' => 'Maxstorlek: ', - 'Unable to upload the file.' => 'Kunde inte ladda upp filen.', - 'Display another project' => 'Visa ett annat projekt', - 'Created by %s' => 'Skapad av %s', - 'Tasks Export' => 'Exportera uppgifter', - 'Tasks exportation for "%s"' => 'Exportera uppgifter för "%s"', - 'Start Date' => 'Startdatum', - 'End Date' => 'Slutdatum', - 'Execute' => 'Utför', - 'Task Id' => 'Uppgift ID', - 'Creator' => 'Skapare', - 'Modification date' => 'Ändringsdatum', - 'Completion date' => 'Slutfört datum', - 'Clone' => 'Klona', - 'Project cloned successfully.' => 'Projektet har klonats.', - 'Unable to clone this project.' => 'Kunde inte klona projektet.', - 'Enable email notifications' => 'Aktivera epostnotiser', - 'Task position:' => 'Uppgiftsposition:', - 'The task #%d have been opened.' => 'Uppgiften #%d har öppnats.', - 'The task #%d have been closed.' => 'Uppgiften #%d har stängts.', - 'Sub-task updated' => 'Deluppgift uppdaterad', - 'Title:' => 'Titel:', - 'Status:' => 'Status:', - 'Assignee:' => 'Tilldelad:', - 'Time tracking:' => 'Tidsspårning', - 'New sub-task' => 'Ny deluppgift', - 'New attachment added "%s"' => 'Ny bifogning tillagd "%s"', - 'New comment posted by %s' => 'Ny kommentar postad av %s', - 'New attachment' => 'Ny bifogning', - 'New comment' => 'Ny kommentar', - 'Comment updated' => 'Kommentaren har uppdaterats', - 'New subtask' => 'Ny deluppgift', - 'Subtask updated' => 'Deluppgiften har uppdaterats', - 'Task updated' => 'Uppgiften har uppdaterats', - 'Task closed' => 'Uppgiften har stängts', - 'Task opened' => 'Uppgiften har öppnats', - 'I want to receive notifications only for those projects:' => 'Jag vill endast få notiser för dessa projekt:', - 'view the task on Kanboard' => 'Visa uppgiften på Kanboard', - 'Public access' => 'Publik åtkomst', - 'Active tasks' => 'Aktiva uppgifter', - 'Disable public access' => 'Inaktivera publik åtkomst', - 'Enable public access' => 'Aktivera publik åtkomst', - 'Public access disabled' => 'Publik åtkomst har inaktiverats', - 'Do you really want to disable this project: "%s"?' => 'Vill du verkligen inaktivera detta projekt: "%s"?', - 'Do you really want to enable this project: "%s"?' => 'Vill du verkligen aktivera detta projekt: "%s"?', - 'Project activation' => 'Projektaktivering', - 'Move the task to another project' => 'Flytta uppgiften till ett annat projekt', - 'Move to another project' => 'Flytta till ett annat projekt', - 'Do you really want to duplicate this task?' => 'Vill du verkligen kopiera denna uppgift?', - 'Duplicate a task' => 'Kopiera en uppgift', - 'External accounts' => 'Externa konton', - 'Account type' => 'Kontotyp', - 'Local' => 'Lokal', - 'Remote' => 'Fjärr', - 'Enabled' => 'Aktiverad', - 'Disabled' => 'Inaktiverad', - 'Username:' => 'Användarnam:', - 'Name:' => 'Namn:', - 'Email:' => 'E-post:', - 'Notifications:' => 'Notiser:', - 'Notifications' => 'Notiser', - 'Account type:' => 'Kontotyp:', - 'Edit profile' => 'Ändra profil', - 'Change password' => 'Byt lösenord', - 'Password modification' => 'Ändra lösenord', - 'External authentications' => 'Extern autentisering', - 'Never connected.' => 'Inte ansluten.', - 'No external authentication enabled.' => 'Ingen extern autentisering aktiverad.', - 'Password modified successfully.' => 'Lösenordet har ändrats.', - 'Unable to change the password.' => 'Kunde inte byta lösenord.', - 'Change category' => 'Byt kategori', - '%s updated the task %s' => '%s uppdaterade uppgiften %s', - '%s opened the task %s' => '%s öppna uppgiften %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s flyttade uppgiften %s till positionen #%d i kolumnen "%s"', - '%s moved the task %s to the column "%s"' => '%s flyttade uppgiften %s till kolumnen "%s"', - '%s created the task %s' => '%s skapade uppgiften %s', - '%s closed the task %s' => '%s stängde uppgiften %s', - '%s created a subtask for the task %s' => '%s skapade en deluppgift för uppgiften %s', - '%s updated a subtask for the task %s' => '%s uppdaterade en deluppgift för uppgiften %s', - 'Assigned to %s with an estimate of %s/%sh' => 'Tilldelades %s med en uppskattning på %s/%sh', - 'Not assigned, estimate of %sh' => 'Inte tilldelade, uppskattat %sh', - '%s updated a comment on the task %s' => '%s uppdaterade en kommentar till uppgiften %s', - '%s commented the task %s' => '%s kommenterade uppgiften %s', - '%s\'s activity' => '%s\'s aktivitet', - 'RSS feed' => 'RSS flöde', - '%s updated a comment on the task #%d' => '%s uppdaterade en kommentar på uppgiften #%d', - '%s commented on the task #%d' => '%s kommenterade uppgiften #%d', - '%s updated a subtask for the task #%d' => '%s uppdaterade en deluppgift för uppgiften #%d', - '%s created a subtask for the task #%d' => '%s skapade en deluppgift för uppgiften #%d', - '%s updated the task #%d' => '%s uppdaterade uppgiften #%d', - '%s created the task #%d' => '%s skapade uppgiften #%d', - '%s closed the task #%d' => '%s stängde uppgiften #%d', - '%s open the task #%d' => '%s öppnade uppgiften #%d', - '%s moved the task #%d to the column "%s"' => '%s flyttade uppgiften #%d till kolumnen "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s flyttade uppgiften #%d till positionen %d i kolumnen "%s"', - 'Activity' => 'Aktivitet', - 'Default values are "%s"' => 'Standardvärden är "%s"', - 'Default columns for new projects (Comma-separated)' => 'Standardkolumner för nya projekt (kommaseparerade)', - 'Task assignee change' => 'Ändra tilldelning av uppgiften', - '%s change the assignee of the task #%d to %s' => '%s byt tilldelning av uppgiften #%d till %s', - '%s changed the assignee of the task %s to %s' => '%s byt tilldelning av uppgiften %s till %s', - 'New password for the user "%s"' => 'Nytt lösenord för användaren "%s"', - 'Choose an event' => 'Välj en händelse', - 'Create a task from an external provider' => 'Skapa en uppgift från en extern leverantör', - 'Change the assignee based on an external username' => 'Ändra tilldelning baserat på ett externt användarnamn', - 'Change the category based on an external label' => 'Ändra kategori baserat på en extern etikett', - 'Reference' => 'Referens', - 'Label' => 'Etikett', - 'Database' => 'Databas', - 'About' => 'Om', - 'Database driver:' => 'Databasdrivrutin:', - 'Board settings' => 'Inställningar för tavla', - 'Webhook settings' => 'Webhook inställningar', - 'Reset token' => 'Nollställ token', - 'API endpoint:' => 'API ändpunkt:', - 'Refresh interval for private board' => 'Uppdateringsintervall för privat tavla', - 'Refresh interval for public board' => 'Uppdateringsintervall för publik tavla', - 'Task highlight period' => 'Period att framhäva ny uppgift', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Period (i sekunder) att betrakta en uppgifts ändring som ny (ange 0 för att inaktivera, 2 dagar är standard)', - 'Frequency in second (60 seconds by default)' => 'Frekvens i sekunder (60 sekunder är standard)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Frekvens i sekunder (ange 0 för att inaktivera, 10 sekunder är standard)', - 'Application URL' => 'Applikations-URL', - 'Token regenerated.' => 'Token nyskapad.', - 'Date format' => 'Datumformat', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO-format är alltid tillåtet, exempel: "%s" och "%s"', - 'New private project' => 'Nytt privat projekt', - 'This project is private' => 'Det här projektet är privat', - 'Add' => 'Lägg till', - 'Start date' => 'Startdatum', - 'Time estimated' => 'Uppskattad tid', - 'There is nothing assigned to you.' => 'Du har inget tilldelat till dig.', - 'My tasks' => 'Mina uppgifter', - 'Activity stream' => 'Aktivitetsström', - 'Dashboard' => 'Instrumentpanel', - 'Confirmation' => 'Bekräftelse', - 'Allow everybody to access to this project' => 'Ge alla tillgång till projektet', - 'Everybody have access to this project.' => 'Alla har tillgång till projektet', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Skapa en kommentar från en extern leverantör', - 'Project management' => 'Projekthantering', - 'My projects' => 'Mina projekt', - 'Columns' => 'Kolumner', - 'Task' => 'Uppgift', - 'Your are not member of any project.' => 'Du är inte medlem i något projekt', - 'Percentage' => 'Procent', - 'Number of tasks' => 'Antal uppgifter', - 'Task distribution' => 'Uppgiftsfördelning', - 'Reportings' => 'Rapportering', - 'Task repartition for "%s"' => 'Uppgiftsdeltagande för "%s"', - 'Analytics' => 'Analyser', - 'Subtask' => 'Deluppgift', - 'My subtasks' => 'Mina deluppgifter', - 'User repartition' => 'Användardeltagande', - 'User repartition for "%s"' => 'Användardeltagande för "%s"', - 'Clone this project' => 'Klona projektet', - 'Column removed successfully.' => 'Kolumnen togs bort', - 'Not enough data to show the graph.' => 'Inte tillräckligt med data för att visa graf', - 'Previous' => 'Föregående', - 'The id must be an integer' => 'ID måste vara ett heltal', - 'The project id must be an integer' => 'Projekt-ID måste vara ett heltal', - 'The status must be an integer' => 'Status måste vara ett heltal', - 'The subtask id is required' => 'Deluppgifts-ID behövs', - 'The subtask id must be an integer' => 'Deluppgifts-ID måste vara ett heltal', - 'The task id is required' => 'Uppgifts-ID behövs', - 'The task id must be an integer' => 'Uppgifts-ID måste vara ett heltal', - 'The user id must be an integer' => 'Användar-ID måste vara ett heltal', - 'This value is required' => 'Värdet behövs', - 'This value must be numeric' => 'Värdet måste vara numeriskt', - 'Unable to create this task.' => 'Kunde inte skapa uppgiften.', - 'Cumulative flow diagram' => 'Diagram med kumulativt flöde', - 'Cumulative flow diagram for "%s"' => 'Diagram med kumulativt flöde för "%s"', - 'Daily project summary' => 'Daglig projektsummering', - 'Daily project summary export' => 'Export av daglig projektsummering', - 'Daily project summary export for "%s"' => 'Export av daglig projektsummering för "%s"', - 'Exports' => 'Exporter', - 'This export contains the number of tasks per column grouped per day.' => 'Denna export innehåller antalet uppgifter per kolumn grupperade per dag.', - 'Active swimlanes' => 'Aktiva swimlanes', - 'Add a new swimlane' => 'Lägg till en nytt swimlane', - 'Change default swimlane' => 'Ändra standard swimlane', - 'Default swimlane' => 'Standard swimlane', - 'Do you really want to remove this swimlane: "%s"?' => 'Vill du verkligen ta bort denna swimlane: "%s"?', - 'Inactive swimlanes' => 'Inaktiv swimlane', - 'Remove a swimlane' => 'Ta bort en swimlane', - 'Show default swimlane' => 'Visa standard swimlane', - 'Swimlane modification for the project "%s"' => 'Ändra swimlane för projektet "%s"', - 'Swimlane removed successfully.' => 'Swimlane togs bort', - 'Swimlanes' => 'Swimlanes', - 'Swimlane updated successfully.' => 'Swimlane uppdaterad', - 'The default swimlane have been updated successfully.' => 'Standardswimlane har uppdaterats', - 'Unable to remove this swimlane.' => 'Kunde inte ta bort swimlane', - 'Unable to update this swimlane.' => 'Kunde inte uppdatera swimlane', - 'Your swimlane have been created successfully.' => 'Din swimlane har skapats', - 'Example: "Bug, Feature Request, Improvement"' => 'Exempel: "Bug, ny funktionalitet, förbättringar"', - 'Default categories for new projects (Comma-separated)' => 'Standardkategorier för nya projekt (komma-separerade)', - 'Integrations' => 'Integrationer', - 'Integration with third-party services' => 'Integration med tjänst från tredjepart', - 'Subtask Id' => 'Deluppgifts-ID', - 'Subtasks' => 'Deluppgift', - 'Subtasks Export' => 'Export av deluppgifter', - 'Subtasks exportation for "%s"' => 'Export av deluppgifter för "%s"', - 'Task Title' => 'Uppgiftstitel', - 'Untitled' => 'Titel saknas', - 'Application default' => 'Applikationsstandard', - 'Language:' => 'Språk', - 'Timezone:' => 'Tidszon', - 'All columns' => 'Alla kolumner', - 'Calendar' => 'Kalender', - 'Next' => 'Nästa', - '#%d' => '#%d', - 'All swimlanes' => 'Alla swimlanes', - 'All colors' => 'Alla färger', - 'Moved to column %s' => 'Flyttad till kolumn %s', - 'User dashboard' => 'Användardashboard', - 'Allow only one subtask in progress at the same time for a user' => 'Tillåt endast en deluppgift igång samtidigt för en användare', - 'Edit column "%s"' => 'Ändra kolumn "%s"', - 'Select the new status of the subtask: "%s"' => 'Välj ny status för deluppgiften: "%s"', - 'Subtask timesheet' => 'Tidrapport för deluppgiften', - 'There is nothing to show.' => 'Det finns inget att visa', - 'Time Tracking' => 'Tidsbevakning', - 'You already have one subtask in progress' => 'Du har redan en deluppgift igång', - 'Which parts of the project do you want to duplicate?' => 'Vilka delar av projektet vill du duplicera?', - // 'Disallow login form' => '', - 'Start' => 'Start', - 'End' => 'Slut', - 'Task age in days' => 'Uppgiftsålder i dagar', - 'Days in this column' => 'Dagar i denna kolumn', - '%dd' => '%dd', - 'Add a new link' => 'Lägg till ny länk', - 'Do you really want to remove this link: "%s"?' => 'Vill du verkligen ta bort länken: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'Vill du verkligen ta bort länken till uppgiften #%d?', - 'Field required' => 'Fältet krävs', - 'Link added successfully.' => 'Länken har lagts till', - 'Link updated successfully.' => 'Länken har uppdaterats', - 'Link removed successfully.' => 'Länken har tagits bort', - 'Link labels' => 'Länketiketter', - 'Link modification' => 'Länkändring', - 'Links' => 'Länkar', - 'Link settings' => 'Länkinställningar', - 'Opposite label' => 'Motpartslänk', - 'Remove a link' => 'Ta bort en länk', - 'Task\'s links' => 'Uppgiftslänkar', - 'The labels must be different' => 'Etiketterna måste vara olika', - 'There is no link.' => 'Det finns ingen länk', - 'This label must be unique' => 'Länken måste vara unik', - 'Unable to create your link.' => 'Kunde inte skapa din länk', - 'Unable to update your link.' => 'Kunde inte uppdatera din länk', - 'Unable to remove this link.' => 'Kunde inte ta bort din länk', - 'relates to' => 'relaterar till', - 'blocks' => 'blockerar', - 'is blocked by' => 'blockeras av', - 'duplicates' => 'dupplicerar', - 'is duplicated by' => 'är duplicerad av', - 'is a child of' => 'är underliggande till', - 'is a parent of' => 'är överliggande till', - 'targets milestone' => 'milstolpemål', - 'is a milestone of' => 'är en milstolpe för', - 'fixes' => 'åtgärdar', - 'is fixed by' => 'åtgärdas av', - 'This task' => 'Denna uppgift', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => 'Expandera uppgifter', - 'Collapse tasks' => 'Minimera uppgifter', - 'Expand/collapse tasks' => 'Expandera/minimera uppgifter', - 'Close dialog box' => 'Stäng dialogruta', - 'Submit a form' => 'Sänd formulär', - 'Board view' => 'Tavelvy', - 'Keyboard shortcuts' => 'Tangentbordsgenvägar', - 'Open board switcher' => 'Växling av öppen tavla', - 'Application' => 'Applikation', - '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', - 'CAD - Canadian Dollar' => 'CAD - Kanadensiska dollar', - 'CHF - Swiss Francs' => 'CHF - Schweiziska Franc', - 'Custom Stylesheet' => 'Anpassad stilmall', - 'download' => 'ladda ned', - 'EUR - Euro' => 'EUR - Euro', - 'GBP - British Pound' => 'GBP - Brittiska Pund', - 'INR - Indian Rupee' => 'INR - Indiska Rupier', - 'JPY - Japanese Yen' => 'JPY - Japanska Yen', - 'NZD - New Zealand Dollar' => 'NZD - Nya Zeeländska Dollar', - 'RSD - Serbian dinar' => 'RSD - Serbiska Dinarer', - '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', - 'Move the task to another column when assignee is cleared' => 'Flytta uppgiften till en annan kolumn när tilldelningen tas bort.', - 'Source column' => 'Källkolumn', - 'Transitions' => 'Övergångar', - 'Executer' => 'Verkställare', - 'Time spent in the column' => 'Tid i kolumnen.', - 'Task transitions' => 'Uppgiftsövergångar', - 'Task transitions export' => 'Export av uppgiftsövergångar', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'Denna rapport innehåller alla kolumnförflyttningar för varje uppgift med datum, användare och nedlagd tid vid varje övergång.', - '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.', - 'Webhook URL' => 'Webhook URL', - '%s remove the assignee of the task %s' => '%s ta bort tilldelningen av uppgiften %s', - 'Enable Gravatar images' => 'Aktivera Gravatar bilder', - 'Information' => 'Information', - 'Check two factor authentication code' => 'Kolla tvåfaktorsverifieringskod', - 'The two factor authentication code is not valid.' => 'Tvåfaktorsverifieringskoden är inte giltig.', - 'The two factor authentication code is valid.' => 'Tvåfaktorsverifieringskoden är giltig.', - 'Code' => 'Kod', - 'Two factor authentication' => 'Tvåfaktorsverifiering', - 'This QR code contains the key URI: ' => 'Denna QR-kod innehåller nyckel-URI:n', - 'Check my code' => 'Kolla min kod', - 'Secret key: ' => 'Säkerhetsnyckel:', - 'Test your device' => 'Testa din enhet', - 'Assign a color when the task is moved to a specific column' => 'Tilldela en färg när uppgiften flyttas till en specifik kolumn', - '%s via Kanboard' => '%s via Kanboard', - 'Burndown chart for "%s"' => 'Burndown diagram för "%s"', - 'Burndown chart' => 'Burndown diagram', - 'This chart show the task complexity over the time (Work Remaining).' => 'Diagrammet visar uppgiftens svårighet över tid (återstående arbete).', - 'Screenshot taken %s' => 'Skärmdump tagen %s', - 'Add a screenshot' => 'Lägg till en skärmdump', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Ta en skärmdump och tryck CTRL+V för att klistra in här.', - 'Screenshot uploaded successfully.' => 'Skärmdumpen laddades upp.', - 'SEK - Swedish Krona' => 'SEK - Svensk Krona', - 'Identifier' => 'Identifierare', - 'Disable two factor authentication' => 'Inaktivera två-faktors autentisering', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'Vill du verkligen inaktivera två-faktors autentisering för denna användare: "%s"?', - 'Edit link' => 'Ändra länk', - 'Start to type task title...' => 'Börja skriv uppgiftstitel...', - 'A task cannot be linked to itself' => 'En uppgift kan inte länkas till sig själv', - 'The exact same link already exists' => 'Länken existerar redan', - 'Recurrent task is scheduled to be generated' => 'Återkommande uppgift är schemalagd att genereras', - 'Score' => 'Poäng', - 'The identifier must be unique' => 'Identifieraren måste vara unik', - 'This linked task id doesn\'t exists' => 'Denna länkade uppgifts id existerar inte', - 'This value must be alphanumeric' => 'Värdet måste vara alfanumeriskt', - 'Edit recurrence' => 'Ändra återkommande', - 'Generate recurrent task' => 'Generera återkommande uppgift', - 'Trigger to generate recurrent task' => 'Aktivera att generera återkommande uppgift', - 'Factor to calculate new due date' => 'Faktor för att beräkna nytt datum', - 'Timeframe to calculate new due date' => 'Tidsram för att beräkna nytt datum', - 'Base date to calculate new due date' => 'Basdatum för att beräkna nytt datum', - 'Action date' => 'Händelsedatum', - 'Base date to calculate new due date: ' => 'Basdatum för att beräkna nytt förfallodatum: ', - 'This task has created this child task: ' => 'Uppgiften har skapat denna underliggande uppgift: ', - 'Day(s)' => 'Dag(ar)', - 'Existing due date' => 'Existerande förfallodatum', - 'Factor to calculate new due date: ' => 'Faktor för att beräkna nytt förfallodatum: ', - 'Month(s)' => 'Månad(er)', - 'Recurrence' => 'Återkommande', - 'This task has been created by: ' => 'Uppgiften har skapats av: ', - 'Recurrent task has been generated:' => 'Återkommande uppgift har genererats:', - 'Timeframe to calculate new due date: ' => 'Tidsram för att beräkna nytt förfallodatum: ', - 'Trigger to generate recurrent task: ' => 'Aktivera att generera återkommande uppgift: ', - 'When task is closed' => 'När uppgiften är stängd', - 'When task is moved from first column' => 'När uppgiften flyttas från första kolumnen', - 'When task is moved to last column' => 'När uppgiften flyttas till sista kolumnen', - 'Year(s)' => 'År', - 'Calendar settings' => 'Inställningar för kalendern', - 'Project calendar view' => 'Projektkalendervy', - 'Project settings' => 'Projektinställningar', - 'Show subtasks based on the time tracking' => 'Visa deluppgifter baserade på tidsspårning', - 'Show tasks based on the creation date' => 'Visa uppgifter baserade på skapat datum', - 'Show tasks based on the start date' => 'Visa uppgifter baserade på startdatum', - 'Subtasks time tracking' => 'Deluppgifter tidsspårning', - 'User calendar view' => 'Användarkalendervy', - 'Automatically update the start date' => 'Automatisk uppdatering av startdatum', - 'iCal feed' => 'iCal flöde', - 'Preferences' => 'Preferenser', - 'Security' => 'Säkerhet', - 'Two factor authentication disabled' => 'Tvåfaktorsverifiering inaktiverad', - 'Two factor authentication enabled' => 'Tvåfaktorsverifiering aktiverad', - 'Unable to update this user.' => 'Kunde inte uppdatera användaren.', - 'There is no user management for private projects.' => 'Det finns ingen användarhantering för privata projekt.', - 'User that will receive the email' => 'Användare som kommer att ta emot mailet', - 'Email subject' => 'E-post ämne', - 'Date' => 'Datum', - 'Add a comment log when moving the task between columns' => 'Lägg till en kommentarslogg när en uppgift flyttas mellan kolumner', - 'Move the task to another column when the category is changed' => 'Flyttas uppgiften till en annan kolumn när kategorin ändras', - 'Send a task by email to someone' => 'Skicka en uppgift med e-post till någon', - 'Reopen a task' => 'Återöppna en uppgift', - 'Column change' => 'Kolumnändring', - 'Position change' => 'Positionsändring', - 'Swimlane change' => 'Swimlaneändring', - 'Assignee change' => 'Tilldelningsändring', - '[%s] Overdue tasks' => '[%s] Försenade uppgifter', - 'Notification' => 'Notis', - '%s moved the task #%d to the first swimlane' => '%s flyttade uppgiften #%d till första swimlane', - '%s moved the task #%d to the swimlane "%s"' => '%s flyttade uppgiften #%d till swimlane "%s"', - 'Swimlane' => 'Swimlane', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s flyttade uppgiften %s till första swimlane', - '%s moved the task %s to the swimlane "%s"' => '%s flyttade uppgiften %s till swimlane "%s"', - 'This report contains all subtasks information for the given date range.' => 'Denna rapport innehåller all deluppgiftsinformation för det givna datumintervallet.', - 'This report contains all tasks information for the given date range.' => 'Denna rapport innehåller all uppgiftsinformation för det givna datumintervallet.', - 'Project activities for %s' => 'Projektaktiviteter för %s', - 'view the board on Kanboard' => 'visa tavlan på Kanboard', - 'The task have been moved to the first swimlane' => 'Uppgiften har flyttats till första swimlane', - 'The task have been moved to another swimlane:' => 'Uppgiften har flyttats till en annan swimlane:', - 'New title: %s' => 'Ny titel: %s', - 'The task is not assigned anymore' => 'Uppgiften är inte länge tilldelad', - 'New assignee: %s' => 'Ny tilldelning: %s', - 'There is no category now' => 'Det finns ingen kategori nu', - 'New category: %s' => 'Ny kategori: %s', - 'New color: %s' => 'Ny färg: %s', - 'New complexity: %d' => 'Ny komplexitet: %d', - 'The due date have been removed' => 'Förfallodatumet har tagits bort', - 'There is no description anymore' => 'Det finns ingen beskrivning längre', - 'Recurrence settings have been modified' => 'Återkommande inställning har ändrats', - 'Time spent changed: %sh' => 'Spenderad tid har ändrats: %sh', - 'Time estimated changed: %sh' => 'Tidsuppskattning ändrad: %sh', - 'The field "%s" have been updated' => 'Fältet "%s" har uppdaterats', - 'The description has been modified:' => 'Beskrivningen har modifierats', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'Vill du verkligen stänga uppgiften "%s" och alla deluppgifter?', - 'I want to receive notifications for:' => 'Jag vill få notiser för:', - 'All tasks' => 'Alla uppgifter', - 'Only for tasks assigned to me' => 'Bara för uppgifter tilldelade mig', - 'Only for tasks created by me' => 'Bara för uppgifter skapade av mig', - 'Only for tasks created by me and assigned to me' => 'Bara för uppgifter skapade av mig och tilldelade till mig', - '%%Y-%%m-%%d' => '%%Y-%%m-%%d', - 'Total for all columns' => 'Totalt för alla kolumner', - 'You need at least 2 days of data to show the chart.' => 'Du behöver minst två dagars data för att visa diagrammet.', - '<15m' => '<15m', - '<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', - 'Reset filters' => 'Återställ filter', - 'My tasks due tomorrow' => 'Mina uppgifter förfaller imorgon', - 'Tasks due today' => 'Uppgifter förfaller idag', - 'Tasks due tomorrow' => 'Uppgifter förfaller imorgon', - 'Tasks due yesterday' => 'Uppgifter förföll igår', - 'Closed tasks' => 'Stängda uppgifter', - 'Open tasks' => 'Öppna uppgifter', - 'Not assigned' => 'Inte tilldelad', - 'View advanced search syntax' => 'Visa avancerad söksyntax', - 'Overview' => 'Översikts', - 'Board/Calendar/List view' => 'Tavla/Kalender/Listvy', - 'Switch to the board view' => 'Växla till tavelvy', - 'Switch to the calendar view' => 'Växla till kalendervy', - 'Switch to the list view' => 'Växla till listvy', - 'Go to the search/filter box' => 'Gå till sök/filter box', - 'There is no activity yet.' => 'Det finns ingen aktivitet ännu.', - 'No tasks found.' => 'Inga uppgifter hittades.', - 'Keyboard shortcut: "%s"' => 'Tangentbordsgenväg: "%s"', - 'List' => 'Lista', - 'Filter' => 'Filter', - 'Advanced search' => 'Avancerad sök', - 'Example of query: ' => 'Exempel på fråga', - 'Search by project: ' => 'Sök efter projekt:', - 'Search by column: ' => 'Sök efter kolumn:', - 'Search by assignee: ' => 'Sök efter tilldelad:', - 'Search by color: ' => 'Sök efter färg:', - 'Search by category: ' => 'Sök efter kategori:', - 'Search by description: ' => 'Sök efter beskrivning', - 'Search by due date: ' => 'Sök efter förfallodatum', - 'Lead and Cycle time for "%s"' => 'Led- och cykeltid för "%s"', - 'Average time spent into each column for "%s"' => 'Medeltidsåtgång i varje kolumn för "%s"', - 'Average time spent into each column' => 'Medeltidsåtgång i varje kolumn', - 'Average time spent' => 'Medeltidsåtgång', - 'This chart show the average time spent into each column for the last %d tasks.' => 'Diagramet visar medeltidsåtgång i varje kolumn för de senaste %d uppgifterna.', - 'Average Lead and Cycle time' => 'Medel av led och cykeltid', - 'Average lead time: ' => 'Medel av ledtid', - 'Average cycle time: ' => 'Medel av cykeltid', - 'Cycle Time' => 'Cykeltid', - 'Lead Time' => 'Ledtid', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Diagramet visar medel av led och cykeltid för de senaste %d uppgifterna över tiden.', - 'Average time into each column' => 'Medeltidsåtgång i varje kolumn', - 'Lead and cycle time' => 'Led och cykeltid', - 'Lead time: ' => 'Ledtid', - 'Cycle time: ' => 'Cykeltid', - 'Time spent into each column' => 'Tidsåtgång per kolumn', - 'The lead time is the duration between the task creation and the completion.' => 'Ledtiden är varaktigheten mellan uppgiftens skapande och slutförande.', - 'The cycle time is the duration between the start date and the completion.' => 'Cykeltiden är varaktigheten mellan uppgiftens startdatum och slut.', - 'If the task is not closed the current time is used instead of the completion date.' => 'Om uppgiften inte är stängd används nuvarande tid istället för slutförandedatum.', - 'Set automatically the start date' => 'Sätt startdatum automatiskt', - 'Edit Authentication' => 'Ändra autentisering', - '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.', - 'Trigger automatically subtask time tracking' => 'Aktivera automatisk tidsbevakning av deluppgifter', - 'Include closed tasks in the cumulative flow diagram' => 'Inkludera stängda uppgifter i digrammet med kumulativt flöde', - 'Current swimlane: %s' => 'Nuvarande swimlane: %s', - 'Current column: %s' => 'Nuvarande kolumn: %s', - 'Current category: %s' => 'Nuvarande kategori: %s', - 'no category' => 'ingen kategori', - 'Current assignee: %s' => 'Nuvarande tilldelning: %s', - 'not assigned' => 'inte tilldelad', - 'Author:' => 'Upphovsman:', - 'contributors' => 'bidragare:', - 'License:' => 'Licens:', - 'License' => 'Licens', - 'Enter the text below' => 'Fyll i texten nedan', - 'Gantt chart for %s' => 'Gantt-schema för %s', - 'Sort by position' => 'Sortera efter position', - 'Sort by date' => 'Sortera efter datum', - 'Add task' => 'Lägg till uppgift', - 'Start date:' => 'Startdatum:', - 'Due date:' => 'Slutdatum:', - 'There is no start date or due date for this task.' => 'Det finns inget startdatum eller slutdatum för uppgiften.', - 'Moving or resizing a task will change the start and due date of the task.' => 'Flytt eller storleksändring av uppgiften ändrar start och slutdatum för uppgiften', - 'There is no task in your project.' => 'Det finns ingen uppgift i ditt projekt.', - 'Gantt chart' => 'Gantt-schema', - // 'People who are project managers' => '', - // 'People who are project members' => '', - // 'NOK - Norwegian Krone' => '', - // 'Show this column' => '', - // 'Hide this column' => '', - // 'open file' => '', - // 'End date' => '', - // 'Users overview' => '', - // 'Members' => '', - // 'Shared project' => '', - // 'Project managers' => '', - // 'Gantt chart for all projects' => '', - // 'Projects list' => '', - // 'Gantt chart for this project' => '', - // 'Project board' => '', - // 'End date:' => '', - // 'There is no start date or end date for this project.' => '', - // 'Projects Gantt chart' => '', - // 'Change task color when using a specific task link' => '', - // 'Task link creation or modification' => '', - // 'Milestone' => '', - // 'Documentation: %s' => '', - // 'Switch to the Gantt chart view' => '', - // 'Reset the search/filter box' => '', - // 'Documentation' => '', - // 'Table of contents' => '', - // 'Gantt' => '', - // 'Author' => '', - // 'Version' => '', - // 'Plugins' => '', - // 'There is no plugin loaded.' => '', - // 'Set maximum column height' => '', - // 'Remove maximum column height' => '', - // 'My notifications' => '', - // 'Custom filters' => '', - // 'Your custom filter have been created successfully.' => '', - // 'Unable to create your custom filter.' => '', - // 'Custom filter removed successfully.' => '', - // 'Unable to remove this custom filter.' => '', - // 'Edit custom filter' => '', - // 'Your custom filter have been updated successfully.' => '', - // 'Unable to update custom filter.' => '', - // 'Web' => '', - // 'New attachment on task #%d: %s' => '', - // 'New comment on task #%d' => '', - // 'Comment updated on task #%d' => '', - // 'New subtask on task #%d' => '', - // 'Subtask updated on task #%d' => '', - // 'New task #%d: %s' => '', - // 'Task updated #%d' => '', - // 'Task #%d closed' => '', - // 'Task #%d opened' => '', - // 'Column changed for task #%d' => '', - // 'New position for task #%d' => '', - // 'Swimlane changed for task #%d' => '', - // 'Assignee changed on task #%d' => '', - // '%d overdue tasks' => '', - // 'Task #%d is overdue' => '', - // 'No new notifications.' => '', - // 'Mark all as read' => '', - // 'Mark as read' => '', - // 'Total number of tasks in this column across all swimlanes' => '', - // 'Collapse swimlane' => '', - // 'Expand swimlane' => '', - // 'Add a new filter' => '', - // 'Share with all project members' => '', - // 'Shared' => '', - // 'Owner' => '', - // 'Unread notifications' => '', - // 'Notification methods:' => '', - // 'Import tasks from CSV file' => '', - // 'Unable to read your file' => '', - // '%d task(s) have been imported successfully.' => '', - // 'Nothing have been imported!' => '', - // 'Import users from CSV file' => '', - // '%d user(s) have been imported successfully.' => '', - // 'Comma' => '', - // 'Semi-colon' => '', - // 'Tab' => '', - // 'Vertical bar' => '', - // 'Double Quote' => '', - // 'Single Quote' => '', - // '%s attached a file to the task #%d' => '', - // 'There is no column or swimlane activated in your project!' => '', - // 'Append filter (instead of replacement)' => '', - // 'Append/Replace' => '', - // 'Append' => '', - // 'Replace' => '', - // 'Import' => '', - // 'change sorting' => '', - // 'Tasks Importation' => '', - // 'Delimiter' => '', - // 'Enclosure' => '', - // 'CSV File' => '', - // 'Instructions' => '', - // 'Your file must use the predefined CSV format' => '', - // 'Your file must be encoded in UTF-8' => '', - // 'The first row must be the header' => '', - // 'Duplicates are not verified for you' => '', - // 'The due date must use the ISO format: YYYY-MM-DD' => '', - // 'Download CSV template' => '', - // 'No external integration registered.' => '', - // 'Duplicates are not imported' => '', - // 'Usernames must be lowercase and unique' => '', - // 'Passwords will be encrypted if present' => '', - // '%s attached a new file to the task %s' => '', - // 'Link type' => '', - // 'Assign automatically a category based on a link' => '', - // 'BAM - Konvertible Mark' => '', - // 'Assignee Username' => '', - // 'Assignee Name' => '', - // 'Groups' => '', - // 'Members of %s' => '', - // 'New group' => '', - // 'Group created successfully.' => '', - // 'Unable to create your group.' => '', - // 'Edit group' => '', - // 'Group updated successfully.' => '', - // 'Unable to update your group.' => '', - // 'Add group member to "%s"' => '', - // 'Group member added successfully.' => '', - // 'Unable to add group member.' => '', - // 'Remove user from group "%s"' => '', - // 'User removed successfully from this group.' => '', - // 'Unable to remove this user from the group.' => '', - // 'Remove group' => '', - // 'Group removed successfully.' => '', - // 'Unable to remove this group.' => '', - // 'Project Permissions' => '', - // 'Manager' => '', - // 'Project Manager' => '', - // 'Project Member' => '', - // 'Project Viewer' => '', - // 'Your account is locked for %d minutes' => '', - // 'Invalid captcha' => '', - // 'The name must be unique' => '', - // 'View all groups' => '', - // 'View group members' => '', - // 'There is no user available.' => '', - // 'Do you really want to remove the user "%s" from the group "%s"?' => '', - // 'There is no group.' => '', - // 'External Id' => '', - // 'Add group member' => '', - // 'Do you really want to remove this group: "%s"?' => '', - // 'There is no user in this group.' => '', - // 'Remove this user' => '', - // 'Permissions' => '', - // 'Allowed Users' => '', - // 'No user have been allowed specifically.' => '', - // 'Role' => '', - // 'Enter user name...' => '', - // 'Allowed Groups' => '', - // 'No group have been allowed specifically.' => '', - // 'Group' => '', - // 'Group Name' => '', - // 'Enter group name...' => '', - // 'Role:' => '', - // 'Project members' => '', - // 'Compare hours for "%s"' => '', - // '%s mentioned you in the task #%d' => '', - // '%s mentioned you in a comment on the task #%d' => '', - // 'You were mentioned in the task #%d' => '', - // 'You were mentioned in a comment on the task #%d' => '', - // 'Mentioned' => '', - // 'Compare Estimated Time vs Actual Time' => '', - // 'Estimated hours: ' => '', - // 'Actual hours: ' => '', - // 'Hours Spent' => '', - // 'Hours Estimated' => '', - // 'Estimated Time' => '', - // 'Actual Time' => '', - // 'Estimated vs actual time' => '', - // 'RUB - Russian Ruble' => '', - // 'Assign the task to the person who does the action when the column is changed' => '', - // 'Close a task in a specific column' => '', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - // 'Password Reset for Kanboard' => '', - // 'Forgot password?' => '', - // 'Enable "Forget Password"' => '', - // 'Password Reset' => '', - // 'New password' => '', - // 'Change Password' => '', - // 'To reset your password click on this link:' => '', - // 'Last Password Reset' => '', - // 'The password has never been reinitialized.' => '', - // 'Creation' => '', - // 'Expiration' => '', - // 'Password reset history' => '', - // 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '', - // 'Do you really want to close all tasks of this column?' => '', - // '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '', - // 'Close all tasks of this column' => '', - // 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '', - // 'My dashboard' => '', - // 'My profile' => '', - // 'Project owner: ' => '', - // 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '', - // 'Project owner' => '', - // 'Those dates are useful for the project Gantt chart.' => '', - // 'Private projects do not have users and groups management.' => '', - // 'There is no project member.' => '', - // 'Priority' => '', - // 'Task priority' => '', - // 'General' => '', - // 'Dates' => '', - // 'Default priority' => '', - // 'Lowest priority' => '', - // 'Highest priority' => '', - // 'If you put zero to the low and high priority, this feature will be disabled.' => '', - // 'Close a task when there is no activity' => '', - // 'Duration in days' => '', - // 'Send email when there is no activity on a task' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/th_TH/translations.php b/sources/app/Locale/th_TH/translations.php deleted file mode 100644 index fd35d28..0000000 --- a/sources/app/Locale/th_TH/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => 'ไม่มี', - 'edit' => 'แก้ไข', - 'Edit' => 'แก้ไข', - 'remove' => 'ลบ', - 'Remove' => 'ลบ', - 'Yes' => 'ใช่', - 'No' => 'ไม่', - 'cancel' => 'ยกเลิก', - 'or' => 'หรือ', - 'Yellow' => 'สีเหลือง', - 'Blue' => 'สีน้ำเงิน', - 'Green' => 'สีเขียว', - 'Purple' => 'สีม่วง', - 'Red' => 'สีแดง', - 'Orange' => 'สีส้ม', - 'Grey' => 'สีเทา', - 'Brown' => 'สีน้ำตาล', - 'Deep Orange' => 'สีส้มเข้ม', - 'Dark Grey' => 'สีเทาเข้ม', - 'Pink' => 'สีชมพู', - 'Teal' => 'สีเขียวหัวเป็ด', - 'Cyan' => 'สีฟ้า', - 'Lime' => 'สีมะนาว', - 'Light Green' => 'สีเขียวสว่าง', - 'Amber' => 'สีเหลืองอำพัน', - 'Save' => 'บันทึก', - 'Login' => 'เข้าสู่ระบบ', - 'Official website:' => 'เวบไซต์อย่างเป็นทางการ:', - 'Unassigned' => 'ไม่กำหนด', - 'View this task' => 'รายละเอียดงานนี้', - 'Remove user' => 'เอาผู้ใช้ออก', - 'Do you really want to remove this user: "%s"?' => 'คุณต้องการเอาผู้ใช้ « %s » ออกใช่หรือไม่?', - 'All users' => 'ผู้ใช้ทั้งหมด', - 'Username' => 'ชื่อผู้ใช้', - 'Password' => 'รหัสผ่าน', - 'Administrator' => 'ผู้ดูแลระบบ', - 'Sign in' => 'เข้าสู่ระบบ', - 'Users' => 'ผู้ใช้', - 'No user' => 'ไม่มีผู้ใช้', - 'Forbidden' => 'ไม่อนุญาติ', - 'Access Forbidden' => 'ไม่อนุญาติให้เข้า', - 'Edit user' => 'แก้ไขผู้ใช้', - 'Logout' => 'ออกจากระบบ', - 'Bad username or password' => 'ชื่อผู้ใช่หรือรหัสผ่านผิด', - 'Edit project' => 'แก้ไขโปรเจค', - 'Name' => 'ชื่อ', - 'Projects' => 'โปรเจค', - 'No project' => 'ไม่มีโปรเจค', - 'Project' => 'โปรเจค', - 'Status' => 'สถานะ', - 'Tasks' => 'งาน', - 'Board' => 'บอร์ด', - 'Actions' => 'การกระทำ', - 'Inactive' => 'ไม่เปิดใช้งาน', - 'Active' => 'เปิดใช้งาน', - '%d tasks on the board' => '%d งานบนบอร์ด', - '%d tasks in total' => '%d งานทั้งหมด', - 'Unable to update this board.' => 'ไม่สามารถปรับปรุงบอร์ดได้.', - 'Edit board' => 'แก้ไขบอร์ด', - 'Disable' => 'ปิดการทำงาน', - 'Enable' => 'เปิดการทำงาน', - 'New project' => 'โปรเจคใหม่', - 'Do you really want to remove this project: "%s"?' => 'คุณต้องการเอาโปรเจค « %s » ออกใช่หรือไม่?', - 'Remove project' => 'ลบโปรเจค', - 'Edit the board for "%s"' => 'แก้ไขบอร์ดสำหรับ « %s »', - 'All projects' => 'โปรเจคทั้งหมด', - 'Add a new column' => 'เพิ่มคอลัมน์ใหม่', - 'Title' => 'หัวเรื่อง', - 'Assigned to %s' => 'กำหนดให้ %s', - 'Remove a column' => 'ลบคอลัมน์', - 'Remove a column from a board' => 'ลบคอลัมน์ออกจากบอร์ด', - 'Unable to remove this column.' => 'ไม่สามารถลบคอลัมน์นี้', - 'Do you really want to remove this column: "%s"?' => 'คุณต้องการลบคอลัมน์ « %s » ออกใช่หรือไม่?', - 'This action will REMOVE ALL TASKS associated to this column!' => 'การกระทำนี้จะลบงานที่เกี่ยวข้องกับคอลัมน์นี้', - 'Settings' => 'ตั้งค่า', - 'Application settings' => 'ตั้งค่าการทำงาน', - 'Language' => 'ภาษา', - // 'Webhook token:' => '', - 'API token:' => 'API token:', - 'Database size:' => 'ขนาดฐานข้อมูล:', - 'Download the database' => 'ดาวน์โหลดฐานข้อมูล', - 'Optimize the database' => 'ปรับปรุงฐานข้อมูล', - '(VACUUM command)' => '(VACUUM command)', - '(Gzip compressed Sqlite file)' => '(Gzip compressed Sqlite file)', - 'Close a task' => 'ปิดงาน', - 'Edit a task' => 'แก้ไขงาน', - 'Column' => 'คอลัมน์', - 'Color' => 'สี', - 'Assignee' => 'กำหนดให้', - 'Create another task' => 'สร้างงานอื่น', - 'New task' => 'งานใหม่', - 'Open a task' => 'เปิดงาน', - 'Do you really want to open this task: "%s"?' => 'คุณต้องการเปิดงาน: « %s » ใช่หรือไม่?', - 'Back to the board' => 'กลับไปที่บอร์ด', - 'There is nobody assigned' => 'ไม่มีใครถูกกำหนด', - 'Column on the board:' => 'คอลัมน์บนบอร์ด:', - 'Close this task' => 'ปิดงานนี้', - 'Open this task' => 'เปิดงานนี้', - 'There is no description.' => 'ไม่มีคำอธิบาย', - 'Add a new task' => 'เพิ่มงานใหม่', - 'The username is required' => 'ต้องการชื่อผู้ใช้', - 'The maximum length is %d characters' => 'จำนวนตัวอักษรสูงสุด %d ตัวอักษร', - 'The minimum length is %d characters' => 'จำนวนตัวอักษรน้อยสุด %d ตัวอักษร', - 'The password is required' => 'ต้องการรหัสผ่าน', - 'This value must be an integer' => 'ต้องเป็นตัวเลข', - 'The username must be unique' => 'ชื่อผู้ใช้ต้องไม่ซ้ำ', - 'The user id is required' => 'ต้องการไอดีผู้ใช้', - 'Passwords don\'t match' => 'รหัสผ่านไม่ถูกต้อง', - 'The confirmation is required' => 'ต้องการการยืนยัน', - 'The project is required' => 'ต้องการโปรเจค', - 'The id is required' => 'ต้องการไอดี', - 'The project id is required' => 'ต้องการไอดีโปรเจค', - 'The project name is required' => 'ต้องการชื่อโปรเจค', - 'The title is required' => 'ต้องการหัวเรื่อง', - 'Settings saved successfully.' => 'บันทึกการตั้งค่าเรียบร้อยแล้ว', - 'Unable to save your settings.' => 'ไม่สามารถบันทึกการตั้งค่าได้', - 'Database optimization done.' => 'ปรับปรุงฐานข้อมูลเรียบร้อยแล้ว', - 'Your project have been created successfully.' => 'สร้างโปรเจคเรียบร้อยแล้ว', - 'Unable to create your project.' => 'ไม่สามารถสร้างโปรเจคได้', - 'Project updated successfully.' => 'ปรับปรุงโปรเจคเรียบร้อยแล้ว', - 'Unable to update this project.' => 'ไม่สามารถปรับปรุงโปรเจคได้', - 'Unable to remove this project.' => 'ไม่สามารถลบโปรเจคได้', - 'Project removed successfully.' => 'ลบโปรเจคเรียบร้อยแล้ว', - 'Project activated successfully.' => 'เปิดใช้งานโปรเจคเรียบร้อยแล้ว', - 'Unable to activate this project.' => 'ไม่สามารถเปิดใช้งานโปรเจคได้', - 'Project disabled successfully.' => 'ปิดโปรเจคเรียบร้อยแล้ว', - 'Unable to disable this project.' => 'ไม่สามารถปิดโปรเจคได้', - 'Unable to open this task.' => 'ไม่สามารถเปิดงานนี้', - 'Task opened successfully.' => 'เปิดงานเรียบร้อยแล้ว', - 'Unable to close this task.' => 'ไม่สามารถปิดงานนี้', - 'Task closed successfully.' => 'ปิดงานเรียบร้อยแล้ว', - 'Unable to update your task.' => 'ไม่สามารถปรับปรุงงานได้', - 'Task updated successfully.' => 'ปรับปรุงงานเรียบร้อยแล้ว', - 'Unable to create your task.' => 'ไม่สามารถสร้างงานได้', - 'Task created successfully.' => 'สร้างงานเรียบร้อยแล้ว', - 'User created successfully.' => 'สร้างผู้ใช้เรียบร้อยแล้ว', - 'Unable to create your user.' => 'ไม่สามารถสร้างผู้ใช้ได้', - 'User updated successfully.' => 'ปรับปรุงผู้ใช้เรียบร้อยแล้ว', - 'Unable to update your user.' => 'ไม่สามารถปรับปรุงผู้ใช้ได้', - 'User removed successfully.' => 'ลบผู้ใช้เรียบร้อยแล้ว', - 'Unable to remove this user.' => 'ไม่สามารถลบผู้ใช้ได้', - 'Board updated successfully.' => 'ปรับปรุงบอร์ดเรียบร้อยแล้ว', - 'Ready' => 'พร้อม', - 'Backlog' => 'งานค้าง', - 'Work in progress' => 'กำลังทำ', - 'Done' => 'เสร็จ', - 'Application version:' => 'แอพเวอร์ชัน:', - 'Id' => 'ไอดี', - '%d closed tasks' => '%d งานที่ปิด', - 'No task for this project' => 'ไม่มีงานสำหรับโปรเจคนี้', - 'Public link' => 'ลิงค์สาธารณะ', - 'Timezone' => 'เขตเวลา', - 'Sorry, I didn\'t find this information in my database!' => 'เสียใจด้วย ไม่สามารถหาข้อมูลในฐานข้อมูลได้', - 'Page not found' => 'ไม่พบหน้า', - 'Complexity' => 'ความซับซ้อน', - 'Task limit' => 'จำกัดงาน', - 'Task count' => 'นับงาน', - 'User' => 'ผู้ใช้', - 'Comments' => 'ความคิดเห็น', - 'Leave a comment' => 'ออกความคิดเห็น', - 'Comment is required' => 'ต้องการความคิดเห็น', - 'Leave a description' => 'แสดงคำอธิบาย', - 'Comment added successfully.' => 'เพิ่มความคิดเห็นเรียบร้อยแล้ว', - 'Unable to create your comment.' => 'ไม่สามารถสร้างความคิดเห็น', - 'Due Date' => 'วันที่ครบกำหนด', - 'Invalid date' => 'วันที่ผิด', - 'Automatic actions' => 'การกระทำอัตโนมัติ', - 'Your automatic action have been created successfully.' => 'การกระทำอัตโนมัติสร้างเรียบร้อยแล้ว', - 'Unable to create your automatic action.' => 'ไม่สามารถสร้างการกระทำอัตโนมัติได้', - 'Remove an action' => 'ลบการกระทำ', - 'Unable to remove this action.' => 'ไม่สามารถลบการกระทำ', - 'Action removed successfully.' => 'ลบการกระทำเรียบร้อยแล้ว', - 'Automatic actions for the project "%s"' => 'การกระทำอัตโนมัติสำหรับโปรเจค « %s »', - 'Add an action' => 'เพิ่มการกระทำ', - 'Event name' => 'ชื่อเหตุกาณ์', - 'Action name' => 'ชื่อการกระทำ', - 'Action parameters' => 'พารามิเตอร์ของการกระทำ', - 'Action' => 'การกระทำ', - 'Event' => 'เหตุการณ์', - 'When the selected event occurs execute the corresponding action.' => 'เหตุการ์ที่เลือกจะเกิดขึ้นเมื่อมีการกระทำที่สอดคล้องกัน', - 'Next step' => 'ขั้นตอนต่อไป', - 'Define action parameters' => 'กำหนดพารามิเตอร์ของการกระทำ', - 'Do you really want to remove this action: "%s"?' => 'คุณต้องการลบการกระทำ « %s » ใช่หรือไม่?', - 'Remove an automatic action' => 'ลบการกระทำอัตโนมัติ', - 'Assign the task to a specific user' => 'กำหนดงานให้ผู้ใช้แบบเจาะจง', - 'Assign the task to the person who does the action' => 'กำหนดงานให้ผู้ใช้งานปัจจุบัน', - 'Duplicate the task to another project' => 'ทำซ้ำงานนี้ในโปรเจคอื่น', - 'Move a task to another column' => 'ย้ายงานไปคอลัมน์อื่น', - 'Task modification' => 'แก้ไขงาน', - 'Task creation' => 'สร้างงาน', - 'Closing a task' => 'กำลังปิดงาน', - 'Assign a color to a specific user' => 'กำหนดสีให้ผู้ใช้แบบเจาะจง', - 'Column title' => 'หัวเรื่องคอลัมน์', - 'Position' => 'ตำแหน่ง', - 'Duplicate to another project' => 'ทำซ้ำในโปรเจคอื่น', - 'Duplicate' => 'ทำซ้ำ', - 'link' => 'ลิงค์', - 'Comment updated successfully.' => 'ปรับปรุงความคิดเห็นเรียบร้อยแล้ว', - 'Unable to update your comment.' => 'ไม่สามารถปรับปรุงความคิดเห็นได้', - 'Remove a comment' => 'ลบความคิดเห็น', - 'Comment removed successfully.' => 'ลบความคิดเห็นเรียบร้อยแล้ว', - 'Unable to remove this comment.' => 'ไม่สามารถลบความคิดเห็นได้', - 'Do you really want to remove this comment?' => 'คุณต้องการลบความคิดเห็น', - 'Current password for the user "%s"' => 'รหัสผ่านปัจจุบันของผู้ใช้ « %s »', - 'The current password is required' => 'ต้องการรหัสผ่านปัจจุบัน', - 'Wrong password' => 'รหัสผ่านผิด', - 'Unknown' => 'ไม่ทราบ', - 'Last logins' => 'เข้าใช้ล่าสุด', - 'Login date' => 'วันที่เข้าใข้', - 'Authentication method' => 'วิธีการยืนยันตัวตน', - 'IP address' => 'ไอพี แอดเดรส', - 'User agent' => 'User agent', - 'Persistent connections' => 'Persistent connections', - 'No session.' => 'No session.', - 'Expiration date' => 'หมดอายุวันที่', - 'Remember Me' => 'จดจำฉัน', - 'Creation date' => 'สร้างวันที่', - 'Everybody' => 'ทุกคน', - 'Open' => 'เปิด', - 'Closed' => 'ปิด', - 'Search' => 'ค้นหา', - 'Nothing found.' => 'ค้นหาไม่พบ.', - 'Due date' => 'วันที่ครบกำหนด', - 'Others formats accepted: %s and %s' => 'รูปแบบอื่นที่ได้รับการยอมรับ: %s และ %s', - 'Description' => 'คำอธิบาย', - '%d comments' => '%d ความคิดเห็น', - '%d comment' => '%d ความคิดเห็น', - 'Email address invalid' => 'อีเมลผิด', - 'Your external account is not linked anymore to your profile.' => 'บัญชีภายนอกของคุณไม่ได้เชื่อมโยงอีกต่อไปในโปรไฟล์ของคุณ', - 'Unable to unlink your external account.' => 'ไม่สามารถยกเลิกการเชื่อมโยงบัญชีภายนอกของคุณ', - 'External authentication failed' => 'การตรวจสอบภายนอกล้มเหลว', - 'Your external account is linked to your profile successfully.' => 'บัญชีภายนอกของคุณลิงค์กับโปรไฟล์ของคุณเรียบร้อย', - 'Email' => 'อีเมล', - 'Task removed successfully.' => 'ลบงานเรียบร้อยแล้ว', - 'Unable to remove this task.' => 'ไม่สามารถลบงานนี้', - 'Remove a task' => 'ลบงาาน', - 'Do you really want to remove this task: "%s"?' => 'คุณต้องการลบงาน "%s" ออกใช่หรือไม่?', - 'Assign automatically a color based on a category' => 'กำหนดสีอัตโนมัติขึ้นอยู่กับหมวด', - 'Assign automatically a category based on a color' => 'กำหนดหมวดอัตโนมัติขึ้นอยู่กับสี', - 'Task creation or modification' => 'สร้างหรือแก้ไขงาน', - 'Category' => 'หมวด', - 'Category:' => 'หมวด:', - 'Categories' => 'หมวด', - 'Your category have been created successfully.' => 'สร้างหมวดเรียบร้อยแล้ว', - 'Unable to create your category.' => 'ไม่สามารถสร้างหมวดได้', - 'Your category have been updated successfully.' => 'ปรับปรุงหมวดเรียบร้อยแล้ว', - 'Unable to update your category.' => 'ไม่สามารถปรับปรุงหมวดได้', - 'Remove a category' => 'ลบหมวด', - 'Category removed successfully.' => 'ลบหมวดเรียบร้อยแล้ว', - 'Unable to remove this category.' => 'ไม่สามารถลบหมวดได้', - 'Category modification for the project "%s"' => 'แก้ไขหมวดสำหรับโปรเจค "%s"', - 'Category Name' => 'ชื่อหมวด', - 'Add a new category' => 'เพิ่มหมวดใหม่', - 'Do you really want to remove this category: "%s"?' => 'คุณต้องการลบหมวด "%s" ใช่หรือไม่?', - 'All categories' => 'หมวดทั้งหมด', - 'No category' => 'ไม่มีหมวด', - 'The name is required' => 'ต้องการชื่อ', - 'Remove a file' => 'ลบไฟล์', - 'Unable to remove this file.' => 'ไม่สามารถลบไฟล์ได้', - 'File removed successfully.' => 'ลบไฟล์เรียบร้อยแล้ว', - 'Attach a document' => 'แนบเอกสาร', - 'Do you really want to remove this file: "%s"?' => 'คุณต้องการลบไฟล์ "%s" ใช่หรือไม่?', - 'Attachments' => 'แนบ', - 'Edit the task' => 'แก้ไขงาน', - 'Add a comment' => 'เพิ่มความคิดเห็น', - 'Edit a comment' => 'แก้ไขความคิดเห็น', - 'Summary' => 'สรุป', - 'Time tracking' => 'การติดตามเวลา', - 'Estimate:' => 'ประมาณ:', - 'Spent:' => 'ใช้:', - 'Do you really want to remove this sub-task?' => 'คุณต้องการลบงานย่อยใช่หรือไม่?', - 'Remaining:' => 'เหลือ:', - 'hours' => 'ชั่วโมง', - 'spent' => 'ใช้', - 'estimated' => 'ประมาณ', - 'Sub-Tasks' => 'งานย่อย', - 'Add a sub-task' => 'เพิ่มงานย่อย', - 'Original estimate' => 'ประมาณการเดิม', - 'Create another sub-task' => 'สร้างงานย่อยอื่น', - 'Time spent' => 'ใช้เวลา', - 'Edit a sub-task' => 'แก้ไขงานย่อย', - 'Remove a sub-task' => 'ลบงานย่อย', - 'The time must be a numeric value' => 'เวลาที่ต้องเป็นตัวเลข', - 'Todo' => 'สิ่งที่ต้องทำ', - 'In progress' => 'กำลังดำเนินการ', - 'Sub-task removed successfully.' => 'ลบงานย่อยเรียบร้อยแล้ว', - 'Unable to remove this sub-task.' => 'ไม่สามารถลบงานย่อยได้', - 'Sub-task updated successfully.' => 'ปรับปรุงงานย่อย่่เรียบร้อยแล้ว', - 'Unable to update your sub-task.' => 'ไม่สามารถปรับปรุงานย่อยได้', - 'Unable to create your sub-task.' => 'ไม่สามารถสร้างงานย่อยได้', - 'Sub-task added successfully.' => 'เพิ่มงานย่อยเรียบร้อยแล้ว', - 'Maximum size: ' => 'ขนาดสูงสุด:', - 'Unable to upload the file.' => 'ไม่สามารถอัพโหลดไฟล์ได้', - 'Display another project' => 'แสดงโปรเจคอื่น', - 'Created by %s' => 'สร้างโดย %s', - 'Tasks Export' => 'ส่งออกงาน', - 'Tasks exportation for "%s"' => 'ส่งออกงานสำหรับ "%s"', - 'Start Date' => 'เริ่มวันที่', - 'End Date' => 'สิ้นสุดวันที่', - 'Execute' => 'ประมวลผล', - 'Task Id' => 'งาน ไอดี', - 'Creator' => 'ผู้สร้าง', - 'Modification date' => 'วันที่แก้ไข', - 'Completion date' => 'วันที่เสร็จสิ้น', - 'Clone' => 'เลียนแบบ', - 'Project cloned successfully.' => 'เลียนแบบโปรเจคเรียบร้อยแล้ว', - 'Unable to clone this project.' => 'ไม่สามารถเลียบแบบโปรเจคได้', - 'Enable email notifications' => 'เปิดอีเมลแจ้งเตือน', - 'Task position:' => 'ตำแหน่งงาน', - 'The task #%d have been opened.' => 'งานที่ #%d ถุกเปิด', - 'The task #%d have been closed.' => 'งานที่ #%d ถูกปิด', - 'Sub-task updated' => 'ปรับปรุงงานย่อย', - 'Title:' => 'หัวเรื่อง:', - 'Status:' => 'สถานะ:', - 'Assignee:' => 'กำหนดให้:', - 'Time tracking:' => 'การติดตามเวลา:', - 'New sub-task' => 'งานย่อยใหม่', - 'New attachment added "%s"' => 'เพิ่มการแนบใหม่ "%s"', - 'New comment posted by %s' => 'ความคิดเห็นใหม่จาก %s', - 'New attachment' => 'การแนบใหม่', - 'New comment' => 'ความคิดเห็นใหม่', - 'Comment updated' => 'ปรับปรุงความคิดเห็น', - 'New subtask' => 'งานย่อยใหม่', - 'Subtask updated' => 'ปรับปรุงงานย่อยแล้ว', - 'Task updated' => 'ปรับปรุงงานแล้ว', - 'Task closed' => 'ปิดงาน', - 'Task opened' => 'เปิดงาน', - 'I want to receive notifications only for those projects:' => 'ฉันต้องการรับการแจ้งเตือนสำหรับโปรเจค:', - 'view the task on Kanboard' => 'แสดงงานบน Kanboard', - 'Public access' => 'การเข้าถึงสาธารณะ', - 'Active tasks' => 'งานที่กำลังใช้งาน', - 'Disable public access' => 'ปิดการเข้าถึงสาธารณะ', - 'Enable public access' => 'เปิดการเข้าถึงสาธารณะ', - 'Public access disabled' => 'การเข้าถึงสาธารณะถูกปิด', - 'Do you really want to disable this project: "%s"?' => 'คุณต้องการปิดการใช้งานโปรเจคนี้: "%s" ใช่หรือไม่?', - 'Do you really want to enable this project: "%s"?' => 'คุณต้องการเปิดการใช้งานโปรเจคนี้: "%s" ใช่หรือไม่?', - 'Project activation' => 'การ เปิด/ปิด ใช้งานโปรเจค', - 'Move the task to another project' => 'ย้ายงานไปโปรเจคอื่น', - 'Move to another project' => 'ย้ายไปโปรเจคอื่น', - 'Do you really want to duplicate this task?' => 'คุณต้องการทำซ้ำงานนี้ใช่หรือไม่?', - 'Duplicate a task' => 'ทำซ้ำงาน', - 'External accounts' => 'บัญชีภายนอก', - 'Account type' => 'ประเภทบัญชี', - 'Local' => 'ท้องถิ่น', - 'Remote' => 'รีโมท', - 'Enabled' => 'เปิดการใช้', - 'Disabled' => 'ปิดการใช้', - 'Username:' => 'ชื่อผู้ใช้:', - 'Name:' => 'ชื่อ:', - 'Email:' => 'อีเมล:', - 'Notifications:' => 'แจ้งเตือน:', - 'Notifications' => 'การแจ้งเตือน', - 'Account type:' => 'ประเภทบัญชี:', - 'Edit profile' => 'แก้ไขประวัติ', - 'Change password' => 'เปลี่ยนรหัสผ่าน', - 'Password modification' => 'แก้ไขรหัสผ่าน', - 'External authentications' => 'การยืนยันภายนอก', - 'Never connected.' => 'ไม่เชื่อมต่อ', - 'No external authentication enabled.' => 'ไม่เปิดการใช้งานการยืนยันภายนอก', - 'Password modified successfully.' => 'แก้ไขรหัสผ่านเรียบร้อยแล้ว', - 'Unable to change the password.' => 'ไม่สามารถเปลี่ยนรหัสผ่านได้', - 'Change category' => 'เปลี่ยนหมวด', - '%s updated the task %s' => '%s ปรับปรุงงานแล้ว %s', - '%s opened the task %s' => '%s เปิดงานแล้ว %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s ย้ายงานแล้ว %s ไปตำแหน่ง #%d ในคอลัมน์ "%s"', - '%s moved the task %s to the column "%s"' => '%s ย้ายงานแล้ว %s ไปคอลัมน์ "%s"', - '%s created the task %s' => '%s สร้างงานแล้ว %s', - '%s closed the task %s' => '%s ปิดงานแล้ว %s', - '%s created a subtask for the task %s' => '%s สร้างงานย่อยสำหรับงานแล้ว %s', - '%s updated a subtask for the task %s' => '%s ปรับปรุงงานย่อยสำหรับงานแล้ว %s', - 'Assigned to %s with an estimate of %s/%sh' => 'กำหนดให้ %s โดยประมาณแล้ว %s/%sh', - 'Not assigned, estimate of %sh' => 'ไม่กำหนดแล้ว, ประมาณเวลาที่ใช้ %s ชั่วโมง', - '%s updated a comment on the task %s' => '%s ปรับปรุงความคิดเห็นในงานแล้ว %s', - '%s commented the task %s' => '%s แสดงความคิดเห็นของงานแล้ว %s', - '%s\'s activity' => 'กิจกรรม %s', - 'RSS feed' => 'RSS feed', - '%s updated a comment on the task #%d' => '%s ปรับปรุงความคิดเห็นบนงานแล้ว #%d', - '%s commented on the task #%d' => '%s แสดงความคิดเห็นบนงานแล้ว #%d', - '%s updated a subtask for the task #%d' => '%s ปรับปรุงงานย่อยสำหรับงานแล้ว #%d', - '%s created a subtask for the task #%d' => '%s สร้างงานย่อยสำหรับงานแล้ว #%d', - '%s updated the task #%d' => '%s ปรับปรุงงานแล้ว #%d', - '%s created the task #%d' => '%s สร้างงานแล้ว #%d', - '%s closed the task #%d' => '%s ปิดงานแล้ว #%d', - '%s open the task #%d' => '%s เปิดงานแล้ว #%d', - '%s moved the task #%d to the column "%s"' => '%s ย้ายงานแล้ว #%d ไปที่คอลัมน์ "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s ย้ายงานแล้ว #%d ไปตำแหน่ง %d ในคอลัมน์ที่ "%s"', - 'Activity' => 'กิจกรรม', - 'Default values are "%s"' => 'ค่าเริ่มต้น "%s"', - 'Default columns for new projects (Comma-separated)' => 'คอลัมน์เริ่มต้นสำหรับโปรเจคใหม่ (Comma-separated)', - 'Task assignee change' => 'เปลี่ยนการกำหนดบุคคลของงาน', - '%s change the assignee of the task #%d to %s' => '%s เปลี่ยนผู้รับผิดชอบของงาน #%d เป็น %s', - '%s changed the assignee of the task %s to %s' => '%s เปลี่ยนผู้รับผิดชอบของงาน %s เป็น %s', - 'New password for the user "%s"' => 'รหัสผ่านใหม่สำหรับผู้ใช้ "%s"', - 'Choose an event' => 'เลือกเหตุการณ์', - 'Create a task from an external provider' => 'สร้างงานจากบริการภายนอก', - 'Change the assignee based on an external username' => 'เปลี่ยนผู้รับผิดชอบขึ้นอยู่กับชื่อผู้ใช้ภายนอก', - 'Change the category based on an external label' => 'เปลี่ยนหมวดขึ้นอยู่กับป้ายชื่อภายนอก', - 'Reference' => 'อ้างถึง', - 'Label' => 'ป้ายชื่อ', - 'Database' => 'ฐานข้อมูล', - 'About' => 'เกี่ยวกับ', - 'Database driver:' => 'เครื่องมือฐานขข้อมูล', - 'Board settings' => 'ตั้งค่าบอร์ด', - // 'Webhook settings' => '', - // 'Reset token' => '', - // 'API endpoint:' => '', - '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)' => 'ช่วงเวลา (เป็นวินาที) ใช้ในการตัดสินใจว่าเป็นการแก้ไขเร็วๆ นี้ (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' => '', - // 'Token regenerated.' => '', - 'Date format' => 'รูปแบบวันที่', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ยอมรับรูปแบบ ISO ตัวอย่าง: "%s" และ "%s"', - 'New private project' => 'เพิ่มโปรเจคส่วนตัวใหม่', - 'This project is private' => 'โปรเจคนี้เป็นโปรเจคส่วนตัว', - 'Add' => 'เพิ่ม', - 'Start date' => 'เริ่มวันที่', - 'Time estimated' => 'เวลาโดยประมาณ', - 'There is nothing assigned to you.' => 'ไม่มีอะไรกำหนดให้คุณ', - 'My tasks' => 'งานของฉัน', - 'Activity stream' => 'กิจกรรมที่เกิดขึ้น', - 'Dashboard' => 'แดชบอร์ด', - 'Confirmation' => 'ยืนยันรหัสผ่าน', - 'Allow everybody to access to this project' => 'อนุญาตให้ทุกคนเข้าถึงโปรเจคนี้', - 'Everybody have access to this project.' => 'ทุกคนสามารถเข้าถึงโปรเจคนี้', - // 'Webhooks' => '', - // 'API' => '', - 'Create a comment from an external provider' => 'สร้างความคิดเห็นจากบริการภายนอก', - 'Project management' => 'การจัดการโปรเจค', - 'My projects' => 'โปรเจคของฉัน', - 'Columns' => 'คอลัมน์', - 'Task' => 'งาน', - 'Your are not member of any project.' => 'คุณไม่ได้เป็นสมาชิกของโปรเจค', - 'Percentage' => 'เปอร์เซ็นต์', - 'Number of tasks' => 'จำนวนงาน', - 'Task distribution' => 'การกระจายงาน', - 'Reportings' => 'รายงาน', - // 'Task repartition for "%s"' => '', - 'Analytics' => 'การวิเคราะห์', - 'Subtask' => 'งานย่อย', - 'My subtasks' => 'งานย่อยของฉัน', - 'User repartition' => 'การแบ่งงานของผู้ใช้', - 'User repartition for "%s"' => 'การแบ่งงานของผู้ใช้ "%s"', - 'Clone this project' => 'เลียนแบบโปรเจคนี้', - 'Column removed successfully.' => 'ลบคอลัมน์สำเร็จ', - 'Not enough data to show the graph.' => 'ไม่มีข้อมูลแสดงเป็นกราฟ', - 'Previous' => 'ก่อนหน้า', - 'The id must be an integer' => 'ไอดีต้องเป็นตัวเลขจำนวนเต็ม', - 'The project id must be an integer' => 'ไอดีโปรเจคต้องเป็นตัวเลข', - 'The status must be an integer' => 'สถานะต้องเป็นตัวเลข', - 'The subtask id is required' => 'ต้องการงานย่อย', - 'The subtask id must be an integer' => 'ไอดีงานย่อยต้องเป็นตัวเลข', - 'The task id is required' => 'ต้องการไอดีงาน', - 'The task id must be an integer' => 'ไอดีงานต้องเป็นตัวเลข', - 'The user id must be an integer' => 'ไอดีผู้ใช้ต้องเป็นตัวเลข', - 'This value is required' => 'ต้องการค่านี้', - 'This value must be numeric' => 'ค่านี้ต้องเป็นตัวเลข', - 'Unable to create this task.' => 'ไม่สามารถสร้างงานนี้', - 'Cumulative flow diagram' => 'แผนภาพงานสะสม', - 'Cumulative flow diagram for "%s"' => 'แผนภาพงานสะสม "%s"', - 'Daily project summary' => 'สรุปโปรเจครายวัน', - 'Daily project summary export' => 'ส่งออกสรุปโปรเจครายวัน', - 'Daily project summary export for "%s"' => 'ส่งออกสรุปโปรเจครายวันสำหรับ "%s"', - 'Exports' => 'ส่งออก', - 'This export contains the number of tasks per column grouped per day.' => 'การส่งออกนี้เป็นการนับจำนวนงานในแต่ละคอลัมน์ในแต่ละวัน', - 'Active swimlanes' => 'สวิมเลนพร้อมใช้งาน', - 'Add a new swimlane' => 'เพิ่มสวิมเลนใหม่', - 'Change default swimlane' => 'เปลี่ยนสวิมเลนเริ่มต้น', - 'Default swimlane' => 'สวิมเลนเริ่มต้น', - 'Do you really want to remove this swimlane: "%s"?' => 'คุณต้องการลบสวิมเลนนี้ : "%s"?', - 'Inactive swimlanes' => 'สวิมเลนไม่ทำงาน', - 'Remove a swimlane' => 'ลบสวิมเลน', - 'Show default swimlane' => 'แสดงสวิมเลนเริ่มต้น', - 'Swimlane modification for the project "%s"' => 'แก้ไขสวิมเลนสำหรับโปรเจค "%s"', - 'Swimlane removed successfully.' => 'ลบสวิมเลนเรียบร้อยแล้ว', - 'Swimlanes' => 'สวิมเลน', - 'Swimlane updated successfully.' => 'ปรับปรุงสวิมเลนเรียบร้อยแล้ว', - 'The default swimlane have been updated successfully.' => 'สวิมเลนเริ่มต้นปรับปรุงเรียบร้อยแล้ว', - 'Unable to remove this swimlane.' => 'ไม่สามารถลบสวิมเลนนี้', - 'Unable to update this swimlane.' => 'ไม่สามารถปรับปรุงสวิมเลนนี้', - 'Your swimlane have been created successfully.' => 'สวิมเลนของคุณถูกสร้างเรียบร้อยแล้ว', - 'Example: "Bug, Feature Request, Improvement"' => 'ตัวอย่าง: "Bug, Feature Request, Improvement"', - 'Default categories for new projects (Comma-separated)' => 'ค่าเริ่มต้นหมวดสำหรับโปรเจคใหม่ (Comma-separated)', - 'Integrations' => 'การใช้ร่วมกัน', - 'Integration with third-party services' => 'การใช้งานร่วมกับบริการ third-party', - 'Subtask Id' => 'รหัสงานย่อย', - 'Subtasks' => 'งานย่อย', - 'Subtasks Export' => 'ส่งออก งานย่อย', - 'Subtasks exportation for "%s"' => 'ส่งออกงานย่อยสำหรับ "%s"', - 'Task Title' => 'ชื่องาน', - 'Untitled' => 'ไม่มีชื่อ', - 'Application default' => 'แอพพลิเคชันเริ่มต้น', - 'Language:' => 'ภาษา:', - 'Timezone:' => 'เขตเวลา:', - 'All columns' => 'คอลัมน์ทั้งหมด', - 'Calendar' => 'ปฏิทิน', - 'Next' => 'ต่อไป', - '#%d' => '#%d', - 'All swimlanes' => 'สวิมเลนทั้งหมด', - 'All colors' => 'สีทั้งหมด', - 'Moved to column %s' => 'เคลื่อนไปคอลัมน์ %s', - '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"', - 'Subtask timesheet' => 'เวลางานย่อย', - 'There is nothing to show.' => 'ไม่มีที่ต้องแสดง', - 'Time Tracking' => 'ติดตามเวลา', - 'You already have one subtask in progress' => 'คุณมีหนึ่งงานย่อยที่กำลังทำงาน', - 'Which parts of the project do you want to duplicate?' => 'เลือกส่วนของโปรเจคที่คุณต้องการทำซ้ำ?', - 'Disallow login form' => 'ไม่อนุญาตให้ใช้แบบฟอร์มการเข้าสู่ระบบ', - 'Start' => 'เริ่ม', - 'End' => 'จบ', - 'Task age in days' => 'อายุงาน', - 'Days in this column' => 'วันในคอลัมน์นี้', - '%dd' => '%d วัน', - 'Add a new link' => 'เพิ่มลิงค์ใหม่', - 'Do you really want to remove this link: "%s"?' => 'คุณต้องการลบลิงค์นี้: "%s"?', - 'Do you really want to remove this link with task #%d?' => 'คุณต้องการลบลิงค์นี้ของงาน #%d?', - 'Field required' => 'ต้องใส่', - 'Link added successfully.' => 'เพิ่มลิงค์เรียบร้อยแล้ว', - 'Link updated successfully.' => 'ปรับปรุงลิงค์เรียบร้อยแล้ว', - 'Link removed successfully.' => 'ลบลิงค์เรียบร้อยแล้ว', - 'Link labels' => 'ป้ายลิงค์', - 'Link modification' => 'แก้ไขลิงค์', - 'Links' => 'ลิงค์', - 'Link settings' => 'ตั้งค่าลิงค์', - 'Opposite label' => 'ป้ายชื่อตรงข้าม', - 'Remove a link' => 'ลบลิงค์', - 'Task\'s links' => 'ลิงค์', - 'The labels must be different' => 'ป้ายชื่อต้องต่างกัน', - 'There is no link.' => 'ไม่มีลิงค์', - 'This label must be unique' => 'ป้ายชื่อต้องไม่ซ้ำกัน', - 'Unable to create your link.' => 'ไม่สามารถสร้างลิงค์ของคุณ', - 'Unable to update your link.' => 'ไม่สามารถปรับปรุงลิงค์ของคุณ', - 'Unable to remove this link.' => 'ไม่สามารถลบลิงค์นี้', - 'relates to' => 'เกี่ยวข้องกับ', - 'blocks' => 'ห้าม', - 'is blocked by' => 'ถูกห้ามด้วย', - 'duplicates' => 'ซ้ำกัน', - 'is duplicated by' => 'ถูกทำซ้ำโดย', - 'is a child of' => 'เป็นลูกของ', - 'is a parent of' => 'เป็นพ่อแม่ของ', - 'targets milestone' => 'เป้าหมาย', - 'is a milestone of' => 'เป็นเป้าหมายของ', - 'fixes' => 'เจาะจง', - 'is fixed by' => 'ถูกเจาะจงด้วย', - 'This task' => 'งานนี้', - '<1h' => '<1 ชม.', - '%dh' => '%d ชม.', - 'Expand tasks' => 'ขยายงาน', - 'Collapse tasks' => 'ย่องาน', - 'Expand/collapse tasks' => 'ขยาย/ย่อ งาน', - 'Close dialog box' => 'ปิดกล่องข้อความ', - 'Submit a form' => 'ยอมรับฟอร์ม', - 'Board view' => 'มุมมองบอร์ด', - 'Keyboard shortcuts' => 'คีย์ลัด', - 'Open board switcher' => 'เปิดการสลับบอร์ด', - 'Application' => 'แอพพลิเคชัน', - 'Compact view' => 'มุมมองพอดี', - 'Horizontal scrolling' => 'เลื่อนตามแนวนอน', - 'Compact/wide view' => 'พอดี/กว้าง มุมมอง', - 'No results match:' => 'ไม่มีผลลัพท์ที่ตรง', - 'Currency' => 'สกุลเงิน', - 'Private project' => 'โปรเจคส่วนตัว', - 'AUD - Australian Dollar' => 'AUD - ดอลลาร์ออสเตรเลีย', - 'CAD - Canadian Dollar' => 'CAD - ดอลลาร์แคนาดา', - 'CHF - Swiss Francs' => 'CHF - ฟรังก์สวิส', - 'Custom Stylesheet' => 'สไตล์ที่กำหนดเอง', - 'download' => 'ดาวน์โหลด', - 'EUR - Euro' => 'EUR - ยูโร', - 'GBP - British Pound' => 'GBP - ปอนด์อังกฤษ', - 'INR - Indian Rupee' => 'INR - รูปี', - 'JPY - Japanese Yen' => 'JPY - เยน', - 'NZD - New Zealand Dollar' => 'NZD - ดอลลาร์นิวซีแลนด์', - 'RSD - Serbian dinar' => 'RSD - ดีนาร์เซอร์เบีย', - 'USD - US Dollar' => 'USD - ดอลลาร์สหรัฐ', - 'Destination column' => 'คอลัมน์เป้าหมาย', - 'Move the task to another column when assigned to a user' => 'ย้ายงานไปคอลัมน์อื่นเมื่อกำหนดบุคคลรับผิดชอบ', - 'Move the task to another column when assignee is cleared' => 'ย้ายงานไปคอลัมน์อื่นเมื่อไม่กำหนดบุคคลรับผิดชอบ', - 'Source column' => 'คอลัมน์ต้นทาง', - 'Transitions' => 'การเปลี่ยนคอลัมน์', - 'Executer' => 'ผู้ประมวลผล', - 'Time spent in the column' => 'เวลาที่ใช้ในคอลัมน์', - 'Task transitions' => 'การเปลี่ยนคอลัมน์งาน', - 'Task transitions export' => 'ส่งออกการเปลี่ยนคอลัมน์งาน', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => 'รายงานนี้มีการเคลื่อนไหวคอลัมน์ทั้งหมดของงานแต่ละงานมีวันที่ผู้ใช้และเวลาที่ใช้สำหรับแต่ละการเปลี่ยนแปลง', - 'Currency rates' => 'อัตราค่าเงิน', - 'Rate' => 'อัตรา', - 'Change reference currency' => 'เปลี่ยนการอ้างถึงค่าเงิน', - 'Add a new currency rate' => 'เพิ่มอัตราค่าเงินใหม่', - 'Reference currency' => 'อ้างถึงค่าเงิน', - 'The currency rate have been added successfully.' => 'เพิ่มอัตราค่าเงินเรียบร้อย', - 'Unable to add this currency rate.' => 'ไม่สามารถเพิ่มค่าเงินนี้', - // 'Webhook URL' => '', - '%s remove the assignee of the task %s' => '%s เอาผู้รับผิดชอบออกจากงาน %s', - 'Enable Gravatar images' => 'สามารถใช้งานภาพ Gravatar', - 'Information' => 'ข้อมูลสารสนเทศ', - // 'Check two factor authentication code' => '', - // 'The two factor authentication code is not valid.' => '', - // 'The two factor authentication code is valid.' => '', - 'Code' => 'รหัส', - // 'Two factor authentication' => '', - // 'This QR code contains the key URI: ' => '', - 'Check my code' => 'ตรวจสอบรหัสของฉัน', - 'Secret key: ' => 'กุญแจลับ', - 'Test your device' => 'ทดสอบอุปกรณ์ของคุณ', - 'Assign a color when the task is moved to a specific column' => 'กำหนดสีเมื่องานถูกย้ายไปคอลัมน์ที่กำหนดไว้', - // '%s via Kanboard' => '', - 'Burndown chart for "%s"' => 'แผนภูมิงานกับเวลา "%s"', - 'Burndown chart' => 'แผนภูมิงานกับเวลา', - 'This chart show the task complexity over the time (Work Remaining).' => 'แผนภูมิแสดงความซับซ้อนของงานตามเวลา (งานที่เหลือ)', - 'Screenshot taken %s' => 'จับภาพหน้าจอ %s', - 'Add a screenshot' => 'เพิ่ม screenshot', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'จับภาพหน้าจอ (screenshot) และกด CTRL+V หรือ ⌘+V เพื่อวางที่นี้', - 'Screenshot uploaded successfully.' => 'อัพโหลด screenshot เรียบร้อยแล้ว', - 'SEK - Swedish Krona' => 'SEK - โครนสวีเดน', - 'Identifier' => 'ตัวบ่งชี้', - // 'Disable two factor authentication' => '', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => 'คุณต้องการยกเลิก the two factor authentication สำหรับผู้ใช้นีั: "%s"?', - 'Edit link' => 'แก้ไขลิงค์', - 'Start to type task title...' => 'พิมพ์ชื่องาน', - 'A task cannot be linked to itself' => 'งานไม่สามารถลิงค์ตัวเอง', - // 'The exact same link already exists' => '', - 'Recurrent task is scheduled to be generated' => 'งานแบบวนลูปถูกสร้างตามที่กำหนดไว้', - 'Score' => 'คะแนน', - 'The identifier must be unique' => 'ตัวบ่งชี้ต้องไม่ซ้ำ', - // 'This linked task id doesn\'t exists' => '', - 'This value must be alphanumeric' => 'ค่านี้ต้องเป็นตัวอักษร', - 'Edit recurrence' => 'แก้ไขการวนลูป', - 'Generate recurrent task' => 'สร้างงานที่เป็นวนลูป', - 'Trigger to generate recurrent task' => 'จะสร้างงานแบบวนลูป', - 'Factor to calculate new due date' => 'ปัจจัยการคำนวณวันครบกำหนดใหม่', - 'Timeframe to calculate new due date' => 'ระยะเวลาการคำนวณวันครบกำหนดใหม่', - 'Base date to calculate new due date' => 'ฐานวันที่การคำนวณวันครบกำหนดใหม่', - 'Action date' => 'วันที่ทำ', - 'Base date to calculate new due date: ' => 'ฐานวันที่การคำนวณวันครบกำหนดใหม่: ', - 'This task has created this child task: ' => 'งานนี้สร้างงานลูกคือ', - 'Day(s)' => 'วัน', - 'Existing due date' => 'วันครบกำหนดที่มีอยู่', - 'Factor to calculate new due date: ' => 'ปัจจัยการคำนวณวันครบกำหนดใหม่: ', - 'Month(s)' => 'เดือน', - 'Recurrence' => 'วนลูป', - 'This task has been created by: ' => 'งานนี้ถูกสร้างโดย', - 'Recurrent task has been generated:' => 'งานแบบวนลูปถูกสร้าง', - 'Timeframe to calculate new due date: ' => 'ระยะเวลาการคำนวณวันครบกำหนดใหม่: ', - 'Trigger to generate recurrent task: ' => 'จะสร้างงานแบบวนลูป', - 'When task is closed' => 'เมื่อปิดงาน', - 'When task is moved from first column' => 'เมื่องานถูกย้ายจากคอลัมน์แรก', - 'When task is moved to last column' => 'เมื่องานถูกย้ายไปคอลัมน์สุดท้าย', - 'Year(s)' => 'ปี', - 'Calendar settings' => 'ตั้งค่าปฏิทิน', - 'Project calendar view' => 'มุมมองปฏิทินของโปรเจค', - 'Project settings' => 'ตั้งค่าโปรเจค', - 'Show subtasks based on the time tracking' => 'แสดงงานย่อยในการติดตามเวลา', - 'Show tasks based on the creation date' => 'แสดงงานจากวันที่สร้าง', - 'Show tasks based on the start date' => 'แสดงงานจากวันที่เริ่ม', - 'Subtasks time tracking' => 'การติดตามเวลางานย่อย', - 'User calendar view' => 'มุมมองปฏิทินของผู้ใช้', - 'Automatically update the start date' => 'ปรับปรุงวันที่เริ่มอัตโนมมัติ', - // 'iCal feed' => '', - // 'Preferences' => '', - 'Security' => 'ความปลอดภัย', - // 'Two factor authentication disabled' => '', - // 'Two factor authentication enabled' => '', - 'Unable to update this user.' => 'ไม่สามารถปรับปรุงผู้ใช้นี้', - 'There is no user management for private projects.' => 'ไม่มีการจัดการผู้ใช้สำหรับโปรเจคส่วนตัว', - 'User that will receive the email' => 'ผู้ใช้จะได้รับอีเมล์', - 'Email subject' => 'หัวเรื่องอีเมล์', - 'Date' => 'วันที่', - 'Add a comment log when moving the task between columns' => 'เพิ่มล็อกความคิดเห็นเมื่อย้ายงานระหว่างคอลัมน์', - 'Move the task to another column when the category is changed' => 'ย้ายงานไปคอลัมน์อื่นเมื่อหมวดถูกเปลี่ยน', - 'Send a task by email to someone' => 'ส่งงานโดยถึงบางคน', - 'Reopen a task' => 'เปิดงานอีกครั้ง', - 'Column change' => 'เปลี่ยนคอลัมน์', - 'Position change' => 'เปลี่ยนตำแหน่ง', - 'Swimlane change' => 'เปลี่ยนสวิมเลน', - 'Assignee change' => 'เปลี่ยนการผู้รับผิดชอบ', - '[%s] Overdue tasks' => '[%s] งานที่เกินกำหนด', - 'Notification' => 'แจ้งเตือน', - '%s moved the task #%d to the first swimlane' => '%s ย้ายงาน #%d ไปสวินเลนแรก', - '%s moved the task #%d to the swimlane "%s"' => '%s ย้ายงาน #%d ไปสวินเลน "%s"', - 'Swimlane' => 'สวิมเลน', - 'Gravatar' => 'รูปแทนตัว', - '%s moved the task %s to the first swimlane' => '%s ย้ายงาน %s ไปสวินเลนแรก', - '%s moved the task %s to the swimlane "%s"' => '%s ย้ายงาน %s ไปสวินเลนไปสวินเลน "%s"', - 'This report contains all subtasks information for the given date range.' => 'รายงานนี้มีข้อมูลงานย่อยทั้งหมดในช่วงวันที่กำหนด', - 'This report contains all tasks information for the given date range.' => 'รายงานนี้มีข้อมูลงานทั้งหมดสำหรับช่วงวันที่ที่กำหนด', - 'Project activities for %s' => 'กิจกรรมโปรเจคสำหรับ %s', - 'view the board on Kanboard' => 'แสดงบอร์ดบนคังบอร์ด', - 'The task have been moved to the first swimlane' => 'งานถูกย้านไปสวิมเลนแรก', - 'The task have been moved to another swimlane:' => 'งานถูกย้านไปสวิมเลนอื่น:', - 'New title: %s' => 'ชื่อเรื่องใหม่: %s', - 'The task is not assigned anymore' => 'ไม่กำหนดผู้รับผิดชอบ', - 'New assignee: %s' => 'ผู้รับผิดชอบใหม่: %s', - 'There is no category now' => 'ปัจจุบันไม่มีหมวด', - 'New category: %s' => 'หมวดใหม่: %s', - 'New color: %s' => 'สีใหม่: %s', - 'New complexity: %d' => 'ความซับซ้อนใหม่: %d', - 'The due date have been removed' => 'วันครบกำหนดถูกลบ', - 'There is no description anymore' => 'ไม่มีคำอธิบาย', - 'Recurrence settings have been modified' => 'แก้ไขการตั้งค่าการวนลูป', - 'Time spent changed: %sh' => 'เวลาที่ใช้ในการเปลี่ยน: %s ชม.', - 'Time estimated changed: %sh' => 'เวลาโดยประมาณในการเปลี่ยน: %s ชม.', - 'The field "%s" have been updated' => 'ฟิลด์ "%s" ถูกปรับปรุง', - 'The description has been modified:' => 'คำอธิบายถูกแก้ไข', - 'Do you really want to close the task "%s" as well as all subtasks?' => 'คุณต้องการปิดงาน "%s" เช่นเดียวกับงานย่อยทั้งหมด?', - 'I want to receive notifications for:' => 'ฉันต้องการรับการแจ้งเตือนสำหรับ:', - 'All tasks' => 'ทุกงาน', - 'Only for tasks assigned to me' => 'เฉพาะงานที่ฉันรับผิดชอบ', - 'Only for tasks created by me' => 'เฉพาะงานที่ฉันสร้าง', - 'Only for tasks created by me and assigned to me' => 'เฉพาะงานที่ฉันสร้างและฉันรับผิดชอบ', - // '%%Y-%%m-%%d' => '', - 'Total for all columns' => 'จำนวนคอลัมน์ทั้งหมด', - 'You need at least 2 days of data to show the chart.' => 'คุณต้องการอย่างน้อย 2 วันในการแสดงแผนภูมิ', - '<15m' => '<15นาที', - '<30m' => '<30นาที', - 'Stop timer' => 'หยุดจับเวลา', - 'Start timer' => 'เริ่มจับเวลา', - 'Add project member' => 'เพิ่มสมาชิกโปรเจค', - 'My activity stream' => 'กิจกรรมที่เกิดขึ้นของฉัน', - 'My calendar' => 'ปฎิทินของฉัน', - 'Search tasks' => 'ค้นหางาน', - 'Reset filters' => 'ล้างตัวกรอง', - 'My tasks due tomorrow' => 'งานถึงกำหนดของฉันวันพรุ่งนี้', - 'Tasks due today' => 'งานถึงกำหนดวันนี้', - 'Tasks due tomorrow' => 'งานถึงกำหนดพรุ่งนี้', - 'Tasks due yesterday' => 'งานถึงกำหนดเมื่อวาน', - 'Closed tasks' => 'งานปิด', - 'Open tasks' => 'งานเปิด', - 'Not assigned' => 'ไม่กำหนดใคร', - 'View advanced search syntax' => 'แสดงรูปแบบการค้นหาขั้นสูง', - 'Overview' => 'ภาพรวม', - 'Board/Calendar/List view' => 'มุมมอง บอร์ด/ปฎิทิน/ลิสต์', - 'Switch to the board view' => 'เปลี่ยนเป็นมุมมองบอร์ด', - 'Switch to the calendar view' => 'เปลี่ยนเป็นมุมมองปฎิทิน', - 'Switch to the list view' => 'เปลี่ยนเป็นมุมมองลิสต์', - 'Go to the search/filter box' => 'ไปที่กล่องค้นหา/ตัวกรอง', - 'There is no activity yet.' => 'ตอนนี้ไม่มีกิจกรรม', - 'No tasks found.' => 'ไม่พบงาน', - 'Keyboard shortcut: "%s"' => 'คีย์ลัด: %s', - 'List' => 'ลิสต์', - 'Filter' => 'ตัวกรอง', - 'Advanced search' => 'ค้นหาขั้นสูง', - 'Example of query: ' => 'ตัวอย่างคิวรี: ', - 'Search by project: ' => 'ค้นหาตามโปรเจค: ', - 'Search by column: ' => 'ค้นหาตามคอลัมน์: ', - 'Search by assignee: ' => 'ค้นหาตามผู้รับผิดชอบ: ', - 'Search by color: ' => 'ค้นหาตามสี: ', - 'Search by category: ' => 'ค้นหาตามหมวด: ', - 'Search by description: ' => 'ค้นหาตามคำอธิบาย: ', - 'Search by due date: ' => 'ค้นหาตามวันครบกำหนด: ', - 'Lead and Cycle time for "%s"' => 'เวลานำและรอบเวลาสำหรับ "%s"', - 'Average time spent into each column for "%s"' => 'ค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์สำหรับ "%s"', - 'Average time spent into each column' => 'ค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์', - 'Average time spent' => 'ค่าเฉลี่ยเวลาที่ใช้', - 'This chart show the average time spent into each column for the last %d tasks.' => 'แผนภูมิแสดงค่าเฉลี่ยเวลาที่ใช้แต่ละคอลัมน์สำหรับ %d งานล่าสุด', - 'Average Lead and Cycle time' => 'ค่าเฉลี่ยเวลานำและรอบเวลา', - 'Average lead time: ' => 'ค่าเฉลี่ยเวลานำ: ', - 'Average cycle time: ' => 'ค่าเฉลี่ยรอบเวลา: ', - 'Cycle Time' => 'รอบเวลา', - 'Lead Time' => 'เวลานำ', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'แผนภูมิแสดงค่าเฉลี่ยเวลานำและรอบเวลาสำหรับ %d งานล่าสุดเมื่อเวลาผ่านไป', - 'Average time into each column' => 'ค่าเฉลี่ยเวลาแต่ละคอลัมน์', - 'Lead and cycle time' => 'เวลานำและรอบเวลา', - 'Lead time: ' => 'เวลานำ: ', - 'Cycle time: ' => 'รอบเวลา: ', - 'Time spent into each column' => 'เวลาที่ใช้แต่ละคอลัมน์', - 'The lead time is the duration between the task creation and the completion.' => 'เวลานำคือระหว่างสร้างงานและจบงาน', - 'The cycle time is the duration between the start date and the completion.' => 'รอบเวลาคือระหว่างวันที่เริ่มและจบงาน', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - 'Set automatically the start date' => 'ตั้งค่าวันที่เริ่มต้นอัตโนมัติ', - 'Edit Authentication' => 'แก้ไขการตรวจสอบ', - 'Remote user' => 'ผู้ใช้รีโมท', - // 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '', - // 'If you check the box "Disallow login form", credentials entered in the login form will be ignored.' => '', - 'New remote user' => 'เพิ่มผู้ใช้รีโมทใหม่', - 'New local user' => 'เพิ่มผู้ใช้ท้องถิ่นใหม่', - 'Default task color' => 'สีเริ่มต้นของงาน', - 'This feature does not work with all browsers.' => 'คุณลักษณะนี้ไม่สามารถทำงานได้ทุกเบราเซอร์', - // 'There is no destination project available.' => '', - 'Trigger automatically subtask time tracking' => 'เรียกโดยอัตโนมัติการติดตามเวลางานย่อย', - // 'Include closed tasks in the cumulative flow diagram' => '', - 'Current swimlane: %s' => 'สวิมเลนปัจจุบัน: %s', - 'Current column: %s' => 'คอลัมน์ปัจจุบัน: %s', - 'Current category: %s' => 'หมวดปัจจุบัน: %s', - 'no category' => 'ไม่มีหมวด', - 'Current assignee: %s' => 'ผู้รับผิดชอบปัจจุบัน: %s', - 'not assigned' => 'ไม่กำหนด', - 'Author:' => 'ผู้แต่ง:', - 'contributors' => 'ผู้ให้กำเนิด', - 'License:' => 'สัญญาอนุญาต:', - 'License' => 'สัญญาอนุญาต', - 'Enter the text below' => 'พิมพ์ข้อความด้านล่าง', - 'Gantt chart for %s' => 'แผนภูมิแกรนท์สำหรับ %s', - 'Sort by position' => 'เรียงตามตำแหน่ง', - 'Sort by date' => 'เรียงตามวัน', - 'Add task' => 'เพิ่มงาน', - 'Start date:' => 'วันที่เริ่ม:', - 'Due date:' => 'วันครบกำหนด:', - 'There is no start date or due date for this task.' => 'งานนี้ไม่มีวันที่เริ่มหรือวันครบกำหนด', - 'Moving or resizing a task will change the start and due date of the task.' => 'การย้ายหรือปรับขนาดงานจะมีการเปลี่ยนแปลงที่วันเริ่มต้นและวันที่ครบกำหนดของงาน', - 'There is no task in your project.' => 'โปรเจคนี้ไม่มีงาน', - 'Gantt chart' => 'แผนภูมิแกรนท์', - 'People who are project managers' => 'คนที่เป็นผู้จัดการโปรเจค', - 'People who are project members' => 'คนที่เป็นสมาชิกโปรเจค', - 'NOK - Norwegian Krone' => 'NOK - โครนนอร์เวย์', - 'Show this column' => 'แสดงคอลัมนี้', - 'Hide this column' => 'ซ่อนคอลัมน์นี้', - 'open file' => 'เปิดไฟล์', - 'End date' => 'วันจบ', - 'Users overview' => 'ภาพรวมผู้ใช้', - 'Members' => 'สมาชิก', - 'Shared project' => 'แชร์โปรเจค', - 'Project managers' => 'ผู้จัดการโปรเจค', - 'Gantt chart for all projects' => 'แผนภูมิแกรนท์สำหรับทุกโปรเจค', - 'Projects list' => 'รายการโปรเจค', - 'Gantt chart for this project' => 'แผนภูมิแกรนท์สำหรับโปรเจคนี้', - 'Project board' => 'บอร์ดโปรเจค', - 'End date:' => 'วันที่จบ:', - 'There is no start date or end date for this project.' => 'ไม่มีวันที่เริ่มหรือวันที่จบของโปรเจคนี้', - 'Projects Gantt chart' => 'แผนภูมิแกรน์ของโปรเจค', - 'Change task color when using a specific task link' => 'เปลี่ยนสีงานเมื่อมีการใช้การเชื่อมโยงงาน', - 'Task link creation or modification' => 'การสร้างการเชื่อมโยงงานหรือการปรับเปลี่ยน', - 'Milestone' => 'ขั้น', - 'Documentation: %s' => 'เอกสาร: %s', - 'Switch to the Gantt chart view' => 'เปลี่ยนเป็นมุมมองแผนภูมิแกรนท์', - 'Reset the search/filter box' => 'รีเซตกล่องค้นหา/ตัวกรอง', - 'Documentation' => 'เอกสาร', - 'Table of contents' => 'สารบัญ', - 'Gantt' => 'แกรนท์', - 'Author' => 'ผู้แต่ง', - 'Version' => 'เวอร์ชัน', - 'Plugins' => 'ปลั๊กอิน', - 'There is no plugin loaded.' => 'ไม่มีปลั๊กอินถูกโหลดไว้', - 'Set maximum column height' => 'กำหนดความสูงสูงสุดของคอลัมน์', - 'Remove maximum column height' => 'เอาความสูงสูงสุดของคอลัมน์ออก', - 'My notifications' => 'การแจ้งเตือนของฉัน', - 'Custom filters' => 'ตัวกรองกำหนดเอง', - 'Your custom filter have been created successfully.' => 'ตัวกรองกำหนดเองของคุณสร้างเรียบร้อย', - 'Unable to create your custom filter.' => 'ไม่สามารถสร้างตัวกรองกำหนดเอง', - 'Custom filter removed successfully.' => 'ลบตัวกรองกำหนดเองเรียบร้อย', - 'Unable to remove this custom filter.' => 'ไม่สามารถลบตัวกรองกำหนดเอง', - 'Edit custom filter' => 'แก้ไขตัวกรองกำหนดเอง', - 'Your custom filter have been updated successfully.' => 'ตัวกรองกำหนดเองของคุณแก้ไขเรียบร้อย', - 'Unable to update custom filter.' => 'ไม่สามารถแก้ไขตัวกรองกำหนดเอง', - 'Web' => 'เวบ', - 'New attachment on task #%d: %s' => 'แนบใหม่ของงาน #%d: %s', - 'New comment on task #%d' => 'ความคิดเห็นใหม่ของงาน #%d', - 'Comment updated on task #%d' => 'แก้ไขความคิดเห็นของงาน #%d', - 'New subtask on task #%d' => 'งานย่อยใหม่ของงาน #%d', - 'Subtask updated on task #%d' => 'แก้ไขงานย่อยของงาน #%d', - 'New task #%d: %s' => 'งานใหม่ #%d: %s', - 'Task updated #%d' => 'แก้ไขงาน #%d', - 'Task #%d closed' => 'ปิดงาน #%d', - 'Task #%d opened' => 'เปิดงาน #%d', - 'Column changed for task #%d' => 'เปลี่ยนคอลัมน์สำหรับงาน #%d', - 'New position for task #%d' => 'ตำแหน่งใหม่ของงาน #%d', - 'Swimlane changed for task #%d' => 'เปลี่ยนสวิมเลนสำหรับงาน #%d', - 'Assignee changed on task #%d' => 'เปลี่ยนผู้รับผิดชอบงาน #%d', - '%d overdue tasks' => '%d งานเกินกำหนด', - 'Task #%d is overdue' => 'งาน #%d เกินกำหนด', - 'No new notifications.' => 'ไม่มีการแจ้งเตือนใหม่', - 'Mark all as read' => 'มาร์คทั้งหมดว่าอ่านแล้ว', - 'Mark as read' => 'มาร์คว่าอ่านแล้ว', - // 'Total number of tasks in this column across all swimlanes' => '', - 'Collapse swimlane' => 'ย่อสวิมเลน', - 'Expand swimlane' => 'ขยายสวิมเลน', - 'Add a new filter' => 'เพิ่มตัวกรองใหม่', - 'Share with all project members' => 'แชร์ให้สมาชิกทุกคนของโปรเจค', - 'Shared' => 'แชร์', - 'Owner' => 'เจ้าของ', - 'Unread notifications' => 'การแจ้งเตือนยังไม่ได้อ่าน', - 'Notification methods:' => 'ลักษณะการแจ้งเตือน:', - 'Import tasks from CSV file' => 'นำเข้างานจากไฟล์ CSV', - 'Unable to read your file' => 'ไม่สามารถอ่านไฟล์ของคุณ', - '%d task(s) have been imported successfully.' => '%d งานนำเข้าเรียบร้อย', - 'Nothing have been imported!' => 'ไม่มีอะไรถูกนำเข้า', - 'Import users from CSV file' => 'นำเข้าผู้ใช้จากไฟล์ CSV', - '%d user(s) have been imported successfully.' => '%d ผู้ใช้นำเข้าเรียบร้อย', - 'Comma' => ', - Comma', - 'Semi-colon' => '; - Semi-colon', - 'Tab' => 'Tab - Tab', - 'Vertical bar' => '| - Vertical bar', - 'Double Quote' => '" " - Double Quote', - 'Single Quote' => '\' \' - Single Quote', - '%s attached a file to the task #%d' => '%s แนบไฟล์ในงาน #%d', - 'There is no column or swimlane activated in your project!' => 'ไม่มีคอลัมน์หรือสวิมเลนเปิดใช้งานในโปรเจคของคุณ!', - // 'Append filter (instead of replacement)' => '', - 'Append/Replace' => 'เพิ่มเติม/แทนที่', - 'Append' => 'เพิ่มเติม', - 'Replace' => 'แทนที่', - 'Import' => 'นำเข้า', - 'change sorting' => 'เปลี่ยนการเรียง', - 'Tasks Importation' => 'การนำเข้างาน', - 'Delimiter' => 'คั่น', - 'Enclosure' => 'กำหนดข้อความ', - 'CSV File' => 'ไฟล์ CSV', - 'Instructions' => 'คำสั่ง', - 'Your file must use the predefined CSV format' => 'ไฟล์ของคุณจะต้องใช้รูปแบบ CSV ที่กำหนดไว้ล่วงหน้า', - 'Your file must be encoded in UTF-8' => 'ไฟล์ของคุณต้องเอนโค้ดด้วย UTF-8', - 'The first row must be the header' => 'แถวแรกต้องเป็นหัวข้อ', - 'Duplicates are not verified for you' => 'รายการที่ซ้ำกันจะไม่ได้รับการตรวจสอบสำหรับคุณ', - 'The due date must use the ISO format: YYYY-MM-DD' => 'วันที่ต้องอยู่ในรูปแบบ ISO: YYYY-MM-DD', - 'Download CSV template' => 'ดาวน์โหลด CSV ต้นฉบับ', - 'No external integration registered.' => 'ไม่มีการรวมภายนอกถูกลงทะเบียนไว้', - 'Duplicates are not imported' => 'ซ้ำกันไม่สามารถนำเข้าได้', - 'Usernames must be lowercase and unique' => 'ชื่อผู้ใช้ต้องเป็นตัวพิมพ์เล็กและไม่ซ้ำ', - // 'Passwords will be encrypted if present' => '', - '%s attached a new file to the task %s' => '%s แนบไฟล์ใหม่ในงาน %s', - 'Link type' => 'ประเภทลิงค์', - 'Assign automatically a category based on a link' => 'กำหนดหมวดอัตโนมัติตามลิงค์', - // 'BAM - Konvertible Mark' => '', - 'Assignee Username' => 'กำหนดชื่อผู้ใช้', - 'Assignee Name' => 'กำหนดชื่อ', - 'Groups' => 'กลุ่ม', - 'Members of %s' => 'สมาชิกของ %s', - 'New group' => 'กลุ่มใหม่', - 'Group created successfully.' => 'สร้างกลุ่มสำเร็จ', - 'Unable to create your group.' => 'ไม่สามารถสร้างกลุ่มของคุณ', - 'Edit group' => 'แก้ไขกลุ่ม', - 'Group updated successfully.' => 'แก้ไขกลุ่มเรียบร้อย', - 'Unable to update your group.' => 'ไม่สามารถแก้ไขกลุ่มของคุณ', - 'Add group member to "%s"' => 'เพิ่มสมาชิกในกลุ่ม %s', - 'Group member added successfully.' => 'เพิ่มสมาชิกกลุ่มเรียบร้อย', - 'Unable to add group member.' => 'ไม่สามารถเพิ่มสมาชิกกลุ่ม', - 'Remove user from group "%s"' => 'เอาผู้ใช้ออกจากกลุ่ม %s', - 'User removed successfully from this group.' => 'เอาผู้ใช้ออกจากกลุ่มนี้เรียบร้อย', - 'Unable to remove this user from the group.' => 'ไม่สามารถลบผู้ใช้ออกจากกลุ่มนี้', - 'Remove group' => 'ลบกลุ่ม', - 'Group removed successfully.' => 'ลบกลุ่มเรียบร้อย', - 'Unable to remove this group.' => 'ไม่สามารถลบกลุ่มนี้', - 'Project Permissions' => 'การอนุญาตใช้งานโปรเจค', - 'Manager' => 'ผู้จัดการ', - 'Project Manager' => 'ผู้จัดการโปรเจค', - 'Project Member' => 'สมาชิกโปรเจค', - 'Project Viewer' => 'ผู้ดูโปรเจค', - 'Your account is locked for %d minutes' => 'บัญชีของคุณถูกล็อก %d นาที', - 'Invalid captcha' => 'captcha ไม่ถูกต้อง', - 'The name must be unique' => 'ชื่อต้องไม่ซ้ำ', - 'View all groups' => 'แสดงกลุ่มทั้งหมด', - 'View group members' => 'แสดงสมาชิกกลุ่ม', - // 'There is no user available.' => '', - 'Do you really want to remove the user "%s" from the group "%s"?' => 'คุณต้องการลบผู้ใช้ "%s" ออกจากกลุ่ม "%s"?', - 'There is no group.' => 'ไม่มีกลุ่ม', - 'External Id' => 'ไอดีภายนอก', - 'Add group member' => 'เพิ่มสมาชิกกลุ่ม', - 'Do you really want to remove this group: "%s"?' => 'คุณต้องการลบกลุ่มนี้: "%s"?', - 'There is no user in this group.' => 'ไม่มีผู้ใช้ในกลุ่มนี้', - 'Remove this user' => 'เอาผู้ใช้คนนี้ออก', - 'Permissions' => 'การอนุญาตใช้งาน', - 'Allowed Users' => 'การอนุญาตผู้ใช้', - 'No user have been allowed specifically.' => 'ไม่มีผู้ใช้ได้รับอนุญาติเป็นพิเศษ', - 'Role' => 'บทบาท', - 'Enter user name...' => 'พิมพ์ชื่อผู้ใช้...', - 'Allowed Groups' => 'อนุญาตกลุ่ม', - 'No group have been allowed specifically.' => 'ไม่มีกลุ่มได้รับอนุญาติเป็นพิเศษ', - 'Group' => 'กลุ่ม', - 'Group Name' => 'ชื่อกลุ่ม', - 'Enter group name...' => 'พิมพ์ชื่อกลุ่ม...', - 'Role:' => 'บทบาท:', - 'Project members' => 'สมาชิกโปรเจค', - 'Compare hours for "%s"' => 'เปรียบเทียบรายชั่วโมงสำหรับ %s', - '%s mentioned you in the task #%d' => '%s กล่าวถึงคุณในงาน #%d', - '%s mentioned you in a comment on the task #%d' => '%s กล่าวถึงคุณในความคิดเห็นของงาน #%d', - 'You were mentioned in the task #%d' => 'คุณได้รับการกล่าวถึงในงาน #%d', - 'You were mentioned in a comment on the task #%d' => 'คุณได้รับการกล่าวถึงในความคิดเห็นของงาน #%d', - 'Mentioned' => 'กล่าวถึง', - 'Compare Estimated Time vs Actual Time' => 'เปรียบเทียบเวลาโดยประมาณกับเวลาที่เกิดขึ้นจริง', - 'Estimated hours: ' => 'เวลาโดยประมาณ:', - 'Actual hours: ' => 'เวลาที่เกิดขึ้นจริง:', - 'Hours Spent' => 'เวลาที่ใช้', - 'Hours Estimated' => 'เวลาโดยประมาณ', - 'Estimated Time' => 'เวลาโดยประมาณ', - 'Actual Time' => 'เวลาที่ใช้', - 'Estimated vs actual time' => 'เวลาโดยประมาณกับเวลาจริง', - 'RUB - Russian Ruble' => 'RUB - รูเบิลรัสเซีย', - 'Assign the task to the person who does the action when the column is changed' => 'กำหนดผู้รับผิดชอบงานเมื่อเปลี่ยนคอลัมน์', - 'Close a task in a specific column' => 'ปิดงานในคอลัมน์ที่เฉพาะเจาะจง', - // 'Time-based One-time Password Algorithm' => '', - // 'Two-Factor Provider: ' => '', - // 'Disable two-factor authentication' => '', - // 'Enable two-factor authentication' => '', - // 'There is no integration registered at the moment.' => '', - 'Password Reset for Kanboard' => 'รีเซตรหัสผ่านสำหรับคังบอร์ด', - 'Forgot password?' => 'ลืมรหัสผ่าน?', - 'Enable "Forget Password"' => 'เปิดการใช้งาน "ลืมรหัสผ่าน"', - 'Password Reset' => 'รีเซตรหัสผ่าน', - 'New password' => 'รหัสผ่านใหม่', - 'Change Password' => 'เปลี่ยนรหัสผ่าน', - 'To reset your password click on this link:' => 'ในการรีเซตรหัสผ่านของคุณคลิ๊กที่ลิงค์นี้:', - 'Last Password Reset' => 'รีเซตรหัสผ่านครั้งล่าสุด', - 'The password has never been reinitialized.' => 'รหัสผ่านไม่เคยเริ่มใหม่อีกครั้ง', - 'Creation' => 'สร้าง', - 'Expiration' => 'สิ้นสุด', - 'Password reset history' => 'ประวัติการรีเซตรหัสผ่าน', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => 'ทุกงานของคอลัมน์ "%s" และสวิมเลน "%s" ถูกปิดเรียบร้อย', - 'Do you really want to close all tasks of this column?' => 'คุณต้องการปิดทุกงานในคอลัมนี้ใช่หรือไม่?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '%d งานในคอลัมน์ "%s" และสวิมเลน "%s" จะปิด', - 'Close all tasks of this column' => 'ปิดทุกงานในคอลัมน์นี้', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => 'ปลั๊กอินไม่ได้ลงทะเบียนการแจ้งเตือนในโปรเจค คุณยังสามารถกำหนดค่าการแจ้งเตือนรายบุคคลในโปรไฟล์ผู้ใช้ของคุณ', - 'My dashboard' => 'แดชบอร์ดของฉํน', - 'My profile' => 'โปรเจคของฉัน', - 'Project owner: ' => 'เจ้าของโปรเจค: ', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => 'ตัวบ่งชี้โปรโจคเป็นตัวเลือกเสริมและต้องเป็นตัวอักษรหรือตัวเลข ตัวอย่าง: MYPROJECT', - 'Project owner' => 'เจ้าของโปรเจค', - 'Those dates are useful for the project Gantt chart.' => 'วันที่ใช้สำหรับแผนภูมิแกรนท์ของโปรเจค', - 'Private projects do not have users and groups management.' => 'โปรเจคส่วนตัวไม่มีการจัดการผู้ใช้และกลุ่ม', - 'There is no project member.' => 'ไม่มีสมาชิกโปรเจค', - 'Priority' => 'ความสำคัญ', - 'Task priority' => 'ความสำคัญของงาน', - 'General' => 'ทั่วไป', - 'Dates' => 'วันที่', - 'Default priority' => 'ความสำคัญเริ่มต้น', - 'Lowest priority' => 'ความสำคัญต่ำสุด', - 'Highest priority' => 'ความสำคัญสูงสุด', - 'If you put zero to the low and high priority, this feature will be disabled.' => 'ถ้าคุณใส่เลขศูนย์ทั้งความสำคัญต่ำและความสำคัญสูง จะเป็นการปิดการทำงานคุณลักษณะนี้', - 'Close a task when there is no activity' => 'ปิดงานเมื่อไม่มีกิจกกรมเกิดขึ้น', - 'Duration in days' => 'ระยะเวลาวันที่', - 'Send email when there is no activity on a task' => 'ส่งอีเมลเมื่อไม่มีกิจกรรมเกิดขึ้นในงาน', - 'Unable to fetch link information.' => 'ไม่สามารถดึงข้อมูลการเชื่อมโยง', - // 'Daily background job for tasks' => '', - 'Auto' => 'อัตโนมัติ', - 'Related' => 'ที่เกี่ยวข้อง', - 'Attachment' => 'แนบ', - 'Title not found' => 'ไม่พบหัวเรื่อง', - 'Web Link' => 'เวบลิงค์', - 'External links' => 'เชื่อมโยงภายนอก', - 'Add external link' => 'เพิ่มการเชื่อมโยงภายนอก', - 'Type' => 'ประเภท', - 'Dependency' => 'ขึ้นอยู่กับ', - 'Add internal link' => 'เพิ่มการเชื่อมโยงภายใน', - 'Add a new external link' => 'เพิ่มการเชื่อมโยงภายนอกใหม่', - 'Edit external link' => 'แก้ไขการเชื่อมโยงภายนอก', - 'External link' => 'เชื่อมโยงภายนอก', - 'Copy and paste your link here...' => 'คัดลอกและวางลิงค์ของคุณที่นี้...', - 'URL' => 'URL', - 'Internal links' => 'เชื่อมโยงภายใน', - 'Assign to me' => 'ฉันรับผิดชอบ', - 'Me' => 'ฉัน', - // 'Do not duplicate anything' => '', - 'Projects management' => 'การจัดการโปรเจค', - 'Users management' => 'การจัดการผู้ใช้', - 'Groups management' => 'การจัดการกลุ่ม', - 'Create from another project' => 'สร้างโปรเจคอื่น', - 'open' => 'เปิด', - 'closed' => 'ปิด', - 'Priority:' => 'ความสำคัญ:', - 'Reference:' => 'อ้างถึง:', - 'Complexity:' => 'ความซับซ้อน:', - 'Swimlane:' => 'สวิมเลน:', - 'Column:' => 'คอลัมน์:', - 'Position:' => 'ตำแหน่ง:', - 'Creator:' => 'ผู้สร้าง:', - 'Time estimated:' => 'เวลาเฉลี่ย:', - '%s hours' => '%s ชั่วโมง', - 'Time spent:' => 'ใช้เวลา:', - 'Created:' => 'สร้าง:', - 'Modified:' => 'แก้ไข:', - 'Completed:' => 'เสร็จสิ้น:', - 'Started:' => 'เริ่ม:', - 'Moved:' => 'ย้าย:', - 'Task #%d' => 'งานที่ #%d', - 'Date and time format' => 'รูปแบบของวันเวลา', - 'Time format' => 'รูปแบบของเวลา', - 'Start date: ' => 'เริ่มวันที่:', - 'End date: ' => 'จบวันที่:', - 'New due date: ' => 'วันครบกำหนดใหม่', - 'Start date changed: ' => 'เปลี่ยนวันที่เริ่ม', - // 'Disable private projects' => '', - // 'Do you really want to remove this custom filter: "%s"?' => '', - // '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/tr_TR/translations.php b/sources/app/Locale/tr_TR/translations.php deleted file mode 100644 index 41e2259..0000000 --- a/sources/app/Locale/tr_TR/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - // 'number.decimals_separator' => '', - // 'number.thousands_separator' => '', - 'None' => 'Hiçbiri', - 'edit' => 'düzenle', - 'Edit' => 'Düzenle', - 'remove' => 'sil', - 'Remove' => 'Sil', - 'Yes' => 'Evet', - 'No' => 'Hayır', - 'cancel' => 'İptal', - 'or' => 'veya', - 'Yellow' => 'Sarı', - 'Blue' => 'Mavi', - 'Green' => 'Yeşil', - 'Purple' => 'Mor', - 'Red' => 'Kırmızı', - 'Orange' => 'Turuncu', - 'Grey' => 'Gri', - 'Brown' => 'Kahverengi', - 'Deep Orange' => 'Koyu Turuncu', - 'Dark Grey' => 'Koyu Gri', - 'Pink' => 'Pembe', - 'Teal' => 'Turkuaz', - 'Cyan' => 'Cam Göbeği', - 'Lime' => 'Limon rengi', - 'Light Green' => 'Açık Yeşil', - 'Amber' => 'Koyu sarı', - 'Save' => 'Kaydet', - 'Login' => 'Giriş', - 'Official website:' => 'Resmi internet sitesi:', - 'Unassigned' => 'Atanmamış', - 'View this task' => 'Bu görevi görüntüle', - 'Remove user' => 'Kullanıcıyı kaldır', - 'Do you really want to remove this user: "%s"?' => 'Bu kullanıcıyı gerçekten silmek istiyor musunuz: "%s"?', - 'All users' => 'Tüm kullanıcılar', - 'Username' => 'Kullanıcı adı', - 'Password' => 'Şifre', - 'Administrator' => 'Yönetici', - 'Sign in' => 'Giriş yap', - 'Users' => 'Kullanıcılar', - 'No user' => 'Kullanıcı yok', - 'Forbidden' => 'Yasak', - 'Access Forbidden' => 'Erişim yasak', - 'Edit user' => 'Kullanıcıyı düzenle', - 'Logout' => 'Çıkış yap', - 'Bad username or password' => 'Hatalı kullanıcı adı veya şifre', - 'Edit project' => 'Projeyi düzenle', - 'Name' => 'İsim', - 'Projects' => 'Projeler', - 'No project' => 'Proje yok', - 'Project' => 'Proje', - 'Status' => 'Durum', - 'Tasks' => 'Görevler', - 'Board' => 'Tablo', - 'Actions' => 'İşlemler', - 'Inactive' => 'Aktif değil', - 'Active' => 'Aktif', - '%d tasks on the board' => '%d görev bu tabloda', - '%d tasks in total' => '%d görev toplam', - 'Unable to update this board.' => 'Bu tablo güncellenemiyor.', - 'Edit board' => 'Tabloyu düzenle', - 'Disable' => 'Devre dışı bırak', - 'Enable' => 'Etkinleştir', - 'New project' => 'Yeni proje', - 'Do you really want to remove this project: "%s"?' => 'Bu projeyi gerçekten silmek istiyor musunuz: "%s"?', - 'Remove project' => 'Projeyi sil', - 'Edit the board for "%s"' => 'Tabloyu "%s" için güncelle', - 'All projects' => 'Tüm projeler', - '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!', - 'Settings' => 'Ayarlar', - 'Application settings' => 'Uygulama ayarları', - 'Language' => 'Dil', - // 'Webhook token:' => '', - 'API token:' => 'API belirteci:', - 'Database size:' => 'Veritabanı boyutu :', - 'Download the database' => 'Veritabanını indir', - 'Optimize the database' => 'Veritabanını optimize et', - '(VACUUM command)' => '(VACUUM komutu)', - '(Gzip compressed Sqlite file)' => '(Gzip ile sıkıştırılmış Sqlite dosyası)', - 'Close a task' => 'Bir görevi kapat', - 'Edit a task' => 'Bir görevi düzenle', - 'Column' => 'Sütun', - 'Color' => 'Renk', - 'Assignee' => 'Atanan', - 'Create another task' => 'Başka bir görev oluştur', - 'New task' => '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', - 'There is nobody assigned' => 'Kimse atanmamış', - 'Column on the board:' => 'Tablodaki sütun:', - 'Close this task' => 'Görevi kapat', - 'Open this task' => 'Görevi aç', - 'There is no description.' => 'Açıklama yok.', - 'Add a new task' => 'Yeni görev ekle', - 'The username is required' => 'Kullanıcı adı gerekli', - 'The maximum length is %d characters' => 'Maksimum uzunluk %d karakterdir', - 'The minimum length is %d characters' => 'Minimum uzunluk %d karakterdir', - 'The password is required' => 'Şifre gerekli', - 'This value must be an integer' => 'Bu değer bir rakam olmak zorunda', - 'The username must be unique' => 'Kullanıcı adı daha önceden var', - 'The user id is required' => 'Kullanıcı kodu gerekli', - 'Passwords don\'t match' => 'Şifreler uyuşmuyor', - 'The confirmation is required' => 'Onay gerekli', - 'The project is required' => 'Proje gerekli', - 'The id is required' => 'Kod gerekli', - 'The project id is required' => 'Proje kodu gerekli', - 'The project name is required' => 'Proje adı gerekli', - 'The title is required' => 'Başlık gerekli', - 'Settings saved successfully.' => 'Ayarlar başarıyla kaydedildi.', - 'Unable to save your settings.' => 'Ayarlarınız kaydedilemedi.', - 'Database optimization done.' => 'Veritabanı optimizasyonu tamamlandı.', - 'Your project have been created successfully.' => 'Projeniz başarıyla oluşturuldu.', - 'Unable to create your project.' => 'Proje oluşturulamadı.', - 'Project updated successfully.' => 'Proje başarıyla güncellendi.', - 'Unable to update this project.' => 'Bu proje güncellenemedi.', - 'Unable to remove this project.' => 'Bu proje silinemedi.', - 'Project removed successfully.' => 'Proje başarıyla silindi.', - 'Project activated successfully.' => 'Proje başarıyla aktive edildi.', - 'Unable to activate this project.' => 'Bu proje aktive edilemedi.', - 'Project disabled successfully.' => 'Proje devre dışı bırakıldı.', - 'Unable to disable this project.' => 'Bu proje devre dışı bırakılamadı.', - 'Unable to open this task.' => 'Bu görev açılamıyor.', - 'Task opened successfully.' => 'Görev başarıyla açıldı.', - 'Unable to close this task.' => 'Bu görev kapatılamıyor.', - 'Task closed successfully.' => 'Görev başarıyla kapatıldı.', - 'Unable to update your task.' => 'Görev güncellenemiyor.', - 'Task updated successfully.' => 'Görev başarıyla güncellendi.', - 'Unable to create your task.' => 'Görev oluşturulamadı.', - 'Task created successfully.' => 'Görev başarıyla oluşturuldu.', - 'User created successfully.' => 'Kullanıcı başarıyla oluşturuldu', - 'Unable to create your user.' => 'Kullanıcı oluşturulamıyor.', - 'User updated successfully.' => 'Kullanıcı başarıyla güncellendi.', - 'Unable to update your user.' => 'Kullanıcı güncellenemiyor.', - 'User removed successfully.' => 'Kullanıcı silindi.', - 'Unable to remove this user.' => 'Bu kullanıcı silinemiyor.', - 'Board updated successfully.' => 'Tablo başarıyla güncellendi.', - 'Ready' => 'Hazır', - 'Backlog' => 'Bekleme listesi', - 'Work in progress' => 'İşlemde', - 'Done' => 'Tamamlandı', - 'Application version:' => 'Uygulama versiyonu:', - 'Id' => 'Kod', - '%d closed tasks' => '%d kapatılmış görevler', - 'No task for this project' => 'Bu proje için görev yok', - 'Public link' => 'Dışa açık link', - 'Timezone' => 'Saat dilimi', - 'Sorry, I didn\'t find this information in my database!' => 'Üzgünüm, bu bilgiyi veri tabanımda bulamadım.', - 'Page not found' => 'Sayfa bulunamadı', - 'Complexity' => 'Zorluk seviyesi', - 'Task limit' => 'Görev limiti', - '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', - 'Invalid date' => 'Geçersiz tarihi', - 'Automatic actions' => 'Otomatik işlemler', - 'Your automatic action have been created successfully.' => 'Otomatik işlem başarıyla oluşturuldu', - 'Unable to create your automatic action.' => 'Otomatik işleminiz oluşturulamadı', - 'Remove an action' => 'Bir işlemi sil', - 'Unable to remove this action.' => 'Bu işlem silinemedi', - 'Action removed successfully.' => 'İşlem başarıyla silindi', - 'Automatic actions for the project "%s"' => '"%s" projesi için otomatik işlemler', - 'Add an action' => 'İşlem ekle', - 'Event name' => 'Durum adı', - 'Action name' => 'İşlem adı', - 'Action parameters' => 'İşlem parametreleri', - 'Action' => 'İşlem', - 'Event' => 'Durum', - 'When the selected event occurs execute the corresponding action.' => 'Seçilen durum oluştuğunda ilgili eylemi gerçekleştir.', - 'Next step' => 'Sonraki adım', - 'Define action parameters' => 'İşlem parametrelerini düzenle', - 'Do you really want to remove this action: "%s"?' => 'Bu işlemi silmek istediğinize emin misiniz: "%s"?', - 'Remove an automatic action' => 'Bir otomatik işlemi sil', - 'Assign the task to a specific user' => 'Görevi bir kullanıcıya ata', - 'Assign the task to the person who does the action' => 'Görevi, işlemi gerçekleştiren kullanıcıya ata', - 'Duplicate the task to another project' => 'Görevi bir başka projeye kopyala', - 'Move a task to another column' => 'Bir görevi başka bir sütuna taşı', - 'Task modification' => 'Görev düzenleme', - 'Task creation' => 'Görev oluşturma', - 'Closing a task' => 'Bir görev kapatılıyor', - 'Assign a color to a specific user' => 'Bir kullanıcıya renk tanımla', - 'Column title' => 'Sütun başlığı', - 'Position' => 'Pozisyon', - 'Duplicate to another project' => 'Başka bir projeye kopyala', - 'Duplicate' => 'Kopya oluştur', - 'link' => 'bağlantı', - 'Comment updated successfully.' => 'Yorum güncellendi.', - 'Unable to update your comment.' => 'Yorum güncellenemedi.', - 'Remove a comment' => 'Bir yorumu sil', - 'Comment removed successfully.' => 'Yorum silindi.', - 'Unable to remove this comment.' => 'Bu yorum silinemiyor.', - 'Do you really want to remove this comment?' => 'Bu yorumu silmek istediğinize emin misiniz?', - 'Current password for the user "%s"' => 'Kullanıcı için mevcut şifre "%s"', - 'The current password is required' => 'Mevcut şifre gerekli', - 'Wrong password' => 'Yanlış şifre', - 'Unknown' => 'Bilinmeyen', - 'Last logins' => 'Son kullanıcı girişleri', - 'Login date' => 'Giriş tarihi', - 'Authentication method' => 'Doğrulama yöntemi', - 'IP address' => 'IP adresi', - 'User agent' => 'Kullanıcı sistemi', - 'Persistent connections' => 'Kalıcı bağlantılar', - 'No session.' => 'Oturum yok.', - 'Expiration date' => 'Geçerlilik sonu', - 'Remember Me' => 'Beni hatırla', - 'Creation date' => 'Oluşturulma tarihi', - 'Everybody' => 'Herkes', - 'Open' => 'Açık', - 'Closed' => 'Kapalı', - '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', - 'Email address invalid' => 'E-posta adresi geçersiz', - 'Your external account is not linked anymore to your profile.' => 'Harici hesabınız artık profilinize bağlı değil', - 'Unable to unlink your external account.' => 'Harici hesabınızla bağlantı koparılamadı', - 'External authentication failed' => 'Harici hesap doğrulaması başarısız', - 'Your external account is linked to your profile successfully.' => 'Harici hesabınız profilinizle başarıyla bağlandı.', - 'Email' => 'E-posta', - 'Task removed successfully.' => 'Görev başarıyla silindi.', - 'Unable to remove this task.' => 'Görev silinemiyor.', - 'Remove a task' => 'Bir görevi sil', - 'Do you really want to remove this task: "%s"?' => 'Bu görevi silmek istediğinize emin misiniz: "%s"?', - 'Assign automatically a color based on a category' => 'Kategoriye göre otomatik renk ata', - 'Assign automatically a category based on a color' => 'Rengine göre otomatik kategori ata', - 'Task creation or modification' => 'Görev oluşturma veya düzenleme', - 'Category' => 'Kategori', - 'Category:' => 'Kategori:', - 'Categories' => 'Kategoriler', - 'Your category have been created successfully.' => 'Kategori başarıyla oluşturuldu.', - 'Unable to create your category.' => 'Kategori oluşturulamadı.', - 'Your category have been updated successfully.' => 'Kategori başarıyla güncellendi.', - 'Unable to update your category.' => 'Kategori güncellenemedi.', - 'Remove a category' => 'Bir kategoriyi sil', - 'Category removed successfully.' => 'Kategori başarıyla silindi.', - 'Unable to remove this category.' => 'Bu kategori silinemedi.', - 'Category modification for the project "%s"' => '"%s" projesi için kategori düzenleme', - 'Category Name' => 'Kategori adı', - 'Add a new category' => 'Yeni kategori ekle', - 'Do you really want to remove this category: "%s"?' => 'Bu kategoriyi silmek istediğinize emin misiniz: "%s"?', - 'All categories' => 'Tüm kategoriler', - 'No category' => 'Kategori Yok', - 'The name is required' => 'İsim gerekli', - 'Remove a file' => 'Dosya sil', - 'Unable to remove this file.' => 'Dosya silinemedi', - 'File removed successfully.' => 'Dosya silindi', - 'Attach a document' => 'Dosya ekle', - 'Do you really want to remove this file: "%s"?' => 'Bu dosyayı silmek istediğinize emin misiniz: "%s"?', - 'Attachments' => 'Ekler', - 'Edit the task' => 'Görevi değiştir', - 'Add a comment' => 'Yorum ekle', - 'Edit a comment' => 'Yorum değiştir', - 'Summary' => 'Özet', - 'Time tracking' => 'Zaman takibi', - 'Estimate:' => 'Tahmini:', - 'Spent:' => 'Harcanan:', - 'Do you really want to remove this sub-task?' => 'Bu alt görevi silmek istediğinize emin misiniz', - 'Remaining:' => 'Kalan', - 'hours' => 'saat', - 'spent' => 'harcanan', - 'estimated' => 'tahmini', - 'Sub-Tasks' => 'Alt Görev', - 'Add a sub-task' => 'Alt görev ekle', - 'Original estimate' => 'Orjinal tahmin', - 'Create another sub-task' => 'Başka bir alt görev daha oluştur', - 'Time spent' => 'Harcanan zaman', - '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ı', - 'Todo' => 'Yapılacaklar', - 'In progress' => 'Devam etmekte', - 'Sub-task removed successfully.' => 'Alt görev başarıyla silindi.', - 'Unable to remove this sub-task.' => 'Alt görev silinemedi.', - 'Sub-task updated successfully.' => 'Alt görev güncellendi.', - 'Unable to update your sub-task.' => 'Alt görev güncellenemiyor.', - 'Unable to create your sub-task.' => 'Alt görev oluşturulamadı.', - 'Sub-task added successfully.' => 'Alt görev başarıyla eklendi.', - 'Maximum size: ' => 'Maksimum boyutu', - 'Unable to upload the file.' => 'Dosya yüklenemiyor.', - 'Display another project' => 'Başka bir proje göster', - 'Created by %s' => '%s tarafından oluşturuldu', - 'Tasks Export' => 'Görevleri dışa aktar', - 'Tasks exportation for "%s"' => '"%s" için görevleri dışa aktar', - 'Start Date' => 'Başlangıç tarihi', - 'End Date' => 'Bitiş tarihi', - 'Execute' => 'Gerçekleştir', - 'Task Id' => 'Görev Kimliği', - 'Creator' => 'Oluşturan', - 'Modification date' => 'Değişiklik tarihi', - 'Completion date' => 'Tamamlanma tarihi', - 'Clone' => 'Kopya oluştur', - 'Project cloned successfully.' => 'Proje kopyası başarıyla oluşturuldu.', - 'Unable to clone this project.' => 'Proje kopyası oluşturulamıyor.', - 'Enable email notifications' => 'E-posta bilgilendirmesini aç', - 'Task position:' => 'Görev pozisyonu', - 'The task #%d have been opened.' => '#%d numaralı görev açıldı.', - 'The task #%d have been closed.' => '#%d numaralı görev kapatıldı.', - 'Sub-task updated' => 'Alt görev güncellendi', - 'Title:' => 'Başlık', - 'Status:' => 'Durum', - 'Assignee:' => 'Sorumlu:', - 'Time tracking:' => 'Zaman takibi', - 'New sub-task' => 'Yeni alt görev', - 'New attachment added "%s"' => 'Yeni dosya "%s" eklendi.', - 'New comment posted by %s' => '%s tarafından yeni yorum eklendi', - 'New attachment' => 'Yeni dosya eki', - 'New comment' => 'Yeni yorum', - 'Comment updated' => 'Yorum güncellendi', - 'New subtask' => 'Yeni alt görev', - 'Subtask updated' => 'Alt görev güncellendi', - 'Task updated' => 'Görev güncellendi', - 'Task closed' => 'Görev kapatıldı', - 'Task opened' => 'Görev açıldı', - 'I want to receive notifications only for those projects:' => 'Yalnızca bu projelerle ilgili bildirim almak istiyorum:', - 'view the task on Kanboard' => 'bu görevi Kanboard üzerinde göster', - 'Public access' => 'Dışa açık erişim', - 'Active tasks' => 'Aktif görevler', - 'Disable public access' => 'Dışa açık erişimi kapat', - 'Enable public access' => 'Dışa açık erişimi aç', - 'Public access disabled' => 'Dışa açık erişim kapatıldı', - 'Do you really want to disable this project: "%s"?' => 'Bu projeyi devre dışı bırakmak istediğinize emin misiniz?: "%s"', - 'Do you really want to enable this project: "%s"?' => 'Bu projeyi aktive etmek istediğinize emin misiniz?: "%s"', - 'Project activation' => 'Proje aktivasyonu', - 'Move the task to another project' => 'Görevi başka projeye taşı', - 'Move to another project' => 'Başka projeye taşı', - 'Do you really want to duplicate this task?' => 'Bu görevin kopyasını oluşturmak istediğinize emin misiniz?', - 'Duplicate a task' => 'Görevin kopyasını oluştur', - 'External accounts' => 'Dış hesaplar', - 'Account type' => 'Hesap türü', - 'Local' => 'Yerel', - 'Remote' => 'Uzak', - 'Enabled' => 'Etkinleştirildi', - 'Disabled' => 'Devre dışı bırakıldı', - 'Username:' => 'Kullanıcı adı', - 'Name:' => 'Ad', - 'Email:' => 'E-posta', - 'Notifications:' => 'Bildirimler:', - 'Notifications' => 'Bildirimler', - 'Account type:' => 'Hesap türü:', - 'Edit profile' => 'Profili değiştir', - 'Change password' => 'Şifre değiştir', - 'Password modification' => 'Şifre değişimi', - 'External authentications' => 'Dış kimlik doğrulamaları', - 'Never connected.' => 'Hiç bağlanmamış.', - 'No external authentication enabled.' => 'Dış kimlik doğrulama kapalı.', - 'Password modified successfully.' => 'Şifre başarıyla değiştirildi.', - 'Unable to change the password.' => 'Şifre değiştirilemiyor.', - 'Change category' => 'Kategori değiştirme', - '%s updated the task %s' => '%s kullanıcısı %s görevini güncelledi', - '%s opened the task %s' => '%s kullanıcısı %s görevini açtı', - '%s moved the task %s to the position #%d in the column "%s"' => '%s kullanıcısı %s görevini #%d pozisyonu "%s" sütununa taşıdı', - '%s moved the task %s to the column "%s"' => '%s kullanıcısı %s görevini "%s" sütununa taşıdı', - '%s created the task %s' => '%s kullanıcısı %s görevini oluşturdu', - '%s closed the task %s' => '%s kullanıcısı %s görevini kapattı', - '%s created a subtask for the task %s' => '%s kullanıcısı %s görevi için bir alt görev oluşturdu', - '%s updated a subtask for the task %s' => '%s kullanıcısı %s görevinin bir alt görevini güncelledi', - 'Assigned to %s with an estimate of %s/%sh' => '%s kullanıcısına tahmini %s/%s saat tamamlanma süresi ile atanmış', - 'Not assigned, estimate of %sh' => 'Kimseye atanmamış, tahmini süre %s saat', - '%s updated a comment on the task %s' => '%s kullanıcısı %s görevinde bir yorumu güncelledi', - '%s commented the task %s' => '%s kullanıcısı %s görevine yorum ekledi', - '%s\'s activity' => '%s\'in aktivitesi', - 'RSS feed' => 'RSS kaynağı', - '%s updated a comment on the task #%d' => '%s kullanıcısı #%d nolu görevde bir yorumu güncelledi', - '%s commented on the task #%d' => '%s kullanıcısı #%d nolu göreve yorum ekledi', - '%s updated a subtask for the task #%d' => '%s kullanıcısı #%d nolu görevin bir alt görevini güncelledi', - '%s created a subtask for the task #%d' => '%s kullanıcısı #%d nolu göreve bir alt görev ekledi', - '%s updated the task #%d' => '%s kullanıcısı #%d nolu görevi güncelledi', - '%s created the task #%d' => '%s kullanıcısı #%d nolu görevi oluşturdu', - '%s closed the task #%d' => '%s kullanıcısı #%d nolu görevi kapattı', - '%s open the task #%d' => '%s kullanıcısı #%d nolu görevi açtı', - '%s moved the task #%d to the column "%s"' => '%s kullanıcısı #%d nolu görevi "%s" sütununa taşıdı', - '%s moved the task #%d to the position %d in the column "%s"' => '%s kullanıcısı #%d nolu görevi %d pozisyonu "%s" sütununa taşıdı', - 'Activity' => 'Aktivite', - 'Default values are "%s"' => 'Varsayılan değerler "%s"', - 'Default columns for new projects (Comma-separated)' => 'Yeni projeler için varsayılan sütunlar (virgül ile ayrılmış)', - 'Task assignee change' => 'Göreve atanan kullanıcı değişikliği', - '%s change the assignee of the task #%d to %s' => '%s kullanıcısı #%d nolu görevin sorumlusunu %s olarak değiştirdi', - '%s changed the assignee of the task %s to %s' => '%s kullanıcısı %s görevinin sorumlusunu %s olarak değiştirdi', - 'New password for the user "%s"' => '"%s" kullanıcısı için yeni şifre', - 'Choose an event' => 'Bir durum seçin', - 'Create a task from an external provider' => 'Dış sağlayıcı ile bir görev oluştur', - 'Change the assignee based on an external username' => 'Dış kaynaklı kullanıcı adı ile göreve atananı değiştir', - 'Change the category based on an external label' => 'Dış kaynaklı bir etiket ile kategori değiştir', - 'Reference' => 'Referans', - 'Label' => 'Etiket', - 'Database' => 'Veritabanı', - 'About' => 'Hakkında', - 'Database driver:' => 'Veritabanı sürücüsü:', - 'Board settings' => 'Tablo 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ığı', - 'Task highlight period' => 'Görevi öne çıkarma süresi', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => 'Bir görevin yeni değiştirilmiş sayılması için süre (saniye olarak) (Bu özelliği iptal etmek için 0, varsayılan değer 2 gün)', - 'Frequency in second (60 seconds by default)' => 'Saniye olarak frekans (varsayılan 60 saniye)', - 'Frequency in second (0 to disable this feature, 10 seconds by default)' => 'Saniye olarak frekans (Bu özelliği iptal etmek için 0, varsayılan değer 10 saniye)', - 'Application URL' => 'Uygulama URL', - 'Token regenerated.' => 'Beliteç yeniden oluşturuldu.', - 'Date format' => 'Tarih formatı', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO formatı her zaman kabul edilir, örneğin: "%s" ve "%s"', - 'New private project' => 'Yeni özel proje', - 'This project is private' => 'Bu proje özel', - 'Add' => 'Ekle', - 'Start date' => 'Başlangıç tarihi', - 'Time estimated' => 'Tahmini süre', - 'There is nothing assigned to you.' => 'Size atanan hiçbir şey yok.', - 'My tasks' => 'Görevlerim', - 'Activity stream' => 'Güncel olay akışı', - 'Dashboard' => 'Anasayfa', - 'Confirmation' => 'Onay', - 'Allow everybody to access to this project' => 'Bu projeye herkesin erişimine izin ver', - 'Everybody have access to this project.' => 'Bu projeye herkesin erişimi var.', - 'Webhooks' => 'Webhooks', - 'API' => 'API', - 'Create a comment from an external provider' => 'Dış sağlayıcı ile bir yorum oluştur', - 'Project management' => 'Proje yönetimi', - 'My projects' => 'Projelerim', - 'Columns' => 'Sütunlar', - 'Task' => 'Görev', - 'Your are not member of any project.' => 'Hiç bir projenin üyesi değilsiniz.', - 'Percentage' => 'Yüzde', - 'Number of tasks' => 'Görev sayısı', - 'Task distribution' => 'Görev dağılımı', - 'Reportings' => 'Raporlar', - 'Task repartition for "%s"' => '"%s" için görev dağılımı', - 'Analytics' => 'Analiz', - 'Subtask' => 'Alt görev', - 'My subtasks' => 'Alt görevlerim', - 'User repartition' => 'Kullanıcı dağılımı', - 'User repartition for "%s"' => '"%s" için kullanıcı dağılımı', - 'Clone this project' => 'Projenin kopyasını oluştur', - 'Column removed successfully.' => 'Sütun başarıyla kaldırıldı.', - 'Not enough data to show the graph.' => 'Grafik gösterimi için yeterli veri yok.', - 'Previous' => 'Önceki', - 'The id must be an integer' => 'ID bir tamsayı olmalı', - 'The project id must be an integer' => 'Proje numarası bir tam sayı olmalı', - 'The status must be an integer' => 'Durum bir tam sayı olmalı', - 'The subtask id is required' => 'Alt görev numarası gerekli', - 'The subtask id must be an integer' => 'Alt görev numarası bir tam sayı olmalı', - 'The task id is required' => 'Görev numarası gerekli', - 'The task id must be an integer' => 'Görev numarası bir tam sayı olmalı', - 'The user id must be an integer' => 'Kullanıcı numarası bir tam sayı olmalı', - 'This value is required' => 'Bu değer gerekli', - 'This value must be numeric' => 'Bu değer sayı olmalı', - 'Unable to create this task.' => 'Bu görev oluşturulamıyor.', - 'Cumulative flow diagram' => 'Kümülatif akış diyagramı', - 'Cumulative flow diagram for "%s"' => '"%s" için kümülatif akış diyagramı', - 'Daily project summary' => 'Günlük proje özeti', - 'Daily project summary export' => 'Günlük proje özetini dışa aktar', - 'Daily project summary export for "%s"' => '"%s" için günlük proje özetinin dışa', - 'Exports' => 'Dışa aktarımlar', - 'This export contains the number of tasks per column grouped per day.' => 'Bu dışa aktarım günlük gruplanmış olarak her sütundaki görev sayısını içerir.', - 'Active swimlanes' => 'Aktif Kulvar', - 'Add a new swimlane' => 'Yeni bir Kulvar ekle', - 'Change default swimlane' => 'Varsayılan Kulvarı değiştir', - 'Default swimlane' => 'Varsayılan Kulvar', - 'Do you really want to remove this swimlane: "%s"?' => 'Bu Kulvarı silmek istediğinize emin misiniz?: "%s"?', - 'Inactive swimlanes' => 'Pasif Kulvarlar', - 'Remove a swimlane' => 'Kulvarı sil', - 'Show default swimlane' => 'Varsayılan Kulvarı göster', - 'Swimlane modification for the project "%s"' => '"%s" Projesi için Kulvar değişikliği', - 'Swimlane removed successfully.' => 'Kulvar başarıyla kaldırıldı.', - 'Swimlanes' => 'Kulvarlar', - 'Swimlane updated successfully.' => 'Kulvar başarıyla güncellendi.', - 'The default swimlane have been updated successfully.' => 'Varsayılan Kulvarlar başarıyla güncellendi.', - 'Unable to remove this swimlane.' => 'Bu Kulvarı silmek mümkün değil.', - 'Unable to update this swimlane.' => 'Bu Kulvarı değiştirmek mümkün değil.', - 'Your swimlane have been created successfully.' => 'Kulvar başarıyla oluşturuldu.', - 'Example: "Bug, Feature Request, Improvement"' => 'Örnek: "Sorun, Özellik talebi, İyileştirme"', - 'Default categories for new projects (Comma-separated)' => 'Yeni projeler için varsayılan kategoriler (Virgül ile ayrılmış)', - 'Integrations' => 'Entegrasyon', - 'Integration with third-party services' => 'Dış servislerle entegrasyon', - 'Subtask Id' => 'Alt görev No:', - 'Subtasks' => 'Alt görevler', - 'Subtasks Export' => 'Alt görevleri dışa aktar', - 'Subtasks exportation for "%s"' => '"%s" için alt görevleri dışa aktarımı', - 'Task Title' => 'Görev Başlığı', - 'Untitled' => 'Başlıksız', - 'Application default' => 'Uygulama varsayılanları', - 'Language:' => 'Dil:', - 'Timezone:' => 'Saat dilimi:', - 'All columns' => 'Tüm sütunlar', - 'Calendar' => 'Takvim', - 'Next' => 'Sonraki', - '#%d' => '#%d', - 'All swimlanes' => 'Tüm Kulvarlar', - 'All colors' => 'Tüm Renkler', - 'Moved to column %s' => '%s Sütununa taşındı', - 'User dashboard' => 'Kullanıcı Anasayfası', - 'Allow only one subtask in progress at the same time for a user' => 'Bir kullanıcı için aynı anda yalnızca bir alt göreve izin ver', - 'Edit column "%s"' => '"%s" sütununu değiştir', - 'Select the new status of the subtask: "%s"' => '"%s" alt görevi için yeni durum seçin.', - 'Subtask timesheet' => 'Alt görev için zaman takip tablosu', - 'There is nothing to show.' => 'Gösterilecek hiçbir şey yok.', - 'Time Tracking' => 'Zaman takibi', - 'You already have one subtask in progress' => 'Zaten işlemde olan bir alt görev var', - 'Which parts of the project do you want to duplicate?' => 'Projenin hangi kısımlarının kopyasını oluşturmak istiyorsunuz?', - 'Disallow login form' => 'Giriş formu erişimini engelle', - 'Start' => 'Başlangıç', - 'End' => 'Son', - 'Task age in days' => 'Görev yaşı gün olarak', - 'Days in this column' => 'Bu sütunda geçirilen gün', - '%dd' => '%dG', - 'Add a new link' => 'Yeni link ekle', - 'Do you really want to remove this link: "%s"?' => '"%s" linkini gerçekten silmek istiyor musunuz?', - 'Do you really want to remove this link with task #%d?' => '#%d numaralı görev ile linki gerçekten silmek istiyor musunuz?', - 'Field required' => 'Bu alan gerekli', - 'Link added successfully.' => 'Link başarıyla eklendi.', - 'Link updated successfully.' => 'Link başarıyla güncellendi.', - 'Link removed successfully.' => 'Link başarıyla silindi.', - 'Link labels' => 'Link etiketleri', - 'Link modification' => 'Link değiştirme', - 'Links' => 'Links', - 'Link settings' => 'Link ayarları', - 'Opposite label' => 'Zıt etiket', - 'Remove a link' => 'Bir link silmek', - 'Task\'s links' => 'Görevin linkleri', - 'The labels must be different' => 'Etiketler farklı olmalı', - 'There is no link.' => 'Hiç bir bağ yok', - 'This label must be unique' => 'Bu etiket tek olmalı', - 'Unable to create your link.' => 'Link oluşturulamadı.', - 'Unable to update your link.' => 'Link güncellenemiyor.', - 'Unable to remove this link.' => 'Link kaldırılamıyor', - 'relates to' => 'şununla ilgili', - 'blocks' => 'şunu engelliyor', - 'is blocked by' => 'şunun tarafından engelleniyor', - 'duplicates' => 'şunun kopyasını oluşturuyor', - 'is duplicated by' => 'şunun tarafından kopyası oluşturuluyor', - 'is a child of' => 'şunun astı', - 'is a parent of' => 'şunun üstü', - 'targets milestone' => 'şu kilometre taşını hedefliyor', - 'is a milestone of' => 'şunun için bir kilometre taşı', - 'fixes' => 'düzeltiyor', - 'is fixed by' => 'şunun tarafından düzeltildi', - 'This task' => 'Bu görev', - '<1h' => '<1s', - '%dh' => '%ds', - 'Expand tasks' => 'Görevleri genişlet', - 'Collapse tasks' => 'Görevleri daralt', - 'Expand/collapse tasks' => 'Görevleri genişlet/daralt', - 'Close dialog box' => 'İletiyi kapat', - 'Submit a form' => 'Formu gönder', - 'Board view' => 'Tablo görünümü', - 'Keyboard shortcuts' => 'Klavye kısayolları', - 'Open board switcher' => 'Tablo seçim listesini aç', - 'Application' => 'Uygulama', - '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' => '', - 'download' => 'indir', - // 'EUR - Euro' => '', - // 'GBP - British Pound' => '', - // 'INR - Indian Rupee' => '', - // 'JPY - Japanese Yen' => '', - // 'NZD - New Zealand Dollar' => '', - // 'RSD - Serbian dinar' => '', - // 'USD - US Dollar' => '', - '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', - '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', - // 'Webhook URL' => '', - '%s remove 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ı', - 'Code' => 'Kod', - 'Two factor authentication' => 'İki 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', - 'Test your device' => 'Cihazınızı test edin', - 'Assign a color when the task is moved to a specific column' => 'Görev belirli bir sütuna taşındığında rengini değiştir', - '%s via Kanboard' => '%s Kanboard ile', - 'Burndown chart for "%s"' => '%s icin kalan iş grafiği', - 'Burndown chart' => 'Kalan iş grafiği', - 'This chart show the task complexity over the time (Work Remaining).' => 'Bu grafik zorluk seviyesini zamana göre gösterir (kalan iş)', - 'Screenshot taken %s' => 'Ekran görüntüsü alındı %s', - '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' => '', - '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"?', - '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', - 'The exact same link already exists' => 'Birebir aynı link zaten var', - 'Recurrent task is scheduled to be generated' => 'Tekrarlanan görev oluşturulması zamanlandı', - 'Score' => 'Skor', - 'The identifier must be unique' => 'Kimlik özgün olmalı', - 'This linked task id doesn\'t exists' => 'Link oluşturulan görec kodu mevcut değil', - 'This value must be alphanumeric' => 'Bu değer alfanumerik olmalı', - 'Edit recurrence' => 'Tekrarlanmayı düzenle', - 'Generate recurrent task' => 'Tekrarlanan görev oluştur', - 'Trigger to generate recurrent task' => 'Tekrarlanan görev oluşturmak için tetikleyici', - 'Factor to calculate new due date' => 'Yeni tamamlanma tarihi için hesaplama faktörü', - 'Timeframe to calculate new due date' => 'Yeni tamamlanma tarihinin hesaplanması için zaman dilimi', - 'Base date to calculate new due date' => 'Yeni tamamlanma tarihinin hesaplanması için baz alınacak tarih', - 'Action date' => 'Hareket tarihi', - 'Base date to calculate new due date: ' => 'Yeni tamamlanma tarihinin hesaplanması için baz alınacak tarih', - 'This task has created this child task: ' => 'Bu görev şu alt görevi oluşturdu:', - 'Day(s)' => 'Gün(ler)', - 'Existing due date' => 'Mevcut tamamlanma tarihi', - 'Factor to calculate new due date: ' => 'Yeni tamamlanma tarihi için hesaplama faktörü', - 'Month(s)' => 'Ay(lar)', - 'Recurrence' => 'Tekrar', - 'This task has been created by: ' => 'Bu görev şunun tarafından oluşturuldu:', - 'Recurrent task has been generated:' => 'Tekrarlanan görev oluşturuldu:', - 'Timeframe to calculate new due date: ' => 'Yeni tamamlanma tarihinin hesaplanması için zaman dilimi', - 'Trigger to generate recurrent task: ' => 'Tekrarlanan görev oluşturmak için tetikleyici', - 'When task is closed' => 'Görev kapatıldığı zaman', - 'When task is moved from first column' => 'Görev ilk sütundan taşındığı zaman', - 'When task is moved to last column' => 'Görev son sütuna taşındığı zaman', - 'Year(s)' => 'Yıl(lar)', - 'Calendar settings' => 'Takvim ayarları', - 'Project calendar view' => 'Proje takvim görünümü', - 'Project settings' => 'Proje ayarları', - 'Show subtasks based on the time tracking' => 'Zaman takibi bazında alt görevleri göster', - 'Show tasks based on the creation date' => 'Oluşturulma zamanına göre görevleri göster', - 'Show tasks based on the start date' => 'Başlangıç zamanına göre görevleri göster', - 'Subtasks time tracking' => 'Alt görevler zaman takibi', - 'User calendar view' => 'Kullanıcı takvim görünümü', - 'Automatically update the start date' => 'Başlangıç tarihini otomatik olarak güncelle', - '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', - '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ı', - 'Email subject' => 'Email başlığı', - 'Date' => 'Tarih', - 'Add a comment log when moving the task between columns' => 'Görevi sütunlar arasında taşırken yorum kaydı ekle', - 'Move the task to another column when the category is changed' => 'Kategori değiştirildiğinde görevi başka sütuna taşı', - 'Send a task by email to someone' => 'Bir görevi email ile birine gönder', - 'Reopen a task' => 'Bir görevi tekrar aç', - 'Column change' => 'Sütun değişikliği', - 'Position change' => 'Konum değişikliği', - 'Swimlane change' => 'Kulvar değişikliği', - 'Assignee change' => 'Atanan değişikliği', - '[%s] Overdue tasks' => '[%s] Gecikmiş görevler', - 'Notification' => 'Uyarılar', - '%s moved the task #%d to the first swimlane' => '%s, #%d görevini birinci kulvara taşıdı', - '%s moved the task #%d to the swimlane "%s"' => '%s, #%d görevini "%s" kulvarına taşıdı', - 'Swimlane' => 'Kulvar', - 'Gravatar' => 'Gravatar', - '%s moved the task %s to the first swimlane' => '%s, %s görevini ilk kulvara taşıdı', - '%s moved the task %s to the swimlane "%s"' => '%s, %s görevini "%s" kulvarına taşıdı', - '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', - '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', - 'The task is not assigned anymore' => 'Görev artık atanmamış', - 'New assignee: %s' => 'Yeni atanan: %s', - 'There is no category now' => 'Şu anda kategori yok', - 'New category: %s' => 'Yeni kategori: %s', - 'New color: %s' => 'Yeni renk: %s', - 'New complexity: %d' => 'Yeni zorluk seviyesi: %d', - '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 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', - 'Do you really want to close the task "%s" as well as all subtasks?' => '"%s" görevini ve tüm alt görevlerini kapatmak istediğinize emin misiniz?', - 'I want to receive notifications for:' => 'Bununla ilgili bildirimler almak istiyorum:', - 'All tasks' => 'Tüm görevler', - 'Only for tasks assigned to me' => 'Yalnızca bana atanmış görevler için', - 'Only for tasks created by me' => 'Yalnızca benim oluşturduğum görevler için', - 'Only for tasks created by me and assigned to me' => 'Yalnızca benim oluşturduğum ve bana atanmış görevler için', - '%%Y-%%m-%%d' => '%%Y-%%m-%%d', - 'Total for all columns' => 'Tüm sütunlar için toplam', - 'You need at least 2 days of data to show the chart.' => 'Grafiği göstermek için en az iki günlük veriye ihtiyaç var.', - '<15m' => '<15dk', - '<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', - 'Reset filters' => 'Filtreleri sıfırla', - 'My tasks due tomorrow' => 'Yarına tamamlanması gereken görevlerim', - 'Tasks due today' => 'Bugün tamamlanması gereken görevler', - 'Tasks due tomorrow' => 'Yarına tamamlanması gereken görevler', - 'Tasks due yesterday' => 'Dün tamamlanmış olması gereken görevler', - 'Closed tasks' => 'Kapatılmış görevler', - '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ç', - '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', - 'There is no activity yet.' => 'Henüz bir aktivite yok.', - 'No tasks found.' => 'Hiç görev bulunamadı.', - 'Keyboard shortcut: "%s"' => 'Klavye kısayolu: "%s"', - 'List' => 'Liste', - 'Filter' => 'Filtre', - 'Advanced search' => 'Gelişmiş arama', - 'Example of query: ' => 'Sorgu örneği', - 'Search by project: ' => 'Projeye göre ara', - 'Search by column: ' => 'Sütuna göre ara', - 'Search by assignee: ' => 'Atanana göre ara', - 'Search by color: ' => 'Renge göre ara', - 'Search by category: ' => 'Kategoriye göre ara', - 'Search by description: ' => 'Açıklamaya göre ara', - 'Search by due date: ' => 'Tamamlanma tarihine göre ara', - 'Lead and Cycle time for "%s"' => '"%s" için teslim ve çevrim süresi', - 'Average time spent into each column for "%s"' => '"%s" için her bir sütunda geçirilen ortalama zaman', - '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 Lead and Cycle time' => 'Ortalama teslim ve çevrim süresi', - 'Average lead time: ' => 'Ortalama teslim süresi', - 'Average cycle time: ' => 'Ortalama çevrim süresi', - 'Cycle Time' => 'Çevrim süresi', - 'Lead Time' => 'Teslim süresi', - 'This chart show the average lead and cycle time for the last %d tasks over the time.' => 'Bu grafik son %d görev için zaman içinde gerçekleşen ortalama teslim ve çevrim sürelerini gösterir.', - 'Average time into each column' => 'Her bir sütunda ortalama zaman', - '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', - '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.', - 'Set automatically the start date' => 'Başlangıç tarihini otomatik olarak belirle', - 'Edit Authentication' => 'Doğrulamayı düzenle', - '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.', - 'Trigger automatically subtask time tracking' => 'Altgörev zamanlayıcıyı otomatik olarak başlat', - 'Include closed tasks in the cumulative flow diagram' => 'Kümülatif akış diyagramında kapatılmış görevleri de dahil et', - 'Current swimlane: %s' => 'Geçerli kulvar: %s', - 'Current column: %s' => 'Geçerli sütun: %s', - 'Current category: %s' => 'Geçerli kategori: %s', - 'no category' => 'kategori yok', - 'Current assignee: %s' => 'Geçerli atanan: %s', - 'not assigned' => 'atanmamış', - 'Author:' => 'Yazar', - 'contributors' => 'Katkı sağlayanlar', - 'License:' => 'Lisans:', - 'License' => 'Lisans', - 'Enter the text below' => 'Aşağıdaki metni girin', - 'Gantt chart for %s' => '%s için Gantt diyagramı', - 'Sort by position' => 'Pozisyona göre sırala', - 'Sort by date' => 'Tarihe göre sırala', - 'Add task' => 'Görev ekle', - 'Start date:' => 'Başlangıç tarihi:', - 'Due date:' => 'Tamamlanması gereken tarih:', - 'There is no start date or due date for this task.' => 'Bu görev için başlangıç veya tamamlanması gereken tarih yok.', - '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 members' => 'Proje üyesi olan kişiler', - // 'NOK - Norwegian Krone' => '', - 'Show this column' => 'Bu sütunu göster', - 'Hide this column' => 'Bu sütunu gizle', - 'open file' => 'dosyayı aç', - 'End date' => 'Bitiş tarihi', - 'Users overview' => 'Kullanıcılara genel bakış', - 'Members' => 'Üyeler', - 'Shared project' => 'Paylaşılan proje', - 'Project managers' => 'Proje yöneticileri', - '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', - '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ı', - 'Change task color when using a specific task link' => 'Belirli bir görev bağlantısı kullanıldığında görevin rengini değiştir', - 'Task link creation or modification' => 'Görev bağlantısı oluşturulması veya değiştirilmesi', - 'Milestone' => 'Kilometre taşı', - 'Documentation: %s' => 'Dokümantasyon: %s', - 'Switch to the Gantt chart view' => 'Gantt diyagramı görünümüne geç', - 'Reset the search/filter box' => 'Arama/Filtre kutusunu sıfırla', - 'Documentation' => 'Dokümantasyon', - 'Table of contents' => 'İçindekiler', - 'Gantt' => 'Gantt', - 'Author' => 'Yazar', - 'Version' => 'Versiyon', - 'Plugins' => 'Eklentiler', - 'There is no plugin loaded.' => 'Yüklenmiş bir eklendi yok', - 'Set maximum column height' => 'Maksimum sütun yüksekliğini belirle', - 'Remove maximum column height' => 'Maksimum sütun yüksekliğini iptal et', - 'My notifications' => 'Bildirimlerim', - 'Custom filters' => 'Özel filtreler', - 'Your custom filter have been created successfully.' => 'Özel filtreleriniz başarıyla oluşturuldu.', - 'Unable to create your custom filter.' => 'Özel filtreniz oluşturulamadı.', - 'Custom filter removed successfully.' => 'Özel filtreniz başarıyla silindi.', - 'Unable to remove this custom filter.' => 'Bu özel filtre silinemiyor.', - 'Edit custom filter' => 'Özel filtreyi düzenle', - 'Your custom filter have been updated successfully.' => 'Özel filtreleriniz başarıyla güncellendi.', - 'Unable to update custom filter.' => 'Özel filtre güncellenemiyor.', - 'Web' => 'İnternet', - 'New attachment on task #%d: %s' => '#%d görevinde yeni dosya: %s', - 'New comment on task #%d' => '#%d görevinde yeni yorum', - 'Comment updated on task #%d' => '#%d görevinde yorum güncellendi', - 'New subtask on task #%d' => '#%d görevinde yeni alt görev', - 'Subtask updated on task #%d' => '#%d görevinde alt görev güncellendi', - 'New task #%d: %s' => 'Yeni #%d görevi: %s', - 'Task updated #%d' => '#%d görevi güncellendi', - 'Task #%d closed' => '#%d görevi kapatıldı', - 'Task #%d opened' => '#%d görevi oluşturuldu', - 'Column changed for task #%d' => '#%d görevinin sütunu değişti', - 'New position for task #%d' => '#%d görevinin konumu değişti', - 'Swimlane changed for task #%d' => '#%d görevinin kulvarı değişti', - 'Assignee changed on task #%d' => '#%d görevine atanan değişti', - '%d overdue tasks' => '%d gecikmiş görev', - 'Task #%d is overdue' => '#%d görevi gecikti', - 'No new notifications.' => 'Yeni bildirim yok.', - 'Mark all as read' => 'Tümünü okunmuş olarak işaretle', - 'Mark as read' => 'Okunmuş olarak işaretle', - 'Total number of tasks in this column across all swimlanes' => 'Bu sutündaki görev sayısının tüm kulvarlardaki toplamı', - 'Collapse swimlane' => 'Kulvarı daralt', - 'Expand swimlane' => 'Kulvarı genişlet', - 'Add a new filter' => 'Yeni bir filtre ekle', - 'Share with all project members' => 'Tüm proje üyeleriyle paylaş', - 'Shared' => 'Paylaşılan', - '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ı!', - 'Import users from CSV file' => 'CSV dosyasından kullanıcıları içeri aktar', - '%d user(s) have been imported successfully.' => '%d kullanıcı başarıyla içeri aktarıldı.', - 'Comma' => 'Virgül', - 'Semi-colon' => 'Noktalı virgül', - 'Tab' => 'Tab', - 'Vertical bar' => 'Dikey çizgi', - 'Double Quote' => 'Tırnak işareti', - 'Single Quote' => 'Kesme işareti', - '%s attached a file to the task #%d' => '%s, #%d görevine bir dosya ekledi.', - 'There is no column or swimlane activated in your project!' => 'Projenizde etkinleştirilmiş hiç bir sütun veya kulvar yok!', - 'Append filter (instead of replacement)' => 'Fıltreye ekle (üzerine yazmak yerine)', - 'Append/Replace' => 'Ekle/Üzerine yaz', - 'Append' => 'Ekle', - 'Replace' => 'Üzerine yaz', - 'Import' => 'İçeri aktar', - 'change sorting' => 'sıralamayı değiştir', - 'Tasks Importation' => 'Görevleri içeri aktar', - 'Delimiter' => 'Ayırıcı', - 'Enclosure' => 'Enclosure', - 'CSV File' => 'CSV Dosyası', - 'Instructions' => 'Yönergeler', - 'Your file must use the predefined CSV format' => 'Dosyanız önceden belirlenmiş CSV formatını kullanmalı', - 'Your file must be encoded in UTF-8' => 'Dosyanız UTF-8 kodlamasında olmalı', - 'The first row must be the header' => 'İlk satır başlık olmalı', - 'Duplicates are not verified for you' => 'Çift girişler sizin için onaylanmamış', - 'The due date must use the ISO format: YYYY-MM-DD' => 'Tamamlanma tarihi ISO formatını kullanmalı: YYYY-MM-DD', - 'Download CSV template' => 'CSV taslağını indir', - 'No external integration registered.' => 'Hiç dış entegrasyon kaydedilmemiş.', - 'Duplicates are not imported' => 'Çift girişler içeri aktarılmaz', - 'Usernames must be lowercase and unique' => 'Kullanıcı adları küçük harf ve tekil olmalı', - 'Passwords will be encrypted if present' => 'Şifreler (eğer varsa) kriptolanır', - '%s attached a new file to the task %s' => '%s, %s görevine yeni dosya ekledi', - 'Link type' => 'Bağlantı türü', - 'Assign automatically a category based on a link' => 'Bir bağlantıya göre otomatik olarak kategori ata', - 'BAM - Konvertible Mark' => 'BAM - Konvertible Mark', - 'Assignee Username' => 'Atanan kullanıcı adı', - 'Assignee Name' => 'Atanan İsmi', - 'Groups' => 'Gruplar', - 'Members of %s' => '%s in üyeleri', - 'New group' => 'Yeni grup', - 'Group created successfully.' => 'Grup başarıyla oluşturuldu.', - 'Unable to create your group.' => 'Grup oluşturulamadı.', - 'Edit group' => 'Grubu düzenle', - 'Group updated successfully.' => 'Grup başarıyla güncellendi.', - 'Unable to update your group.' => 'Grup güncellenemedi.', - 'Add group member to "%s"' => '"%s" e grup üyesi ekle', - 'Group member added successfully.' => 'Grup üyesi başarıyla eklendi.', - 'Unable to add group member.' => 'Grup üyesi eklenemedi.', - 'Remove user from group "%s"' => '"%s" grubundan kullanıcı çıkar', - 'User removed successfully from this group.' => 'Kullanıcı bu gruptan başarıyla çıkarıldı.', - 'Unable to remove this user from the group.' => 'Bu kullanıcı bu grubtan çıkarılamadı', - 'Remove group' => 'Grubu sil', - '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', - 'Project Member' => 'Proje üyesi', - 'Project Viewer' => 'Proje izleyicisi', - 'Your account is locked for %d minutes' => 'Hesabınız %d dakika boyunca kilitlendi', - 'Invalid captcha' => 'Geçersiz captcha', - 'The name must be unique' => 'İsim tekil olmalı', - 'View all groups' => 'Tüm grupları görüntüle', - 'View group members' => 'Grup üyelerini görüntüle', - 'There is no user available.' => 'Uygun üye yok', - 'Do you really want to remove the user "%s" from the group "%s"?' => '"%s" kullanıcısını "%s" grubundan çıkarmak istediğinize emin misiniz?', - 'There is no group.' => 'Hiç grup yok.', - 'External Id' => 'Harici Kimlik', - 'Add group member' => 'Grup üyesi ekle', - 'Do you really want to remove this group: "%s"?' => '"%s" grubunu silmek istediğinize emin misiniz?', - 'There is no user in this group.' => 'Bu grupta hiç kullanıcı yok.', - 'Remove this user' => 'Bu kullanıcıyı sil', - 'Permissions' => 'İzinler', - 'Allowed Users' => 'İzin verilen kullanıcı', - 'No user have been allowed specifically.' => 'Hiç bir kullanıcıya özel olarak izin verilmemiş.', - 'Role' => 'Rol', - 'Enter user name...' => 'Kullanıcı adını girin...', - 'Allowed Groups' => 'İzinli gruplar', - 'No group have been allowed specifically.' => 'Hiç bir gruba özel olarak izin verilmemiş', - 'Group' => 'Grup', - 'Group Name' => 'Grup adı', - 'Enter group name...' => 'Grup adını girin...', - 'Role:' => 'Rol:', - 'Project members' => 'Proje üyeleri', - 'Compare hours for "%s"' => '"%s" için saatleri karşılaştır', - '%s mentioned you in the task #%d' => '%s sizden #%d görevinde bahsetti', - '%s mentioned you in a comment on the task #%d' => '%s sizden #%d görevindeki bir yorumda bahsetti', - 'You were mentioned in the task #%d' => '#%d görevinde sizden bahsedildi', - 'You were mentioned in a comment on the task #%d' => '#%d görevindeki bir yorumda sizden bahsedildi', - 'Mentioned' => 'Bahsedilmiş', - 'Compare Estimated Time vs Actual Time' => 'Tahmini süre ile gerçekleşen süreyi karşılaştır', - 'Estimated hours: ' => 'Tahmini saat:', - 'Actual hours: ' => 'Gerçekleşen saat:', - 'Hours Spent' => 'Harcanan saat', - 'Hours Estimated' => 'Tahmini saat', - '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' => '', - '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', - '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?', - 'Enable "Forget Password"' => '"Şifremi unuttum" komutunu etkinleştir', - 'Password Reset' => 'Şifre sıfırlama', - 'New password' => 'Yeni şifre', - 'Change Password' => 'Şifreyi değiştir', - 'To reset your password click on this link:' => 'Şifrenizi sıfırlamak için bu linke tıklayın:', - 'Last Password Reset' => 'Son şifre sıfırlama', - 'The password has never been reinitialized.' => 'Şifre hiç bir zaman tekrar başlatılmamış.', - 'Creation' => 'Oluşturulma', - 'Expiration' => 'Sona erme', - 'Password reset history' => 'Şifre sıfırlama geçmişi', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '"%s" sütunu ve "%s" kulvarındaki tüm görevler başarıyla kapatıldı.', - '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' => '', - // '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' => '', -); diff --git a/sources/app/Locale/zh_CN/translations.php b/sources/app/Locale/zh_CN/translations.php deleted file mode 100644 index 2f456cc..0000000 --- a/sources/app/Locale/zh_CN/translations.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php - -return array( - 'number.decimals_separator' => '.', - 'number.thousands_separator' => ',', - 'None' => '无', - 'edit' => '编辑', - 'Edit' => '编辑', - 'remove' => '移除', - 'Remove' => '移除', - 'Yes' => '是', - 'No' => '否', - 'cancel' => '取消', - 'or' => '或者', - 'Yellow' => '黄色', - 'Blue' => '蓝色', - 'Green' => '绿色', - 'Purple' => '紫色', - 'Red' => '红色', - 'Orange' => '橘色', - 'Grey' => '灰色', - 'Brown' => '褐色', - 'Deep Orange' => '橘红色', - 'Dark Grey' => '深灰色', - 'Pink' => '粉红色', - 'Teal' => '青色', - 'Cyan' => '蓝绿色', - 'Lime' => '绿黄色', - 'Light Green' => '浅绿色', - 'Amber' => '黄褐色', - 'Save' => '保存', - 'Login' => '登录', - 'Official website:' => '官方网站:', - 'Unassigned' => '未指定', - 'View this task' => '查看该任务', - 'Remove user' => '移除用户', - 'Do you really want to remove this user: "%s"?' => '确定要删除用户"%s"吗?', - 'All users' => '所有用户', - 'Username' => '用户名', - 'Password' => '密码', - 'Administrator' => '超级管理员', - 'Sign in' => '登录', - 'Users' => '用户', - 'No user' => '没有用户', - 'Forbidden' => '禁止', - 'Access Forbidden' => '禁止进入', - 'Edit user' => '修改用户', - 'Logout' => '退出', - 'Bad username or password' => '用户名或密码错误', - 'Edit project' => '修改项目', - 'Name' => '名称', - 'Projects' => '项目', - 'No project' => '无项目', - 'Project' => '项目', - 'Status' => '状态', - 'Tasks' => '任务', - 'Board' => '看板', - 'Actions' => '动作', - 'Inactive' => '未激活', - 'Active' => '激活', - '%d tasks on the board' => '看板目前有%d个任务', - '%d tasks in total' => '总共有%d个任务', - 'Unable to update this board.' => '无法更新该看板。', - 'Edit board' => '修改看板', - 'Disable' => '停用', - 'Enable' => '启用', - 'New project' => '新建项目', - 'Do you really want to remove this project: "%s"?' => '确定要移除项目"%s"吗?', - 'Remove project' => '移除项目', - 'Edit the board for "%s"' => '为"%s"修改看板', - 'All projects' => '所有项目', - 'Add a new column' => '添加新栏目', - 'Title' => '标题', - 'Assigned to %s' => '指派给 %s', - 'Remove a column' => '移除一个栏目', - 'Remove a column from a board' => '从看板移除一个栏目', - 'Unable to remove this column.' => '无法移除该栏目。', - 'Do you really want to remove this column: "%s"?' => '确定要移除栏目"%s"吗?', - 'This action will REMOVE ALL TASKS associated to this column!' => '该动作将移除与该栏目相关的所有项目!', - 'Settings' => '设置', - 'Application settings' => '应用设置', - 'Language' => '语言', - 'Webhook token:' => '页面钩子令牌:', - 'API token:' => 'API 令牌:', - 'Database size:' => '数据库大小:', - 'Download the database' => '下载数据库', - 'Optimize the database' => '优化数据库', - '(VACUUM command)' => '(VACUUM 指令)', - '(Gzip compressed Sqlite file)' => '(用Gzip压缩的Sqlite文件)', - 'Close a task' => '关闭一个任务', - 'Edit a task' => '修改一个任务', - 'Column' => '栏目', - 'Color' => '颜色', - 'Assignee' => '负责人', - 'Create another task' => '创建另一个任务', - 'New task' => '新进任务', - 'Open a task' => '开一个任务', - 'Do you really want to open this task: "%s"?' => '你确定要开这个任务吗?"%s"', - 'Back to the board' => '回到看板', - 'There is nobody assigned' => '当前无人被指派', - 'Column on the board:' => '看板上的栏目:', - 'Close this task' => '关闭该任务', - 'Open this task' => '开启该任务', - 'There is no description.' => '当前没有描述。', - 'Add a new task' => '添加新任务', - 'The username is required' => '需要用户名', - 'The maximum length is %d characters' => '最长%d个英文字符', - 'The minimum length is %d characters' => '最短%d个英文自负', - 'The password is required' => '需要密码', - 'This value must be an integer' => '该值必须为整数', - 'The username must be unique' => '用户名必须唯一', - 'The user id is required' => '用户id是必须的', - 'Passwords don\'t match' => '密码不匹配', - 'The confirmation is required' => '需要确认', - 'The project is required' => '需要指定项目', - 'The id is required' => '需要指定id', - 'The project id is required' => '需要指定项目id', - 'The project name is required' => '需要指定项目名称', - 'The title is required' => '需要指定标题', - 'Settings saved successfully.' => '设置成功保存。', - 'Unable to save your settings.' => '无法保存你的设置。', - 'Database optimization done.' => '数据库优化完成。', - 'Your project have been created successfully.' => '您的项目已经成功创建。', - 'Unable to create your project.' => '无法为您创建项目。', - 'Project updated successfully.' => '成功更新项目。', - 'Unable to update this project.' => '无法更新该项目。', - 'Unable to remove this project.' => '无法移除该项目。', - 'Project removed successfully.' => '成功移除项目。', - 'Project activated successfully.' => '项目成功激活。', - 'Unable to activate this project.' => '无法激活该项目。', - 'Project disabled successfully.' => '成功停用项目。', - 'Unable to disable this project.' => '无法停用该项目。', - 'Unable to open this task.' => '无法开启该任务。', - 'Task opened successfully.' => '任务开启成功。', - 'Unable to close this task.' => '无法关闭该任务。', - 'Task closed successfully.' => '成功关闭任务。', - 'Unable to update your task.' => '无法更新您的任务。', - 'Task updated successfully.' => '成功更新任务。', - 'Unable to create your task.' => '无法为您创建任务。', - 'Task created successfully.' => '成功创建任务。', - 'User created successfully.' => '成功创建用户。', - 'Unable to create your user.' => '无法创建用户。', - 'User updated successfully.' => '成功更新用户。', - 'Unable to update your user.' => '无法为您更新用户。', - 'User removed successfully.' => '成功移除用户。', - 'Unable to remove this user.' => '无法移除该用户。', - 'Board updated successfully.' => '看板成功更新。', - 'Ready' => '预备', - 'Backlog' => '积压', - 'Work in progress' => '工作进行中', - 'Done' => '完成', - 'Application version:' => '应用程序版本:', - 'Id' => '编号', - '%d closed tasks' => '%d个已关闭任务', - 'No task for this project' => '该项目尚无任务', - 'Public link' => '公开链接', - 'Timezone' => '时区', - 'Sorry, I didn\'t find this information in my database!' => '抱歉,无法在数据库中找到该信息!', - 'Page not found' => '页面未找到', - 'Complexity' => '复杂度', - 'Task limit' => '任务限制', - 'Task count' => '任务数', - 'User' => '用户', - 'Comments' => '评论', - 'Leave a comment' => '留言', - 'Comment is required' => '必须得有评论', - 'Leave a description' => '给一个描述', - 'Comment added successfully.' => '评论成功添加。', - 'Unable to create your comment.' => '无法创建评论。', - 'Due Date' => '到期时间', - 'Invalid date' => '无效日期', - 'Automatic actions' => '自动动作', - 'Your automatic action have been created successfully.' => '您的自动动作已成功创建', - 'Unable to create your automatic action.' => '无法为您创建自动动作。', - 'Remove an action' => '移除一个动作。', - 'Unable to remove this action.' => '无法移除该动作', - 'Action removed successfully.' => '成功移除动作。', - 'Automatic actions for the project "%s"' => '项目"%s"的自动动作', - 'Add an action' => '添加动作', - 'Event name' => '事件名称', - 'Action name' => '动作名称', - 'Action parameters' => '动作参数', - 'Action' => '动作', - 'Event' => '事件', - 'When the selected event occurs execute the corresponding action.' => '当所选事件发生时执行相应动作。', - 'Next step' => '下一步', - 'Define action parameters' => '定义动作参数', - 'Do you really want to remove this action: "%s"?' => '确定要移除动作"%s"吗?', - 'Remove an automatic action' => '移除一个自动动作', - 'Assign the task to a specific user' => '将该任务指派给一个用户', - 'Assign the task to the person who does the action' => '将任务指派给产生该动作的用户', - 'Duplicate the task to another project' => '复制该任务到另一项目', - 'Move a task to another column' => '移动任务到另一栏目', - 'Task modification' => '任务修改', - 'Task creation' => '任务创建', - 'Closing a task' => '正在关闭任务', - 'Assign a color to a specific user' => '为特定用户指派颜色', - 'Column title' => '栏目名称', - 'Position' => '位置', - 'Duplicate to another project' => '复制到另一项目', - 'Duplicate' => '复制', - 'link' => '连接', - 'Comment updated successfully.' => '评论成功更新。', - 'Unable to update your comment.' => '无法更新您的评论。', - 'Remove a comment' => '移除评论', - 'Comment removed successfully.' => '评论成功移除。', - 'Unable to remove this comment.' => '无法移除该评论。', - 'Do you really want to remove this comment?' => '确定要移除评论吗?', - 'Current password for the user "%s"' => '用户"%s"的当前密码', - 'The current password is required' => '需要输入当前密码', - 'Wrong password' => '密码错误', - 'Unknown' => '未知', - 'Last logins' => '上次登录', - 'Login date' => '登录日期', - 'Authentication method' => '认证方式', - 'IP address' => 'IP地址', - 'User agent' => '浏览器标识', - 'Persistent connections' => '持续连接', - 'No session.' => '无会话', - 'Expiration date' => '过期日期', - 'Remember Me' => '记住我', - 'Creation date' => '创建日期', - 'Everybody' => '所有人', - 'Open' => '打开', - 'Closed' => '关闭', - 'Search' => '查找', - 'Nothing found.' => '没找到。', - 'Due date' => '到期时间', - 'Others formats accepted: %s and %s' => '可以使用的其它格式:%s 和 %s', - 'Description' => '描述', - '%d comments' => '%d个评论', - '%d comment' => '%d个评论', - 'Email address invalid' => '电子邮件地址无效', - 'Your external account is not linked anymore to your profile.' => '你的外部账户关联已解除', - 'Unable to unlink your external account.' => '无法关联到你的外部账户', - 'External authentication failed' => '外部认证失败', - 'Your external account is linked to your profile successfully.' => '你已成功关联到你的外部账户', - 'Email' => '电子邮件', - 'Task removed successfully.' => '任务成功去除', - 'Unable to remove this task.' => '无法移除该任务。', - 'Remove a task' => '移除一个任务', - 'Do you really want to remove this task: "%s"?' => '确定要移除任务"%s"吗?', - 'Assign automatically a color based on a category' => '基于一个分类自动指派颜色', - 'Assign automatically a category based on a color' => '基于一种颜色自动指派分类', - 'Task creation or modification' => '任务创建或修改', - 'Category' => '分类', - 'Category:' => '分类:', - 'Categories' => '分类', - 'Your category have been created successfully.' => '成功为您创建分类。', - 'Unable to create your category.' => '无法为您创建分类。', - 'Your category have been updated successfully.' => '成功为您更新分类。', - 'Unable to update your category.' => '无法为您更新分类。', - 'Remove a category' => '移除一个分类', - 'Category removed successfully.' => '分类成功移除。', - 'Unable to remove this category.' => '无法移除该分类。', - 'Category modification for the project "%s"' => '为项目"%s"修改分类', - 'Category Name' => '分类名称', - 'Add a new category' => '加入新分类', - 'Do you really want to remove this category: "%s"?' => '确定要移除分类"%s"吗?', - 'All categories' => '所有分类', - 'No category' => '无分类', - 'The name is required' => '必须要有名字', - 'Remove a file' => '移除一个文件', - 'Unable to remove this file.' => '无法移除该文件。', - 'File removed successfully.' => '文件成功移除。', - 'Attach a document' => '附加文档', - 'Do you really want to remove this file: "%s"?' => '确定要移除文件"%s"吗?', - 'Attachments' => '附件', - 'Edit the task' => '修改任务', - 'Add a comment' => '添加评论', - 'Edit a comment' => '编辑评论', - 'Summary' => '概要', - 'Time tracking' => '时间记录', - 'Estimate:' => '评估:', - 'Spent:' => '花费:', - 'Do you really want to remove this sub-task?' => '请确认是否要删除此子任务?', - 'Remaining:' => '剩余:', - 'hours' => '小时', - 'spent' => '花费', - 'estimated' => '评估', - 'Sub-Tasks' => '子任务', - 'Add a sub-task' => '添加子任务', - 'Original estimate' => '初步预估', - 'Create another sub-task' => '创建另一个子任务', - 'Time spent' => '时间花费', - 'Edit a sub-task' => '编辑子任务', - 'Remove a sub-task' => '删除子任务', - 'The time must be a numeric value' => '时间必须为数字', - 'Todo' => '待完成', - 'In progress' => '正在进行', - 'Sub-task removed successfully.' => '成功删除子任务', - 'Unable to remove this sub-task.' => '无法删除此任务', - 'Sub-task updated successfully.' => '成功创建子任务', - 'Unable to update your sub-task.' => '无法更新子任务', - 'Unable to create your sub-task.' => '无法创建子任务', - 'Sub-task added successfully.' => '成功添加子任务', - 'Maximum size: ' => '大小上限:', - 'Unable to upload the file.' => '无法上传文件', - 'Display another project' => '显示其它项目', - 'Created by %s' => '创建者:%s', - 'Tasks Export' => '任务导出', - 'Tasks exportation for "%s"' => '导出"%s"的任务', - 'Start Date' => '开始时间', - 'End Date' => '结束时间', - 'Execute' => '执行', - 'Task Id' => '任务ID', - 'Creator' => '创建者', - 'Modification date' => '修改日期', - 'Completion date' => '完成日期', - 'Clone' => '克隆', - 'Project cloned successfully.' => '成功复制项目。', - 'Unable to clone this project.' => '无法复制此项目', - 'Enable email notifications' => '启用邮件通知', - 'Task position:' => '任务位置:', - 'The task #%d have been opened.' => '任务#%d已经被开启.', - 'The task #%d have been closed.' => '任务#%d已经被关闭.', - 'Sub-task updated' => '子任务更新', - 'Title:' => '标题:', - 'Status:' => '状态:', - 'Assignee:' => '负责人', - 'Time tracking:' => '时间记录', - 'New sub-task' => '新建子任务', - 'New attachment added "%s"' => '新附件已添加"%s"', - 'New comment posted by %s' => '%s 的新评论', - 'New attachment' => '新建附件', - 'New comment' => '新建评论', - 'Comment updated' => '更新了评论', - 'New subtask' => '新建子任务', - 'Subtask updated' => '子任务更新', - 'Task updated' => '任务更新', - 'Task closed' => '任务关闭', - 'Task opened' => '任务开启', - 'I want to receive notifications only for those projects:' => '我仅需要收到下面项目的通知:', - 'view the task on Kanboard' => '在看板中查看此任务', - 'Public access' => '公开访问', - 'Active tasks' => '活动任务', - 'Disable public access' => '停止公开访问', - 'Enable public access' => '开启公开访问', - 'Public access disabled' => '已经禁止公开访问', - 'Do you really want to disable this project: "%s"?' => '确认要禁用项目"%s"吗?', - 'Do you really want to enable this project: "%s"?' => '确认要启用项目"%s"吗?', - 'Project activation' => '项目启动', - 'Move the task to another project' => '移动任务到其它项目', - 'Move to another project' => '移动到其它项目', - 'Do you really want to duplicate this task?' => '确定要复制此任务吗?', - 'Duplicate a task' => '复制任务', - 'External accounts' => '外部账户', - 'Account type' => '账户类型', - 'Local' => '本地', - 'Remote' => '远程', - 'Enabled' => '启用', - 'Disabled' => '停用', - 'Username:' => '用户名:', - 'Name:' => '姓名:', - 'Email:' => '电子邮件:', - 'Notifications:' => '通知:', - 'Notifications' => '通知', - 'Account type:' => '账户类型:', - 'Edit profile' => '编辑属性', - 'Change password' => '修改密码', - 'Password modification' => '修改密码', - 'External authentications' => '外部认证', - 'Never connected.' => '从未连接。', - 'No external authentication enabled.' => '未启用外部认证。', - 'Password modified successfully.' => '已经成功修改密码。', - 'Unable to change the password.' => '无法修改密码。', - 'Change category' => '变更分类', - '%s updated the task %s' => '%s 更新了任务 %s', - '%s opened the task %s' => '%s 开启了任务 %s', - '%s moved the task %s to the position #%d in the column "%s"' => '%s 将任务 %s 移动到了"%s"的第#%d个位置', - '%s moved the task %s to the column "%s"' => '%s 移动任务 %s 到栏目 "%s"', - '%s created the task %s' => '%s 创建了任务 %s', - '%s closed the task %s' => '%s 关闭了任务 %s', - '%s created a subtask for the task %s' => '%s 创建了 %s的子任务', - '%s updated a subtask for the task %s' => '%s 更新了 %s的子任务', - 'Assigned to %s with an estimate of %s/%sh' => '分配给 %s,预估需要 %s/%s 小时', - 'Not assigned, estimate of %sh' => '未分配,预估需要 %s 小时', - '%s updated a comment on the task %s' => '%s 更新了任务 %s的评论', - '%s commented the task %s' => '%s 评论了任务 %s', - '%s\'s activity' => '%s的动态', - 'RSS feed' => 'RSS 链接', - '%s updated a comment on the task #%d' => '%s 更新了任务 #%d 的评论', - '%s commented on the task #%d' => '%s 评论了任务 #%d', - '%s updated a subtask for the task #%d' => '%s 更新了任务 #%d 的子任务', - '%s created a subtask for the task #%d' => '%s 创建了任务 #%d 的子任务', - '%s updated the task #%d' => '%s 更新了任务 #%d', - '%s created the task #%d' => '%s 创建了任务 #%d', - '%s closed the task #%d' => '%s 关闭了任务 #%d', - '%s open the task #%d' => '%s 开启了任务 #%d', - '%s moved the task #%d to the column "%s"' => '%s 将任务 #%d 移动到栏目 "%s"', - '%s moved the task #%d to the position %d in the column "%s"' => '%s将任务#%d移动到"%s"的第 %d 列', - 'Activity' => '动态', - 'Default values are "%s"' => '默认值为 "%s"', - 'Default columns for new projects (Comma-separated)' => '新建项目的默认栏目(用逗号分开)', - 'Task assignee change' => '任务分配变更', - '%s change the assignee of the task #%d to %s' => '%s 将任务 #%d 分配给了 %s', - '%s changed the assignee of the task %s to %s' => '%s 将任务 %s 分配给 %s', - 'New password for the user "%s"' => '用户"%s"的新密码', - 'Choose an event' => '选择一个事件', - 'Create a task from an external provider' => '从外部创建任务', - 'Change the assignee based on an external username' => '根据外部用户名修改任务分配', - 'Change the category based on an external label' => '根据外部标签修改分类', - 'Reference' => '参考', - 'Label' => '标签', - 'Database' => '数据库', - 'About' => '关于', - 'Database driver:' => '数据库驱动:', - 'Board settings' => '看板设置', - 'Webhook settings' => 'Webhook 设置', - 'Reset token' => '重置令牌', - 'API endpoint:' => 'API 端点:', - 'Refresh interval for private board' => '私人看板的刷新时间', - 'Refresh interval for public board' => '公共看板的刷新时间', - 'Task highlight period' => '任务高亮时间', - 'Period (in second) to consider a task was modified recently (0 to disable, 2 days by default)' => '多久内的任务视作刚刚修改(单位:秒,设置为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' => '日期格式', - 'ISO format is always accepted, example: "%s" and "%s"' => 'ISO 格式总是允许的,例如:"%s" 和 "%s"', - 'New private project' => '新建私有项目', - 'This project is private' => '此项目为私有项目', - 'Add' => '添加', - 'Start date' => '启动日期', - 'Time estimated' => '预计时间', - 'There is nothing assigned to you.' => '当前无任务指派给你。', - 'My tasks' => '我的任务', - 'Activity stream' => '动态记录', - 'Dashboard' => '面板', - 'Confirmation' => '确认', - 'Allow everybody to access to this project' => '允许所有人访问此项目', - 'Everybody have access to this project.' => '所有人都可以访问此项目', - 'Webhooks' => '网络钩子', - 'API' => '应用程序接口', - 'Create a comment from an external provider' => '从外部创建一个评论', - 'Project management' => '项目管理', - 'My projects' => '我的项目', - 'Columns' => '栏目', - 'Task' => '任务', - 'Your are not member of any project.' => '您尚未加入任何项目', - 'Percentage' => '百分比', - 'Number of tasks' => '任务数', - 'Task distribution' => '任务分布', - 'Reportings' => '报告', - 'Task repartition for "%s"' => '"%s"的任务分析', - 'Analytics' => '分析', - 'Subtask' => '子任务', - 'My subtasks' => '我的子任务', - 'User repartition' => '用户分析', - 'User repartition for "%s"' => '"%s"的用户分析', - 'Clone this project' => '复制此项目', - 'Column removed successfully.' => '成功删除了栏目。', - 'Not enough data to show the graph.' => '数据不足,无法绘图。', - 'Previous' => '后退', - 'The id must be an integer' => '编号必须为整数', - 'The project id must be an integer' => '项目编号必须为整数', - 'The status must be an integer' => '状态必须为整数', - 'The subtask id is required' => '必须提供子任务编号', - 'The subtask id must be an integer' => '子任务编号必须为整数', - 'The task id is required' => '需要任务编号', - 'The task id must be an integer' => '任务编号必须为整数', - 'The user id must be an integer' => '用户编号必须为整数', - 'This value is required' => '必须给出这个值', - 'This value must be numeric' => '这个值必须为数字', - 'Unable to create this task.' => '无法创建此任务。', - 'Cumulative flow diagram' => '累积流图表', - 'Cumulative flow diagram for "%s"' => '"%s"的累积流图表', - 'Daily project summary' => '每日项目汇总', - 'Daily project summary export' => '导出每日项目汇总', - 'Daily project summary export for "%s"' => '导出项目"%s"的每日汇总', - 'Exports' => '导出', - 'This export contains the number of tasks per column grouped per day.' => '此导出包含每列的任务数,按天分组', - 'Active swimlanes' => '活动里程碑', - 'Add a new swimlane' => '添加新里程碑', - 'Change default swimlane' => '修改默认里程碑', - 'Default swimlane' => '默认里程碑', - 'Do you really want to remove this swimlane: "%s"?' => '确定要删除里程碑:"%s"?', - 'Inactive swimlanes' => '非活动里程碑', - 'Remove a swimlane' => '删除里程碑', - 'Show default swimlane' => '显示默认里程碑', - 'Swimlane modification for the project "%s"' => '项目"%s"的里程碑变更', - 'Swimlane removed successfully.' => '成功删除里程碑', - 'Swimlanes' => '里程碑', - 'Swimlane updated successfully.' => '成功更新了里程碑。', - 'The default swimlane have been updated successfully.' => '成功更新了默认里程碑。', - 'Unable to remove this swimlane.' => '无法删除此里程碑', - 'Unable to update this swimlane.' => '无法更新此里程碑', - 'Your swimlane have been created successfully.' => '已经成功创建里程碑。', - 'Example: "Bug, Feature Request, Improvement"' => '示例:“缺陷,功能需求,提升', - 'Default categories for new projects (Comma-separated)' => '新项目的默认分类(用逗号分隔)', - 'Integrations' => '整合', - 'Integration with third-party services' => '与第三方服务进行整合', - 'Subtask Id' => '子任务 Id', - 'Subtasks' => '子任务', - 'Subtasks Export' => '子任务导出', - 'Subtasks exportation for "%s"' => '导出"%s"的子任务', - 'Task Title' => '任务标题', - 'Untitled' => '无标题', - 'Application default' => '程序默认', - 'Language:' => '语言:', - 'Timezone:' => '时区:', - 'All columns' => '全部栏目', - 'Calendar' => '日程表', - 'Next' => '前进', - '#%d' => '#%d', - 'All swimlanes' => '全部里程碑', - 'All colors' => '全部颜色', - 'Moved to column %s' => '移动到栏目 %s', - '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"', - 'Subtask timesheet' => '子任务时间', - 'There is nothing to show.' => '当前无内容可展示。', - 'Time Tracking' => '时间记录', - 'You already have one subtask in progress' => '你已经有了一个进行中的子任务', - 'Which parts of the project do you want to duplicate?' => '要复制项目的哪些内容?', - 'Disallow login form' => '禁止登陆', - 'Start' => '开始', - 'End' => '结束', - 'Task age in days' => '任务存在天数', - 'Days in this column' => '在此栏目的天数', - '%dd' => '%d天', - 'Add a new link' => '添加一个新关联', - 'Do you really want to remove this link: "%s"?' => '确认要删除此关联吗:"%s"?', - 'Do you really want to remove this link with task #%d?' => '确认要删除到任务 #%d 的关联吗?', - 'Field required' => '必须的字段', - 'Link added successfully.' => '成功添加关联。', - 'Link updated successfully.' => '成功更新关联。', - 'Link removed successfully.' => '成功删除关联。', - 'Link labels' => '关联标签', - 'Link modification' => '关联修改', - 'Links' => '关联', - 'Link settings' => '关联设置', - 'Opposite label' => '反向标签', - 'Remove a link' => '删除关联', - 'Task\'s links' => '任务的关联', - 'The labels must be different' => '标签不能一样', - 'There is no link.' => '当前没有关联', - 'This label must be unique' => '关联必须唯一', - 'Unable to create your link.' => '无法创建关联。', - 'Unable to update your link.' => '无法更新关联。', - 'Unable to remove this link.' => '无法删除关联。', - 'relates to' => '关联到', - 'blocks' => '阻塞', - 'is blocked by' => '阻塞于', - 'duplicates' => '重复', - 'is duplicated by' => '重复于', - 'is a child of' => '子任务自', - 'is a parent of' => '父任务于', - 'targets milestone' => '里程碑目标', - 'is a milestone of' => '属于里程碑', - 'fixes' => '修复', - 'is fixed by' => '修复于', - 'This task' => '此任务', - '<1h' => '<1h', - '%dh' => '%dh', - 'Expand tasks' => '展开任务', - 'Collapse tasks' => '收缩任务', - 'Expand/collapse tasks' => '展开/收缩任务', - 'Close dialog box' => '关闭对话框', - 'Submit a form' => '提交表单', - 'Board view' => '面板视图', - 'Keyboard shortcuts' => '键盘快捷方式', - 'Open board switcher' => '打开面板切换器', - 'Application' => '应用程序', - 'Compact view' => '紧凑视图', - 'Horizontal scrolling' => '水平滚动', - 'Compact/wide view' => '紧凑/宽视图', - 'No results match:' => '无匹配结果:', - 'Currency' => '货币', - 'Private project' => '私人项目', - 'AUD - Australian Dollar' => '澳元', - 'CAD - Canadian Dollar' => '加元', - 'CHF - Swiss Francs' => '瑞士法郎', - 'Custom Stylesheet' => '自定义样式表', - 'download' => '下载', - 'EUR - Euro' => '欧元', - 'GBP - British Pound' => '英镑', - 'INR - Indian Rupee' => '印度卢比', - 'JPY - Japanese Yen' => '日元', - 'NZD - New Zealand Dollar' => '新西兰元', - 'RSD - Serbian dinar' => '第纳尔', - 'USD - US Dollar' => '美元', - 'Destination column' => '目标栏目', - 'Move the task to another column when assigned to a user' => '指定负责人时移动到其它栏目', - 'Move the task to another column when assignee is cleared' => '移除负责人时移动到其它栏目', - 'Source column' => '原栏目', - 'Transitions' => '变更', - 'Executer' => '执行者', - 'Time spent in the column' => '栏目中的时间消耗', - 'Task transitions' => '任务变更', - 'Task transitions export' => '导出任务变更', - 'This report contains all column moves for each task with the date, the user and the time spent for each transition.' => '此报告记录任务的变更,包含日期、用户和时间消耗。', - 'Currency rates' => '汇率', - 'Rate' => '汇率', - 'Change reference currency' => '修改参考货币', - 'Add a new currency rate' => '添加新汇率', - 'Reference currency' => '参考货币', - 'The currency rate have been added successfully.' => '成功添加汇率。', - 'Unable to add this currency rate.' => '无法添加此汇率', - 'Webhook URL' => '网络钩子 URL', - '%s remove the assignee of the task %s' => '%s删除了任务%s的负责人', - 'Enable Gravatar images' => '启用 Gravatar 图像', - 'Information' => '信息', - 'Check two factor authentication code' => '检查双重认证码', - 'The two factor authentication code is not valid.' => '双重认证码不正确。', - 'The two factor authentication code is valid.' => '双重认证码正确。', - 'Code' => '认证码', - 'Two factor authentication' => '双重认证', - 'This QR code contains the key URI: ' => '此二维码包含密码 URI:', - 'Check my code' => '检查我的认证码', - 'Secret key: ' => '密码:', - 'Test your device' => '测试设备', - 'Assign a color when the task is moved to a specific column' => '任务移动到指定栏目时设置颜色', - '%s via Kanboard' => '%s 通过KanBoard', - 'Burndown chart for "%s"' => '燃尽图:"%s"', - 'Burndown chart' => '燃尽图', - 'This chart show the task complexity over the time (Work Remaining).' => '图表显示任务随时间(剩余时间)的复杂度', - 'Screenshot taken %s' => '已截图 %s', - 'Add a screenshot' => '添加截图', - 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '获取截图并按CTRL+V或者⌘+V粘贴到这里', - 'Screenshot uploaded successfully.' => '截图上传成功', - 'SEK - Swedish Krona' => '瑞郎', - 'Identifier' => '标识符', - 'Disable two factor authentication' => '禁用双重认证', - 'Do you really want to disable the two factor authentication for this user: "%s"?' => '你真的要禁用 "%s" 的双重认证吗?', - 'Edit link' => '编辑链接', - 'Start to type task title...' => '输入任务标题...', - 'A task cannot be linked to itself' => '任务不能关联到本身', - 'The exact same link already exists' => '相同的关联已存在', - 'Recurrent task is scheduled to be generated' => '循环性任务将按计划生成', - 'Score' => '积分', - 'The identifier must be unique' => '标识符必须唯一', - 'This linked task id doesn\'t exists' => '关联任务不存在', - 'This value must be alphanumeric' => '此值必须是字母或者数字', - 'Edit recurrence' => '编辑循环周期', - 'Generate recurrent task' => '生成循环任务', - 'Trigger to generate recurrent task' => '生成循环任务的触发器', - 'Factor to calculate new due date' => '超期因素', - 'Timeframe to calculate new due date' => '计算超期时间表', - 'Base date to calculate new due date' => '计算超期基准日期', - 'Action date' => '操作日期', - 'Base date to calculate new due date: ' => '基准日期', - 'This task has created this child task: ' => '此任务创建了子任务:', - 'Day(s)' => '天', - 'Existing due date' => '已超期', - 'Factor to calculate new due date: ' => '超期因素', - 'Month(s)' => '月', - 'Recurrence' => '循环', - 'This task has been created by: ' => '此任务被谁创建:', - 'Recurrent task has been generated:' => '循环任务已生成:', - 'Timeframe to calculate new due date: ' => '计算超期时间表', - 'Trigger to generate recurrent task: ' => '生成循环任务的触发器', - 'When task is closed' => '当任务关闭时', - 'When task is moved from first column' => '当任务从第一列任务栏移走时', - 'When task is moved to last column' => '当任务移动到最后一列任务栏时', - 'Year(s)' => '年', - 'Calendar settings' => '日程设置', - 'Project calendar view' => '项目日历表', - 'Project settings' => '项目设置', - 'Show subtasks based on the time tracking' => '在时间跟踪上显示子任务', - 'Show tasks based on the creation date' => '显示任务创建日期于', - 'Show tasks based on the start date' => '显示任务开始日期于', - 'Subtasks time tracking' => '子任务时间跟踪', - 'User calendar view' => '用户日程视图', - 'Automatically update the start date' => '自动更新开始日期', - 'iCal feed' => '日历订阅', - 'Preferences' => '偏好', - 'Security' => '安全', - 'Two factor authentication disabled' => '双重认证已禁用', - 'Two factor authentication enabled' => '双重认证已启用', - 'Unable to update this user.' => '无法更新此用户', - 'There is no user management for private projects.' => '私有项目下无用户可管理', - 'User that will receive the email' => '用户将收到邮件', - 'Email subject' => '邮件主题', - 'Date' => '日期', - 'Add a comment log when moving the task between columns' => '当任务移动到任务栏时添加评论日志', - 'Move the task to another column when the category is changed' => '当任务分类改变时移动到任务栏', - 'Send a task by email to someone' => '发送任务邮件到用户', - 'Reopen a task' => '重新开始一个任务', - 'Column change' => '任务栏改变', - 'Position change' => '位置改变', - 'Swimlane change' => '里程碑改变', - 'Assignee change' => '指派人改变', - '[%s] Overdue tasks' => '[%s] 超期任务', - 'Notification' => '通知', - '%s moved the task #%d to the first swimlane' => '%s将任务#%d移动到了首个里程碑', - '%s moved the task #%d to the swimlane "%s"' => '%s将任务#%d移动到了里程碑"%s"下', - 'Swimlane' => '里程碑', - '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.' => '该报告包含了指定日期范围内的所有子任务信息。', - 'This report contains all tasks information for the given date range.' => '该报告包含了指定日期范围内的所有任务信息。', - 'Project activities for %s' => '%s的项目活动记录', - 'view the board on Kanboard' => '在看板上查看面板', - 'The task have been moved to the first swimlane' => '该任务已被移动到首个里程碑', - 'The task have been moved to another swimlane:' => '该任务已被移动到别的里程碑:', - 'New title: %s' => '新标题:%s', - 'The task is not assigned anymore' => '该任务没有指派人', - 'New assignee: %s' => '新指派到:%s', - 'There is no category now' => '当前没有分类', - 'New category: %s' => '新分类:%s', - 'New color: %s' => '新颜色:%s', - 'New complexity: %d' => '新的复杂度:%d', - 'The due date have been removed' => '超期时间已被移除', - 'There is no description anymore' => '当前没有描述', - 'Recurrence settings have been modified' => '循环周期已被更改', - 'Time spent changed: %sh' => '时间花费已变更:%sh', - 'Time estimated changed: %sh' => '时间预估已变更:%sh', - 'The field "%s" have been updated' => '"%s"字段已更新', - 'The description has been modified:' => '描述已更改', - 'Do you really want to close the task "%s" as well as all subtasks?' => '你是否要移除所有子任务的同时父任务"%s"', - 'I want to receive notifications for:' => '我想接收以下相关通知:', - 'All tasks' => '所有任务', - 'Only for tasks assigned to me' => '所有指派给我的任务', - 'Only for tasks created by me' => '所有我创建的任务', - 'Only for tasks created by me and assigned to me' => '所有我创建的并且指派给我的任务', - // '%%Y-%%m-%%d' => '', - 'Total for all columns' => '所有栏目下的', - 'You need at least 2 days of data to show the chart.' => '当前柱状图至少需要2天的数据。', - '<15m' => '小于15分钟', - '<30m' => '小于30分钟', - 'Stop timer' => '停止计时器', - 'Start timer' => '开启计时器', - 'Add project member' => '添加项目成员', - 'My activity stream' => '我的活动流', - 'My calendar' => '我的日程表', - 'Search tasks' => '搜索任务', - 'Reset filters' => '重置过滤器', - 'My tasks due tomorrow' => '我的明天到期的任务', - 'Tasks due today' => '今天到期的任务', - 'Tasks due tomorrow' => '明天到期的任务', - 'Tasks due yesterday' => '昨天到期的任务', - 'Closed tasks' => '已关闭任务', - 'Open tasks' => '打开的任务', - 'Not assigned' => '未指派', - 'View advanced search syntax' => '查看高级搜索语法', - 'Overview' => '概览', - 'Board/Calendar/List view' => '看板/日程/列表视图', - 'Switch to the board view' => '切换到看板视图', - 'Switch to the calendar view' => '切换到日程视图', - 'Switch to the list view' => '切换到列表视图', - 'Go to the search/filter box' => '前往搜索/过滤箱', - 'There is no activity yet.' => '当前无任何活动.', - 'No tasks found.' => '没有找人任何任务.', - 'Keyboard shortcut: "%s"' => '快捷键: "%s"', - 'List' => '列表', - 'Filter' => '过滤器', - 'Advanced search' => '高级搜索', - 'Example of query: ' => '查询示例: ', - 'Search by project: ' => '按项目: ', - 'Search by column: ' => '按任务栏: ', - 'Search by assignee: ' => '按被指派人: ', - 'Search by color: ' => '按颜色: ', - 'Search by category: ' => '按分类:', - 'Search by description: ' => '按描述:', - 'Search by due date: ' => '按超期时间:', - // 'Lead and Cycle time for "%s"' => '', - 'Average time spent into each column for "%s"' => '"%s"在每个任务栏下平均花费时间', - 'Average time spent into each column' => '每个任务栏平均花费时间', - 'Average time spent' => '平均花费时间', - 'This chart show the average time spent into each column for the last %d tasks.' => '当前柱状图表示最新%d条任务在每个任务栏下的平均花费时间', - // 'Average Lead and Cycle time' => '', - // 'Average lead time: ' => '', - // 'Average cycle time: ' => '', - // 'Cycle Time' => '', - // 'Lead Time' => '', - // 'This chart show the average lead and cycle time for the last %d tasks over the time.' => '', - // 'Average time into each column' => '', - // 'Lead and cycle time' => '', - // 'Lead time: ' => '', - // 'Cycle time: ' => '', - // 'Time spent into each column' => '', - // 'The lead time is the duration between the task creation and the completion.' => '', - // 'The cycle time is the duration between the start date and the completion.' => '', - // 'If the task is not closed the current time is used instead of the completion date.' => '', - // 'Set automatically the start date' => '', - 'Edit Authentication' => '编辑认证信息', - 'Remote user' => '远程用户', - 'Remote users do not store their password in Kanboard database, examples: LDAP, Google and Github accounts.' => '远程用户不会在看板数据库保存密码,例如: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.' => '当前没有目标项目可用', - 'Trigger automatically subtask time tracking' => '自动跟踪子任务时间', - 'Include closed tasks in the cumulative flow diagram' => '在累计流程图中包含已关闭任务', - 'Current swimlane: %s' => '当前里程碑:%s', - 'Current column: %s' => '当前任务栏:%s', - 'Current category: %s' => '当前分类:%s', - 'no category' => '无分类', - 'Current assignee: %s' => '当前被指派人: %s', - 'not assigned' => '未指派', - 'Author:' => '作者', - 'contributors' => '贡献者', - 'License:' => '授权许可:', - 'License' => '授权许可', - 'Enter the text below' => '输入下方的文本', - 'Gantt chart for %s' => '%s的甘特图', - 'Sort by position' => '按位置排序', - 'Sort by date' => '按日期排序', - 'Add task' => '添加任务', - 'Start date:' => '开始日期', - 'Due date:' => '到期日期', - 'There is no start date or due date for this task.' => '当前任务没有开始或结束时间。', - 'Moving or resizing a task will change the start and due date of the task.' => '移动或者重设任务将改变任务开始和结束时间。', - 'There is no task in your project.' => '当前项目还没有任务', - 'Gantt chart' => '甘特图', - 'People who are project managers' => '项目管理员', - 'People who are project members' => '项目成员', - 'NOK - Norwegian Krone' => '克朗', - 'Show this column' => '显示任务栏', - 'Hide this column' => '隐藏任务栏', - 'open file' => '打开文件', - 'End date' => '结束日期', - 'Users overview' => '用户概览', - 'Members' => '成员', - 'Shared project' => '公开项目', - 'Project managers' => '项目管理员', - 'Gantt chart for all projects' => '所有项目的甘特图', - 'Projects list' => '项目列表', - 'Gantt chart for this project' => '此项目的甘特图', - 'Project board' => '项目面板', - 'End date:' => '结束日期', - 'There is no start date or end date for this project.' => '当前项目没有开始或结束日期', - 'Projects Gantt chart' => '项目甘特图', - 'Change task color when using a specific task link' => '当任务关联到指定任务时改变颜色', - 'Task link creation or modification' => '任务链接创建或更新时间', - 'Milestone' => '里程碑', - 'Documentation: %s' => '文档:%s', - 'Switch to the Gantt chart view' => '切换到甘特图', - 'Reset the search/filter box' => '重置搜索/过滤框', - 'Documentation' => '文档', - 'Table of contents' => '表内容', - 'Gantt' => '甘特图', - 'Author' => '作者', - 'Version' => '版本', - 'Plugins' => '插件', - 'There is no plugin loaded.' => '当前没有插件载入', - 'Set maximum column height' => '设置任务栏最大高度', - 'Remove maximum column height' => '移除任务栏最大高度', - 'My notifications' => '我的通知', - 'Custom filters' => '自定义过滤器', - 'Your custom filter have been created successfully.' => '成功创建过滤器', - 'Unable to create your custom filter.' => '无法创建过滤器', - 'Custom filter removed successfully.' => '成功删除过滤器', - 'Unable to remove this custom filter.' => '无法删除这个过滤器', - 'Edit custom filter' => '编辑过滤器', - 'Your custom filter have been updated successfully.' => '你的过滤器更新成功', - 'Unable to update custom filter.' => '无法更新过滤器', - 'Web' => 'web', - 'New attachment on task #%d: %s' => '任务#%d下的新附件:%s', - 'New comment on task #%d' => '任务#%d下的新评论', - 'Comment updated on task #%d' => '任务#%d的评论已更新', - 'New subtask on task #%d' => '任务#%d下新的子任务', - 'Subtask updated on task #%d' => '任务#%d下的子任务已更新', - 'New task #%d: %s' => '新任务#%d:%s', - 'Task updated #%d' => '任务#%d已更新', - 'Task #%d closed' => '任务#%d已关闭', - 'Task #%d opened' => '任务#%d已打开', - 'Column changed for task #%d' => '任务#%d的任务栏已改变', - 'New position for task #%d' => '任务#%d的新状态', - 'Swimlane changed for task #%d' => '任务#%d的里程碑已改变', - 'Assignee changed on task #%d' => '任务#%d的指派人已改变', - '%d overdue tasks' => '%d条超期任务', - 'Task #%d is overdue' => '任务#%d已超期', - 'No new notifications.' => '没有新通知', - 'Mark all as read' => '标记所有为已读', - 'Mark as read' => '标记为已读', - 'Total number of tasks in this column across all swimlanes' => '此任务栏下的任务数(跨里程碑)', - 'Collapse swimlane' => '收起里程碑', - 'Expand swimlane' => '展开里程碑', - 'Add a new filter' => '添加新过滤器', - 'Share with all project members' => '对项目所有成员共享', - 'Shared' => '共享', - 'Owner' => '所有人', - 'Unread notifications' => '未读通知', - 'Notification methods:' => '通知提醒方式:', - 'Import tasks from CSV file' => '从CSV文件导入任务', - 'Unable to read your file' => '无法读取文件', - '%d task(s) have been imported successfully.' => '成功导入%d条任务。', - 'Nothing have been imported!' => '没有信息被导入!', - 'Import users from CSV file' => '从CSV文件导入用户', - '%d user(s) have been imported successfully.' => '成功导入%d个用户。', - 'Comma' => '逗号', - 'Semi-colon' => '分号', - 'Tab' => '制表符', - 'Vertical bar' => '竖线', - 'Double Quote' => '双引号', - 'Single Quote' => '单引号', - '%s attached a file to the task #%d' => '%s添加文件到任务#%d', - 'There is no column or swimlane activated in your project!' => '当前项目没有活动任务栏或里程碑', - 'Append filter (instead of replacement)' => '追加过滤', - 'Append/Replace' => '追加/替换', - 'Append' => '追加', - 'Replace' => '替换', - 'Import' => '导入', - 'change sorting' => '改变排序', - 'Tasks Importation' => '任务重要性', - 'Delimiter' => '分隔符', - 'Enclosure' => '附件', - 'CSV File' => 'CSV文件', - 'Instructions' => '操作指南', - 'Your file must use the predefined CSV format' => '文件必须为预定格式的CSV文件', - 'Your file must be encoded in UTF-8' => '文件编码必须为UTF-8', - 'The first row must be the header' => '第一行必须为表头', - 'Duplicates are not verified for you' => '无法验证重复信息', - 'The due date must use the ISO format: YYYY-MM-DD' => '超期日期必须为ISO格式:YYYY-MM-DD', - 'Download CSV template' => '下载CSV模板', - 'No external integration registered.' => '没有外部注册信息', - 'Duplicates are not imported' => '重复信息未导入', - 'Usernames must be lowercase and unique' => '用户名必须小写且唯一', - 'Passwords will be encrypted if present' => '密码将被加密', - '%s attached a new file to the task %s' => '"%s"添加了附件到任务"%s"', - 'Link type' => '关联类型', - 'Assign automatically a category based on a link' => '基于链接自动关联分类', - 'BAM - Konvertible Mark' => '波斯尼亚马克', - 'Assignee Username' => '指派用户名', - 'Assignee Name' => '指派名称', - 'Groups' => '用户组', - 'Members of %s' => '“%s”组成员', - 'New group' => '新加用户组', - 'Group created successfully.' => '用户组创建成功', - 'Unable to create your group.' => '无法创建你的用户组', - 'Edit group' => '编辑用户组', - 'Group updated successfully.' => '用户组更新成功', - 'Unable to update your group.' => '无法更新你的用户组', - 'Add group member to "%s"' => '添加到用户组"%s"', - 'Group member added successfully.' => '成功添加用户组成员', - 'Unable to add group member.' => '无法添加用户组成员', - 'Remove user from group "%s"' => '从"%s"组中移除用户', - 'User removed successfully from this group.' => '用户已从该用户组中删除', - 'Unable to remove this user from the group.' => '无法从该用户组中删除用户', - 'Remove group' => '删除用户组', - 'Group removed successfully.' => '用户组已删除', - 'Unable to remove this group.' => '无法删除该用户组', - 'Project Permissions' => '项目权限', - 'Manager' => '管理员', - 'Project Manager' => '项目管理员', - 'Project Member' => '项目成员', - 'Project Viewer' => '项目观察员', - 'Your account is locked for %d minutes' => '你的账户被锁定%d分钟', - 'Invalid captcha' => '验证码无效', - 'The name must be unique' => '请确保用户名唯一', - 'View all groups' => '查看所有用户组', - 'View group members' => '查看该组所有用户', - 'There is no user available.' => '当前没有有效用户', - 'Do you really want to remove the user "%s" from the group "%s"?' => '你确定把用户"%s"从"%s"中移除?', - 'There is no group.' => '当前没有用户组', - 'External Id' => '关联ID', - 'Add group member' => '添加用户组成员', - 'Do you really want to remove this group: "%s"?' => '你真的想要移除用户组:"%s"?', - 'There is no user in this group.' => '当前用户组下没有成员', - 'Remove this user' => '移除用户', - 'Permissions' => '权限', - 'Allowed Users' => '被允许的用户', - 'No user have been allowed specifically.' => '没有被允许的用户。', - 'Role' => '角色', - 'Enter user name...' => '输入用户名...', - 'Allowed Groups' => '被允许的用户组', - 'No group have been allowed specifically.' => '没有被允许的用户组。', - 'Group' => '用户组', - 'Group Name' => '用户组名称', - 'Enter group name...' => '输入用户组名称...', - 'Role:' => '角色:', - 'Project members' => '项目成员', - 'Compare hours for "%s"' => '比较"%s"的时间', - '%s mentioned you in the task #%d' => '%s在任务#%d里提及你', - '%s mentioned you in a comment on the task #%d' => '%s在任务#%d的评论里提及你', - 'You were mentioned in the task #%d' => '你在任务#%d里被提及', - 'You were mentioned in a comment on the task #%d' => '你在任务#%d的评论里被提及', - 'Mentioned' => '被提及', - 'Compare Estimated Time vs Actual Time' => '对比预估时间VS实际时间', - 'Estimated hours: ' => '预估小时数', - 'Actual hours: ' => '实际小时数', - 'Hours Spent' => '花费小时数', - 'Hours Estimated' => '预估小时数', - 'Estimated Time' => '预估时间', - 'Actual Time' => '实际时间', - 'Estimated vs actual time' => '预估时间 VS 实际时间', - 'RUB - Russian Ruble' => '卢布', - 'Assign the task to the person who does the action when the column is changed' => '当任务所属任务栏改变时分配到指定用户', - 'Close a task in a specific column' => '关闭指定任务栏下的任务', - 'Time-based One-time Password Algorithm' => '基于时间的一次性密码算法', - 'Two-Factor Provider: ' => '双重认证提供商', - 'Disable two-factor authentication' => '禁用双重认证', - 'Enable two-factor authentication' => '启用双重认证', - 'There is no integration registered at the moment.' => '当前没有注册关联', - 'Password Reset for Kanboard' => '重置kanboard密码', - 'Forgot password?' => '忘记密码?', - 'Enable "Forget Password"' => '启用找回密码', - 'Password Reset' => '密码重置', - 'New password' => '新密码', - 'Change Password' => '更改密码', - 'To reset your password click on this link:' => '点击此链接重置你的密码', - 'Last Password Reset' => '上次密码重置', - 'The password has never been reinitialized.' => '密码从未被重新初始化', - 'Creation' => '创建时间', - 'Expiration' => '过期时间', - 'Password reset history' => '密码重置历史', - 'All tasks of the column "%s" and the swimlane "%s" have been closed successfully.' => '任务栏 "%s" 和 里程碑 "%s" 下的所有任务已关闭', - 'Do you really want to close all tasks of this column?' => '你确定要关闭此任务栏下的所有任务?', - '%d task(s) in the column "%s" and the swimlane "%s" will be closed.' => '任务栏 "%s" 和 里程碑 "%s" 下 %d 条任务将被关闭。', - 'Close all tasks of this column' => '关闭此任务栏下的所有任务', - 'No plugin has registered a project notification method. You can still configure individual notifications in your user profile.' => '没有插件注册到项目通知接口,你仍然可以在你个人设置里启用单独的通知', - 'My dashboard' => '我的控制台', - 'My profile' => '我的个人信息', - 'Project owner: ' => '项目负责人', - 'The project identifier is optional and must be alphanumeric, example: MYPROJECT.' => '项目标识符是可选的,且只能是数字或字母组成,例如:MYPROJECT。', - 'Project owner' => '项目负责人', - 'Those dates are useful for the project Gantt chart.' => '那些时间对于项目甘特图非常有用', - 'Private projects do not have users and groups management.' => '私有项目下没有成员或组可管理', - 'There is no project member.' => '当前没有项目成员', - 'Priority' => '优先级', - 'Task priority' => '任务优先级', - 'General' => '常用', - 'Dates' => '时间', - 'Default priority' => '默认优先级', - 'Lowest priority' => '最低优先级', - 'Highest priority' => '最高优先级', - 'If you put zero to the low and high priority, this feature will be disabled.' => '如果你为优先级填0,将禁用本功能', - 'Close a task when there is no activity' => '当任务没有活动记录时关闭任务', - 'Duration in days' => '持续天数', - 'Send email when there is no activity on a task' => '当任务没有活动记录时发送邮件', - 'Unable to fetch link information.' => '无法获取关联信息', - 'Daily background job for tasks' => '每日后台任务', - 'Auto' => '自动', - 'Related' => '相关的', - 'Attachment' => '附件', - 'Title not found' => '标题未找到', - 'Web Link' => '网页链接', - 'External links' => '外部关联', - 'Add external link' => '添加外部关联', - 'Type' => '类型', - 'Dependency' => '依赖', - 'Add internal link' => '添加内部关联', - 'Add a new external link' => '添加新的外部关联', - 'Edit external link' => '编辑外部关联', - 'External link' => '外部关联', - 'Copy and paste your link here...' => '复制并粘贴链接到当前位置...', - 'URL' => 'URL', - 'Internal links' => '内部关联', - 'Assign to me' => '指派给我', - 'Me' => '我', - 'Do not duplicate anything' => '不再重复', - 'Projects management' => '项目管理', - 'Users management' => '用户管理', - 'Groups management' => '用户组管理', - 'Create from another project' => '从另一个项目中创建', - 'open' => '打开', - 'closed' => '已关闭', - 'Priority:' => '优先级:', - 'Reference:' => '引用:', - 'Complexity:' => '复杂度:', - 'Swimlane:' => '里程碑:', - 'Column:' => '列:', - 'Position:' => '位置:', - 'Creator:' => '创建者:', - 'Time estimated:' => '时间已过去:', - '%s hours' => '%s 小时', - 'Time spent:' => '时间消耗:', - 'Created:' => '已创建:', - 'Modified:' => '已修改:', - 'Completed:' => '已完成:', - 'Started:' => '已开始:', - 'Moved:' => '已移走', - 'Task #%d' => '任务#%d', - 'Date and time format' => '时间和日期格式', - 'Time format' => '时间格式', - 'Start date: ' => '开始时间:', - 'End date: ' => '结束时间:', - 'New due date: ' => '新超期时间:', - 'Start date changed: ' => '开始时间已改变:', - 'Disable private projects' => '禁用私有项目', - 'Do you really want to remove this custom filter: "%s"?' => '你确定要移除这个自定义过滤器:"%s"?', - 'Remove a custom filter' => '移除自定义过滤器', - 'User activated successfully.' => '用户已激活。', - 'Unable to enable this user.' => '无法启用该用户。', - 'User disabled successfully.' => '用户已禁用。', - 'Unable to disable this user.' => '无法禁用该用户。', - 'All files have been uploaded successfully.' => '所有文件已成功上传。', - 'View uploaded files' => '查看已上传文件', - 'The maximum allowed file size is %sB.' => '最大上传尺寸 %sB', - 'Choose files again' => '重新选择文件', - 'Drag and drop your files here' => '拖放文件到这里', - 'choose files' => '选择文件', - 'View profile' => '查看个人信息', - 'Two Factor' => '双重认证', - 'Disable user' => '禁用用户', - 'Do you really want to disable this user: "%s"?' => '你确定要禁用该用户:"%s"?', - 'Enable user' => '启用用户', - 'Do you really want to enable this user: "%s"?' => '你确定要启用该用户:"%s"?', - 'Download' => '下载', - 'Uploaded: %s' => '上传:%s', - 'Size: %s' => '大小:%s', - 'Uploaded by %s' => '由%s上传', - 'Filename' => '文件名', - 'Size' => '大小', - 'Column created successfully.' => '新增任务栏成功。', - 'Another column with the same name exists in the project' => '当前项目中重名任务栏已存在', - 'Default filters' => '默认过滤器', - 'Your board doesn\'t have any 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' => '当前输入值必须大于%d', - 'Another swimlane with the same name exists in the project' => '当前项目中重名里程碑已存在', - 'Example: http://example.kanboard.net/ (used to generate absolute URLs)' => '例如: http://example.kanboard.net/(通常用于生成绝对地址)', - 'Actions duplicated successfully.' => '动作复制成功。', - 'Unable to duplicate actions.' => '无法复制动作。', - 'Add a new action' => '添加新动作', - 'Import from another project' => '从另一个项目中导入', - 'There is no action at the moment.' => '当前没有动作。', - 'Import actions from another project' => '从另一个项目中导入动作', - 'There is no available project.' => '当前没有可用项目', - // 'Local File' => '', - // 'Configuration' => '', - // 'PHP version:' => '', - // 'PHP SAPI:' => '', - // 'OS version:' => '', - // 'Database version:' => '', - // 'Browser:' => '', - // 'Task view' => '', - // 'Edit task' => '', - // 'Edit description' => '', - // 'New internal link' => '', - // 'Display list of keyboard shortcuts' => '', - // 'Menu' => '', - // 'Set start date' => '', - // 'Avatar' => '', - // 'Upload my avatar image' => '', - // 'Remove my image' => '', - // 'The OAuth2 state parameter is invalid' => '', - // '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' => '', -); diff --git a/sources/app/Middleware/ApplicationAuthorizationMiddleware.php b/sources/app/Middleware/ApplicationAuthorizationMiddleware.php deleted file mode 100644 index faca2d6..0000000 --- a/sources/app/Middleware/ApplicationAuthorizationMiddleware.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -namespace Kanboard\Middleware; - -use Kanboard\Core\Controller\AccessForbiddenException; -use Kanboard\Core\Controller\BaseMiddleware; - -/** - * Class ApplicationAuthorizationMiddleware - * - * @package Kanboard\Middleware - * @author Frederic Guillot - */ -class ApplicationAuthorizationMiddleware extends BaseMiddleware -{ - /** - * Execute middleware - */ - public function execute() - { - if (! $this->helper->user->hasAccess($this->router->getController(), $this->router->getAction())) { - throw new AccessForbiddenException(); - } - - $this->next(); - } -} diff --git a/sources/app/Middleware/AuthenticationMiddleware.php b/sources/app/Middleware/AuthenticationMiddleware.php deleted file mode 100644 index 499843f..0000000 --- a/sources/app/Middleware/AuthenticationMiddleware.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php - -namespace Kanboard\Middleware; - -use Kanboard\Core\Controller\AccessForbiddenException; -use Kanboard\Core\Controller\BaseMiddleware; -use Kanboard\Core\Security\Role; - -/** - * Class AuthenticationMiddleware - * - * @package Kanboard\Middleware - * @author Frederic Guillot - */ -class AuthenticationMiddleware extends BaseMiddleware -{ - /** - * Execute middleware - */ - public function execute() - { - if (! $this->authenticationManager->checkCurrentSession()) { - throw AccessForbiddenException::getInstance()->withoutLayout(); - } - - if (! $this->isPublicAccess()) { - $this->handleAuthentication(); - } - - $this->next(); - } - - protected function handleAuthentication() - { - if (! $this->userSession->isLogged() && ! $this->authenticationManager->preAuthentication()) { - $this->nextMiddleware = null; - - if ($this->request->isAjax()) { - $this->response->text('Not Authorized', 401); - } else { - $this->sessionStorage->redirectAfterLogin = $this->request->getUri(); - $this->response->redirect($this->helper->url->to('AuthController', 'login')); - } - } - } - - protected function isPublicAccess() - { - if ($this->applicationAuthorization->isAllowed($this->router->getController(), $this->router->getAction(), Role::APP_PUBLIC)) { - $this->nextMiddleware = null; - return true; - } - - return false; - } -} diff --git a/sources/app/Middleware/BootstrapMiddleware.php b/sources/app/Middleware/BootstrapMiddleware.php deleted file mode 100644 index 727f600..0000000 --- a/sources/app/Middleware/BootstrapMiddleware.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -namespace Kanboard\Middleware; - -use Kanboard\Core\Controller\BaseMiddleware; - -/** - * Class BootstrapMiddleware - * - * @package Kanboard\Middleware - * @author Frederic Guillot - */ -class BootstrapMiddleware extends BaseMiddleware -{ - /** - * Execute middleware - */ - public function execute() - { - $this->sessionManager->open(); - $this->dispatcher->dispatch('app.bootstrap'); - $this->sendHeaders(); - $this->next(); - } - - /** - * Send HTTP headers - * - * @access private - */ - private function sendHeaders() - { - $this->response->withContentSecurityPolicy($this->container['cspRules']); - $this->response->withSecurityHeaders(); - - if (ENABLE_XFRAME) { - $this->response->withXframe(); - } - - if (ENABLE_HSTS) { - $this->response->withStrictTransportSecurity(); - } - } -} diff --git a/sources/app/Middleware/PostAuthenticationMiddleware.php b/sources/app/Middleware/PostAuthenticationMiddleware.php deleted file mode 100644 index f7eccbc..0000000 --- a/sources/app/Middleware/PostAuthenticationMiddleware.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -namespace Kanboard\Middleware; - -use Kanboard\Core\Controller\BaseMiddleware; - -/** - * Class PostAuthenticationMiddleware - * - * @package Kanboard\Middleware - * @author Frederic Guillot - */ -class PostAuthenticationMiddleware extends BaseMiddleware -{ - /** - * Execute middleware - */ - public function execute() - { - $controller = strtolower($this->router->getController()); - $action = strtolower($this->router->getAction()); - $ignore = ($controller === 'twofactorcontroller' && in_array($action, array('code', 'check'))) || ($controller === 'authcontroller' && $action === 'logout'); - - if ($ignore === false && $this->userSession->hasPostAuthentication() && ! $this->userSession->isPostAuthenticationValidated()) { - $this->nextMiddleware = null; - - if ($this->request->isAjax()) { - $this->response->text('Not Authorized', 401); - } - - $this->response->redirect($this->helper->url->to('TwoFactorController', 'code')); - } - - $this->next(); - } -} diff --git a/sources/app/Middleware/ProjectAuthorizationMiddleware.php b/sources/app/Middleware/ProjectAuthorizationMiddleware.php deleted file mode 100644 index 704491b..0000000 --- a/sources/app/Middleware/ProjectAuthorizationMiddleware.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -namespace Kanboard\Middleware; - -use Kanboard\Core\Controller\AccessForbiddenException; -use Kanboard\Core\Controller\BaseMiddleware; - -/** - * Class ProjectAuthorizationMiddleware - * - * @package Kanboard\Middleware - * @author Frederic Guillot - */ -class ProjectAuthorizationMiddleware extends BaseMiddleware -{ - /** - * Execute middleware - */ - public function execute() - { - $project_id = $this->request->getIntegerParam('project_id'); - $task_id = $this->request->getIntegerParam('task_id'); - - if ($task_id > 0 && $project_id === 0) { - $project_id = $this->taskFinderModel->getProjectId($task_id); - } - - if ($project_id > 0 && ! $this->helper->user->hasProjectAccess($this->router->getController(), $this->router->getAction(), $project_id)) { - throw new AccessForbiddenException(); - } - - $this->next(); - } -} diff --git a/sources/app/Model/ActionModel.php b/sources/app/Model/ActionModel.php deleted file mode 100644 index b5d2bd0..0000000 --- a/sources/app/Model/ActionModel.php +++ /dev/null @@ -1,202 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Action Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ActionModel extends Base -{ - /** - * SQL table name for actions - * - * @var string - */ - const TABLE = 'actions'; - - /** - * Return actions and parameters for a given user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getAllByUser($user_id) - { - $project_ids = $this->projectPermissionModel->getActiveProjectIds($user_id); - $actions = array(); - - if (! empty($project_ids)) { - $actions = $this->db->table(self::TABLE)->in('project_id', $project_ids)->findAll(); - $params = $this->actionParameterModel->getAllByActions(array_column($actions, 'id')); - $this->attachParamsToActions($actions, $params); - } - - return $actions; - } - - /** - * Return actions and parameters for a given project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getAllByProject($project_id) - { - $actions = $this->db->table(self::TABLE)->eq('project_id', $project_id)->findAll(); - $params = $this->actionParameterModel->getAllByActions(array_column($actions, 'id')); - return $this->attachParamsToActions($actions, $params); - } - - /** - * Return all actions and parameters - * - * @access public - * @return array - */ - public function getAll() - { - $actions = $this->db->table(self::TABLE)->findAll(); - $params = $this->actionParameterModel->getAll(); - return $this->attachParamsToActions($actions, $params); - } - - /** - * Fetch an action - * - * @access public - * @param integer $action_id - * @return array - */ - public function getById($action_id) - { - $action = $this->db->table(self::TABLE)->eq('id', $action_id)->findOne(); - - if (! empty($action)) { - $action['params'] = $this->actionParameterModel->getAllByAction($action_id); - } - - return $action; - } - - /** - * Get the projectId by the actionId - * - * @access public - * @param integer $action_id - * @return integer - */ - public function getProjectId($action_id) - { - return $this->db->table(self::TABLE)->eq('id', $action_id)->findOneColumn('project_id') ?: 0; - } - - /** - * Attach parameters to actions - * - * @access private - * @param array &$actions - * @param array &$params - * @return array - */ - private function attachParamsToActions(array &$actions, array &$params) - { - foreach ($actions as &$action) { - $action['params'] = isset($params[$action['id']]) ? $params[$action['id']] : array(); - } - - return $actions; - } - - /** - * Remove an action - * - * @access public - * @param integer $action_id - * @return bool - */ - public function remove($action_id) - { - return $this->db->table(self::TABLE)->eq('id', $action_id)->remove(); - } - - /** - * Create an action - * - * @access public - * @param array $values Required parameters to save an action - * @return boolean|integer - */ - public function create(array $values) - { - $this->db->startTransaction(); - - $action = array( - 'project_id' => $values['project_id'], - 'event_name' => $values['event_name'], - 'action_name' => $values['action_name'], - ); - - if (! $this->db->table(self::TABLE)->insert($action)) { - $this->db->cancelTransaction(); - return false; - } - - $action_id = $this->db->getLastId(); - - if (! $this->actionParameterModel->create($action_id, $values)) { - $this->db->cancelTransaction(); - return false; - } - - $this->db->closeTransaction(); - - return $action_id; - } - - /** - * Copy actions from a project to another one (skip actions that cannot resolve parameters) - * - * @author Antonio Rabelo - * @param integer $src_project_id Source project id - * @param integer $dst_project_id Destination project id - * @return boolean - */ - public function duplicate($src_project_id, $dst_project_id) - { - $actions = $this->actionModel->getAllByProject($src_project_id); - - foreach ($actions as $action) { - $this->db->startTransaction(); - - $values = array( - 'project_id' => $dst_project_id, - 'event_name' => $action['event_name'], - 'action_name' => $action['action_name'], - ); - - if (! $this->db->table(self::TABLE)->insert($values)) { - $this->db->cancelTransaction(); - continue; - } - - $action_id = $this->db->getLastId(); - - if (! $this->actionParameterModel->duplicateParameters($dst_project_id, $action_id, $action['params'])) { - $this->logger->error('Action::duplicate => skip action '.$action['action_name'].' '.$action['id']); - $this->db->cancelTransaction(); - continue; - } - - $this->db->closeTransaction(); - } - - return true; - } -} diff --git a/sources/app/Model/ActionParameterModel.php b/sources/app/Model/ActionParameterModel.php deleted file mode 100644 index 9895da0..0000000 --- a/sources/app/Model/ActionParameterModel.php +++ /dev/null @@ -1,164 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Action Parameter Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ActionParameterModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'action_has_params'; - - /** - * Get all action params - * - * @access public - * @return array - */ - public function getAll() - { - $params = $this->db->table(self::TABLE)->findAll(); - return $this->toDictionary($params); - } - - /** - * Get all params for a list of actions - * - * @access public - * @param array $action_ids - * @return array - */ - public function getAllByActions(array $action_ids) - { - $params = $this->db->table(self::TABLE)->in('action_id', $action_ids)->findAll(); - return $this->toDictionary($params); - } - - /** - * Build params dictionary - * - * @access private - * @param array $params - * @return array - */ - private function toDictionary(array $params) - { - $result = array(); - - foreach ($params as $param) { - $result[$param['action_id']][$param['name']] = $param['value']; - } - - return $result; - } - - /** - * Get all action params for a given action - * - * @access public - * @param integer $action_id - * @return array - */ - public function getAllByAction($action_id) - { - return $this->db->hashtable(self::TABLE)->eq('action_id', $action_id)->getAll('name', 'value'); - } - - /** - * Insert new parameters for an action - * - * @access public - * @param integer $action_id - * @param array $values - * @return boolean - */ - public function create($action_id, array $values) - { - foreach ($values['params'] as $name => $value) { - $param = array( - 'action_id' => $action_id, - 'name' => $name, - 'value' => $value, - ); - - if (! $this->db->table(self::TABLE)->save($param)) { - return false; - } - } - - return true; - } - - /** - * Duplicate action parameters - * - * @access public - * @param integer $project_id - * @param integer $action_id - * @param array $params - * @return boolean - */ - public function duplicateParameters($project_id, $action_id, array $params) - { - foreach ($params as $name => $value) { - $value = $this->resolveParameter($project_id, $name, $value); - - if ($value === false) { - $this->logger->error('ActionParameter::duplicateParameters => unable to resolve '.$name.'='.$value); - return false; - } - - $values = array( - 'action_id' => $action_id, - 'name' => $name, - 'value' => $value, - ); - - if (! $this->db->table(self::TABLE)->insert($values)) { - return false; - } - } - - return true; - } - - /** - * Resolve action parameter values according to another project - * - * @access private - * @param integer $project_id - * @param string $name - * @param string $value - * @return mixed - */ - private function resolveParameter($project_id, $name, $value) - { - switch ($name) { - case 'project_id': - return $value != $project_id ? $value : false; - case 'category_id': - return $this->categoryModel->getIdByName($project_id, $this->categoryModel->getNameById($value)) ?: false; - case 'src_column_id': - case 'dest_column_id': - case 'dst_column_id': - case 'column_id': - $column = $this->columnModel->getById($value); - return empty($column) ? false : $this->columnModel->getColumnIdByTitle($project_id, $column['title']) ?: false; - case 'user_id': - case 'owner_id': - return $this->projectPermissionModel->isAssignable($project_id, $value) ? $value : false; - default: - return $value; - } - } -} diff --git a/sources/app/Model/AvatarFileModel.php b/sources/app/Model/AvatarFileModel.php deleted file mode 100644 index 6e36d83..0000000 --- a/sources/app/Model/AvatarFileModel.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Exception; -use Kanboard\Core\Base; - -/** - * Avatar File - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class AvatarFileModel extends Base -{ - /** - * Path prefix - * - * @var string - */ - const PATH_PREFIX = 'avatars'; - - /** - * Get image filename - * - * @access public - * @param integer $user_id - * @return string - */ - public function getFilename($user_id) - { - return $this->db->table(UserModel::TABLE)->eq('id', $user_id)->findOneColumn('avatar_path'); - } - - /** - * Add avatar in the user profile - * - * @access public - * @param integer $user_id Foreign key - * @param string $path Path on the disk - * @return bool - */ - public function create($user_id, $path) - { - $result = $this->db->table(UserModel::TABLE)->eq('id', $user_id)->update(array( - 'avatar_path' => $path, - )); - - $this->userSession->refresh($user_id); - - return $result; - } - - /** - * Remove avatar from the user profile - * - * @access public - * @param integer $user_id Foreign key - * @return bool - */ - public function remove($user_id) - { - try { - $filename = $this->getFilename($user_id); - - if (! empty($filename)) { - $this->objectStorage->remove($filename); - return $this->db->table(UserModel::TABLE)->eq('id', $user_id)->update(array('avatar_path' => '')); - } - } catch (Exception $e) { - $this->logger->error($e->getMessage()); - return false; - } - - return true; - } - - /** - * Upload avatar image file - * - * @access public - * @param integer $user_id - * @param array $file - * @return boolean - */ - public function uploadImageFile($user_id, array $file) - { - try { - if ($file['error'] == UPLOAD_ERR_OK && $file['size'] > 0) { - $destinationFilename = $this->generatePath($user_id, $file['name']); - $this->objectStorage->moveUploadedFile($file['tmp_name'], $destinationFilename); - $this->create($user_id, $destinationFilename); - } else { - throw new Exception('File not uploaded: '.var_export($file['error'], true)); - } - - } catch (Exception $e) { - $this->logger->error($e->getMessage()); - return false; - } - - return true; - } - - /** - * Upload avatar image content - * - * @access public - * @param integer $user_id - * @param string $blob - * @return boolean - */ - public function uploadImageContent($user_id, &$blob) - { - try { - $destinationFilename = $this->generatePath($user_id, 'imageContent'); - $this->objectStorage->put($destinationFilename, $blob); - $this->create($user_id, $destinationFilename); - } catch (Exception $e) { - $this->logger->error($e->getMessage()); - return false; - } - - return true; - } - - /** - * Generate the path for a new filename - * - * @access public - * @param integer $user_id - * @param string $filename - * @return string - */ - public function generatePath($user_id, $filename) - { - return implode(DIRECTORY_SEPARATOR, array(self::PATH_PREFIX, $user_id, hash('sha1', $filename.time()))); - } -} diff --git a/sources/app/Model/BoardModel.php b/sources/app/Model/BoardModel.php deleted file mode 100644 index 4d55993..0000000 --- a/sources/app/Model/BoardModel.php +++ /dev/null @@ -1,115 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Board model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class BoardModel extends Base -{ - /** - * Get Kanboard default columns - * - * @access public - * @return string[] - */ - public function getDefaultColumns() - { - return array(t('Backlog'), t('Ready'), t('Work in progress'), t('Done')); - } - - /** - * Get user default columns - * - * @access public - * @return array - */ - public function getUserColumns() - { - $column_names = explode(',', $this->configModel->get('board_columns', implode(',', $this->getDefaultColumns()))); - $columns = array(); - - foreach ($column_names as $column_name) { - $column_name = trim($column_name); - - if (! empty($column_name)) { - $columns[] = array('title' => $column_name, 'task_limit' => 0, 'description' => ''); - } - } - - return $columns; - } - - /** - * Create a board with default columns, must be executed inside a transaction - * - * @access public - * @param integer $project_id Project id - * @param array $columns Column parameters [ 'title' => 'boo', 'task_limit' => 2 ... ] - * @return boolean - */ - public function create($project_id, array $columns) - { - $position = 0; - - foreach ($columns as $column) { - $values = array( - 'title' => $column['title'], - 'position' => ++$position, - 'project_id' => $project_id, - 'task_limit' => $column['task_limit'], - 'description' => $column['description'], - ); - - if (! $this->db->table(ColumnModel::TABLE)->save($values)) { - return false; - } - } - - return true; - } - - /** - * Copy board columns from a project to another one - * - * @author Antonio Rabelo - * @param integer $project_from Project Template - * @param integer $project_to Project that receives the copy - * @return boolean - */ - public function duplicate($project_from, $project_to) - { - $columns = $this->db->table(ColumnModel::TABLE) - ->columns('title', 'task_limit', 'description') - ->eq('project_id', $project_from) - ->asc('position') - ->findAll(); - - return $this->boardModel->create($project_to, $columns); - } - - /** - * Get the total of tasks per column - * - * @access public - * @param integer $project_id - * @param boolean $prepend Prepend default value - * @return array - */ - public function getColumnStats($project_id, $prepend = false) - { - $listing = $this->db - ->hashtable(TaskModel::TABLE) - ->eq('project_id', $project_id) - ->eq('is_active', 1) - ->groupBy('column_id') - ->getAll('column_id', 'COUNT(*) AS total'); - - return $prepend ? array(-1 => t('All columns')) + $listing : $listing; - } -} diff --git a/sources/app/Model/CategoryModel.php b/sources/app/Model/CategoryModel.php deleted file mode 100644 index 024d002..0000000 --- a/sources/app/Model/CategoryModel.php +++ /dev/null @@ -1,230 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Category model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class CategoryModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'project_has_categories'; - - /** - * Return true if a category exists for a given project - * - * @access public - * @param integer $category_id Category id - * @return boolean - */ - public function exists($category_id) - { - return $this->db->table(self::TABLE)->eq('id', $category_id)->exists(); - } - - /** - * Get a category by the id - * - * @access public - * @param integer $category_id Category id - * @return array - */ - public function getById($category_id) - { - return $this->db->table(self::TABLE)->eq('id', $category_id)->findOne(); - } - - /** - * Get the category name by the id - * - * @access public - * @param integer $category_id Category id - * @return string - */ - public function getNameById($category_id) - { - return $this->db->table(self::TABLE)->eq('id', $category_id)->findOneColumn('name') ?: ''; - } - - /** - * Get the projectId by the category id - * - * @access public - * @param integer $category_id Category id - * @return integer - */ - public function getProjectId($category_id) - { - return $this->db->table(self::TABLE)->eq('id', $category_id)->findOneColumn('project_id') ?: 0; - } - - /** - * Get a category id by the category name and project id - * - * @access public - * @param integer $project_id Project id - * @param string $category_name Category name - * @return integer - */ - public function getIdByName($project_id, $category_name) - { - return (int) $this->db->table(self::TABLE) - ->eq('project_id', $project_id) - ->eq('name', $category_name) - ->findOneColumn('id'); - } - - /** - * Return the list of all categories - * - * @access public - * @param integer $project_id Project id - * @param bool $prepend_none If true, prepend to the list the value 'None' - * @param bool $prepend_all If true, prepend to the list the value 'All' - * @return array - */ - public function getList($project_id, $prepend_none = true, $prepend_all = false) - { - $listing = $this->db->hashtable(self::TABLE) - ->eq('project_id', $project_id) - ->asc('name') - ->getAll('id', 'name'); - - $prepend = array(); - - if ($prepend_all) { - $prepend[-1] = t('All categories'); - } - - if ($prepend_none) { - $prepend[0] = t('No category'); - } - - return $prepend + $listing; - } - - /** - * Return all categories for a given project - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getAll($project_id) - { - return $this->db->table(self::TABLE) - ->eq('project_id', $project_id) - ->asc('name') - ->findAll(); - } - - /** - * Create default categories during project creation (transaction already started in Project::create()) - * - * @access public - * @param integer $project_id - * @return boolean - */ - public function createDefaultCategories($project_id) - { - $results = array(); - $categories = explode(',', $this->configModel->get('project_categories')); - - foreach ($categories as $category) { - $category = trim($category); - - if (! empty($category)) { - $results[] = $this->db->table(self::TABLE)->insert(array( - 'project_id' => $project_id, - 'name' => $category, - )); - } - } - - return in_array(false, $results, true); - } - - /** - * Create a category (run inside a transaction) - * - * @access public - * @param array $values Form values - * @return bool|integer - */ - public function create(array $values) - { - return $this->db->table(self::TABLE)->persist($values); - } - - /** - * Update a category - * - * @access public - * @param array $values Form values - * @return bool - */ - public function update(array $values) - { - return $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); - } - - /** - * Remove a category - * - * @access public - * @param integer $category_id Category id - * @return bool - */ - public function remove($category_id) - { - $this->db->startTransaction(); - - $this->db->table(TaskModel::TABLE)->eq('category_id', $category_id)->update(array('category_id' => 0)); - - if (! $this->db->table(self::TABLE)->eq('id', $category_id)->remove()) { - $this->db->cancelTransaction(); - return false; - } - - $this->db->closeTransaction(); - - return true; - } - - /** - * Duplicate categories from a project to another one, must be executed inside a transaction - * - * @author Antonio Rabelo - * @param integer $src_project_id Source project id - * @param integer $dst_project_id Destination project id - * @return boolean - */ - public function duplicate($src_project_id, $dst_project_id) - { - $categories = $this->db - ->table(self::TABLE) - ->columns('name', 'description') - ->eq('project_id', $src_project_id) - ->asc('name') - ->findAll(); - - foreach ($categories as $category) { - $category['project_id'] = $dst_project_id; - - if (! $this->db->table(self::TABLE)->save($category)) { - return false; - } - } - - return true; - } -} diff --git a/sources/app/Model/ColorModel.php b/sources/app/Model/ColorModel.php deleted file mode 100644 index 9e69dda..0000000 --- a/sources/app/Model/ColorModel.php +++ /dev/null @@ -1,228 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Color model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ColorModel extends Base -{ - /** - * Default colors - * - * @access private - * @var array - */ - private $default_colors = array( - 'yellow' => array( - 'name' => 'Yellow', - 'background' => 'rgb(245, 247, 196)', - 'border' => 'rgb(223, 227, 45)', - ), - 'blue' => array( - 'name' => 'Blue', - 'background' => 'rgb(219, 235, 255)', - 'border' => 'rgb(168, 207, 255)', - ), - 'green' => array( - 'name' => 'Green', - 'background' => 'rgb(189, 244, 203)', - 'border' => 'rgb(74, 227, 113)', - ), - 'purple' => array( - 'name' => 'Purple', - 'background' => 'rgb(223, 176, 255)', - 'border' => 'rgb(205, 133, 254)', - ), - 'red' => array( - 'name' => 'Red', - 'background' => 'rgb(255, 187, 187)', - 'border' => 'rgb(255, 151, 151)', - ), - 'orange' => array( - 'name' => 'Orange', - 'background' => 'rgb(255, 215, 179)', - 'border' => 'rgb(255, 172, 98)', - ), - 'grey' => array( - 'name' => 'Grey', - 'background' => 'rgb(238, 238, 238)', - 'border' => 'rgb(204, 204, 204)', - ), - 'brown' => array( - 'name' => 'Brown', - 'background' => '#d7ccc8', - 'border' => '#4e342e', - ), - 'deep_orange' => array( - 'name' => 'Deep Orange', - 'background' => '#ffab91', - 'border' => '#e64a19', - ), - 'dark_grey' => array( - 'name' => 'Dark Grey', - 'background' => '#cfd8dc', - 'border' => '#455a64', - ), - 'pink' => array( - 'name' => 'Pink', - 'background' => '#f48fb1', - 'border' => '#d81b60', - ), - 'teal' => array( - 'name' => 'Teal', - 'background' => '#80cbc4', - 'border' => '#00695c', - ), - 'cyan' => array( - 'name' => 'Cyan', - 'background' => '#b2ebf2', - 'border' => '#00bcd4', - ), - 'lime' => array( - 'name' => 'Lime', - 'background' => '#e6ee9c', - 'border' => '#afb42b', - ), - 'light_green' => array( - 'name' => 'Light Green', - 'background' => '#dcedc8', - 'border' => '#689f38', - ), - 'amber' => array( - 'name' => 'Amber', - 'background' => '#ffe082', - 'border' => '#ffa000', - ), - ); - - /** - * Find a color id from the name or the id - * - * @access public - * @param string $color - * @return string - */ - public function find($color) - { - $color = strtolower($color); - - foreach ($this->default_colors as $color_id => $params) { - if ($color_id === $color) { - return $color_id; - } elseif ($color === strtolower($params['name'])) { - return $color_id; - } - } - - return ''; - } - - /** - * Get color properties - * - * @access public - * @param string $color_id - * @return array - */ - public function getColorProperties($color_id) - { - if (isset($this->default_colors[$color_id])) { - return $this->default_colors[$color_id]; - } - - return $this->default_colors[$this->getDefaultColor()]; - } - - /** - * Get available colors - * - * @access public - * @param bool $prepend - * @return array - */ - public function getList($prepend = false) - { - $listing = $prepend ? array('' => t('All colors')) : array(); - - foreach ($this->default_colors as $color_id => $color) { - $listing[$color_id] = t($color['name']); - } - - return $listing; - } - - /** - * Get the default color - * - * @access public - * @return string - */ - public function getDefaultColor() - { - return $this->configModel->get('default_color', 'yellow'); - } - - /** - * Get the default colors - * - * @access public - * @return array - */ - public function getDefaultColors() - { - return $this->default_colors; - } - - /** - * Get border color from string - * - * @access public - * @param string $color_id Color id - * @return string - */ - public function getBorderColor($color_id) - { - $color = $this->getColorProperties($color_id); - return $color['border']; - } - - /** - * Get background color from the color_id - * - * @access public - * @param string $color_id Color id - * @return string - */ - public function getBackgroundColor($color_id) - { - $color = $this->getColorProperties($color_id); - return $color['background']; - } - - /** - * Get CSS stylesheet of all colors - * - * @access public - * @return string - */ - public function getCss() - { - $buffer = ''; - - foreach ($this->default_colors as $color => $values) { - $buffer .= 'div.color-'.$color.' {'; - $buffer .= 'background-color: '.$values['background'].';'; - $buffer .= 'border-color: '.$values['border']; - $buffer .= '}'; - $buffer .= 'td.color-'.$color.' { background-color: '.$values['background'].'}'; - } - - return $buffer; - } -} diff --git a/sources/app/Model/ColumnModel.php b/sources/app/Model/ColumnModel.php deleted file mode 100644 index 795fe69..0000000 --- a/sources/app/Model/ColumnModel.php +++ /dev/null @@ -1,223 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Column Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ColumnModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'columns'; - - /** - * Get a column by the id - * - * @access public - * @param integer $column_id Column id - * @return array - */ - public function getById($column_id) - { - return $this->db->table(self::TABLE)->eq('id', $column_id)->findOne(); - } - - /** - * Get projectId by the columnId - * - * @access public - * @param integer $column_id Column id - * @return integer - */ - public function getProjectId($column_id) - { - return $this->db->table(self::TABLE)->eq('id', $column_id)->findOneColumn('project_id'); - } - - /** - * Get the first column id for a given project - * - * @access public - * @param integer $project_id Project id - * @return integer - */ - public function getFirstColumnId($project_id) - { - return $this->db->table(self::TABLE)->eq('project_id', $project_id)->asc('position')->findOneColumn('id'); - } - - /** - * Get the last column id for a given project - * - * @access public - * @param integer $project_id Project id - * @return integer - */ - public function getLastColumnId($project_id) - { - return $this->db->table(self::TABLE)->eq('project_id', $project_id)->desc('position')->findOneColumn('id'); - } - - /** - * Get the position of the last column for a given project - * - * @access public - * @param integer $project_id Project id - * @return integer - */ - public function getLastColumnPosition($project_id) - { - return (int) $this->db - ->table(self::TABLE) - ->eq('project_id', $project_id) - ->desc('position') - ->findOneColumn('position'); - } - - /** - * Get a column id by the name - * - * @access public - * @param integer $project_id - * @param string $title - * @return integer - */ - public function getColumnIdByTitle($project_id, $title) - { - return (int) $this->db->table(self::TABLE)->eq('project_id', $project_id)->eq('title', $title)->findOneColumn('id'); - } - - /** - * Get a column title by the id - * - * @access public - * @param integer $column_id - * @return integer - */ - public function getColumnTitleById($column_id) - { - return $this->db->table(self::TABLE)->eq('id', $column_id)->findOneColumn('title'); - } - - /** - * Get all columns sorted by position for a given project - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getAll($project_id) - { - return $this->db->table(self::TABLE)->eq('project_id', $project_id)->asc('position')->findAll(); - } - - /** - * Get the list of columns sorted by position [ column_id => title ] - * - * @access public - * @param integer $project_id Project id - * @param boolean $prepend Prepend a default value - * @return array - */ - public function getList($project_id, $prepend = false) - { - $listing = $this->db->hashtable(self::TABLE)->eq('project_id', $project_id)->asc('position')->getAll('id', 'title'); - return $prepend ? array(-1 => t('All columns')) + $listing : $listing; - } - - /** - * Add a new column to the board - * - * @access public - * @param integer $project_id Project id - * @param string $title Column title - * @param integer $task_limit Task limit - * @param string $description Column description - * @return boolean|integer - */ - public function create($project_id, $title, $task_limit = 0, $description = '') - { - $values = array( - 'project_id' => $project_id, - 'title' => $title, - 'task_limit' => intval($task_limit), - 'position' => $this->getLastColumnPosition($project_id) + 1, - 'description' => $description, - ); - - return $this->db->table(self::TABLE)->persist($values); - } - - /** - * Update a column - * - * @access public - * @param integer $column_id Column id - * @param string $title Column title - * @param integer $task_limit Task limit - * @param string $description Optional description - * @return boolean - */ - public function update($column_id, $title, $task_limit = 0, $description = '') - { - return $this->db->table(self::TABLE)->eq('id', $column_id)->update(array( - 'title' => $title, - 'task_limit' => intval($task_limit), - 'description' => $description, - )); - } - - /** - * Remove a column and all tasks associated to this column - * - * @access public - * @param integer $column_id Column id - * @return boolean - */ - public function remove($column_id) - { - return $this->db->table(self::TABLE)->eq('id', $column_id)->remove(); - } - - /** - * Change column position - * - * @access public - * @param integer $project_id - * @param integer $column_id - * @param integer $position - * @return boolean - */ - public function changePosition($project_id, $column_id, $position) - { - if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('project_id', $project_id)->count()) { - return false; - } - - $column_ids = $this->db->table(self::TABLE)->eq('project_id', $project_id)->neq('id', $column_id)->asc('position')->findAllByColumn('id'); - $offset = 1; - $results = array(); - - foreach ($column_ids as $current_column_id) { - if ($offset == $position) { - $offset++; - } - - $results[] = $this->db->table(self::TABLE)->eq('id', $current_column_id)->update(array('position' => $offset)); - $offset++; - } - - $results[] = $this->db->table(self::TABLE)->eq('id', $column_id)->update(array('position' => $position)); - - return !in_array(false, $results, true); - } -} diff --git a/sources/app/Model/CommentModel.php b/sources/app/Model/CommentModel.php deleted file mode 100644 index 4231f29..0000000 --- a/sources/app/Model/CommentModel.php +++ /dev/null @@ -1,173 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Event\CommentEvent; -use Kanboard\Core\Base; - -/** - * Comment model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class CommentModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'comments'; - - /** - * Events - * - * @var string - */ - const EVENT_UPDATE = 'comment.update'; - const EVENT_CREATE = 'comment.create'; - const EVENT_USER_MENTION = 'comment.user.mention'; - - /** - * Get projectId from commentId - * - * @access public - * @param integer $comment_id - * @return integer - */ - public function getProjectId($comment_id) - { - return $this->db - ->table(self::TABLE) - ->eq(self::TABLE.'.id', $comment_id) - ->join(TaskModel::TABLE, 'id', 'task_id') - ->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0; - } - - /** - * Get all comments for a given task - * - * @access public - * @param integer $task_id Task id - * @param string $sorting ASC/DESC - * @return array - */ - public function getAll($task_id, $sorting = 'ASC') - { - return $this->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.id', - self::TABLE.'.date_creation', - self::TABLE.'.task_id', - self::TABLE.'.user_id', - self::TABLE.'.comment', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name', - UserModel::TABLE.'.email', - UserModel::TABLE.'.avatar_path' - ) - ->join(UserModel::TABLE, 'id', 'user_id') - ->orderBy(self::TABLE.'.date_creation', $sorting) - ->eq(self::TABLE.'.task_id', $task_id) - ->findAll(); - } - - /** - * Get a comment - * - * @access public - * @param integer $comment_id Comment id - * @return array - */ - public function getById($comment_id) - { - return $this->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.id', - self::TABLE.'.task_id', - self::TABLE.'.user_id', - self::TABLE.'.date_creation', - self::TABLE.'.comment', - self::TABLE.'.reference', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name', - UserModel::TABLE.'.email', - UserModel::TABLE.'.avatar_path' - ) - ->join(UserModel::TABLE, 'id', 'user_id') - ->eq(self::TABLE.'.id', $comment_id) - ->findOne(); - } - - /** - * Get the number of comments for a given task - * - * @access public - * @param integer $task_id Task id - * @return integer - */ - public function count($task_id) - { - return $this->db - ->table(self::TABLE) - ->eq(self::TABLE.'.task_id', $task_id) - ->count(); - } - - /** - * Create a new comment - * - * @access public - * @param array $values Form values - * @return boolean|integer - */ - public function create(array $values) - { - $values['date_creation'] = time(); - $comment_id = $this->db->table(self::TABLE)->persist($values); - - if ($comment_id !== false) { - $event = new CommentEvent(array('id' => $comment_id) + $values); - $this->dispatcher->dispatch(self::EVENT_CREATE, $event); - $this->userMentionModel->fireEvents($values['comment'], self::EVENT_USER_MENTION, $event); - } - - return $comment_id; - } - - /** - * Update a comment in the database - * - * @access public - * @param array $values Form values - * @return boolean - */ - public function update(array $values) - { - $result = $this->db - ->table(self::TABLE) - ->eq('id', $values['id']) - ->update(array('comment' => $values['comment'])); - - if ($result) { - $this->container['dispatcher']->dispatch(self::EVENT_UPDATE, new CommentEvent($values)); - } - - return $result; - } - - /** - * Remove a comment - * - * @access public - * @param integer $comment_id Comment id - * @return boolean - */ - public function remove($comment_id) - { - return $this->db->table(self::TABLE)->eq('id', $comment_id)->remove(); - } -} diff --git a/sources/app/Model/ConfigModel.php b/sources/app/Model/ConfigModel.php deleted file mode 100644 index 945c5e6..0000000 --- a/sources/app/Model/ConfigModel.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Security\Token; - -/** - * Config model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ConfigModel extends SettingModel -{ - /** - * Get a config variable with in-memory caching - * - * @access public - * @param string $name Parameter name - * @param string $default_value Default value of the parameter - * @return string - */ - public function get($name, $default_value = '') - { - $options = $this->memoryCache->proxy($this, 'getAll'); - return isset($options[$name]) && $options[$name] !== '' ? $options[$name] : $default_value; - } - - /** - * Optimize the Sqlite database - * - * @access public - * @return boolean - */ - public function optimizeDatabase() - { - return $this->db->getConnection()->exec('VACUUM'); - } - - /** - * Compress the Sqlite database - * - * @access public - * @return string - */ - public function downloadDatabase() - { - return gzencode(file_get_contents(DB_FILENAME)); - } - - /** - * Get the Sqlite database size in bytes - * - * @access public - * @return integer - */ - public function getDatabaseSize() - { - return DB_DRIVER === 'sqlite' ? filesize(DB_FILENAME) : 0; - } - - /** - * Regenerate a token - * - * @access public - * @param string $option Parameter name - * @return boolean - */ - public function regenerateToken($option) - { - return $this->save(array($option => Token::getToken())); - } - - /** - * Prepare data before save - * - * @access public - * @param array $values - * @return array - */ - public function prepare(array $values) - { - if (! empty($values['application_url']) && substr($values['application_url'], -1) !== '/') { - $values['application_url'] = $values['application_url'].'/'; - } - - return $values; - } -} diff --git a/sources/app/Model/CurrencyModel.php b/sources/app/Model/CurrencyModel.php deleted file mode 100644 index bfd9697..0000000 --- a/sources/app/Model/CurrencyModel.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Currency - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class CurrencyModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'currencies'; - - /** - * Get available application currencies - * - * @access public - * @return array - */ - public function getCurrencies() - { - return array( - 'USD' => t('USD - US Dollar'), - 'EUR' => t('EUR - Euro'), - 'GBP' => t('GBP - British Pound'), - 'CHF' => t('CHF - Swiss Francs'), - 'CAD' => t('CAD - Canadian Dollar'), - 'AUD' => t('AUD - Australian Dollar'), - 'NZD' => t('NZD - New Zealand Dollar'), - 'INR' => t('INR - Indian Rupee'), - 'JPY' => t('JPY - Japanese Yen'), - 'RSD' => t('RSD - Serbian dinar'), - 'SEK' => t('SEK - Swedish Krona'), - 'NOK' => t('NOK - Norwegian Krone'), - 'BAM' => t('BAM - Konvertible Mark'), - 'RUB' => t('RUB - Russian Ruble'), - ); - } - - /** - * Get all currency rates - * - * @access public - * @return array - */ - public function getAll() - { - return $this->db->table(self::TABLE)->findAll(); - } - - /** - * Calculate the price for the reference currency - * - * @access public - * @param string $currency - * @param double $price - * @return double - */ - public function getPrice($currency, $price) - { - static $rates = null; - $reference = $this->configModel->get('application_currency', 'USD'); - - if ($reference !== $currency) { - $rates = $rates === null ? $this->db->hashtable(self::TABLE)->getAll('currency', 'rate') : $rates; - $rate = isset($rates[$currency]) ? $rates[$currency] : 1; - - return $rate * $price; - } - - return $price; - } - - /** - * Add a new currency rate - * - * @access public - * @param string $currency - * @param float $rate - * @return boolean|integer - */ - public function create($currency, $rate) - { - if ($this->db->table(self::TABLE)->eq('currency', $currency)->exists()) { - return $this->update($currency, $rate); - } - - return $this->db->table(self::TABLE)->insert(array('currency' => $currency, 'rate' => $rate)); - } - - /** - * Update a currency rate - * - * @access public - * @param string $currency - * @param float $rate - * @return boolean - */ - public function update($currency, $rate) - { - return $this->db->table(self::TABLE)->eq('currency', $currency)->update(array('rate' => $rate)); - } -} diff --git a/sources/app/Model/CustomFilterModel.php b/sources/app/Model/CustomFilterModel.php deleted file mode 100644 index a4c23b5..0000000 --- a/sources/app/Model/CustomFilterModel.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Custom Filter model - * - * @package Kanboard\Model - * @author Timo Litzbarski - */ -class CustomFilterModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'custom_filters'; - - /** - * Return the list of all allowed custom filters for a user and project - * - * @access public - * @param integer $project_id Project id - * @param integer $user_id User id - * @return array - */ - public function getAll($project_id, $user_id) - { - return $this->db - ->table(self::TABLE) - ->columns( - UserModel::TABLE.'.name as owner_name', - UserModel::TABLE.'.username as owner_username', - self::TABLE.'.id', - self::TABLE.'.user_id', - self::TABLE.'.project_id', - self::TABLE.'.filter', - self::TABLE.'.name', - self::TABLE.'.is_shared', - self::TABLE.'.append' - ) - ->asc(self::TABLE.'.name') - ->join(UserModel::TABLE, 'id', 'user_id') - ->beginOr() - ->eq('is_shared', 1) - ->eq('user_id', $user_id) - ->closeOr() - ->eq('project_id', $project_id) - ->findAll(); - } - - /** - * Get custom filter by id - * - * @access private - * @param integer $filter_id - * @return array - */ - public function getById($filter_id) - { - return $this->db->table(self::TABLE)->eq('id', $filter_id)->findOne(); - } - - /** - * Create a custom filter - * - * @access public - * @param array $values Form values - * @return bool|integer - */ - public function create(array $values) - { - return $this->db->table(self::TABLE)->persist($values); - } - - /** - * Update a custom filter - * - * @access public - * @param array $values Form values - * @return bool - */ - public function update(array $values) - { - return $this->db->table(self::TABLE) - ->eq('id', $values['id']) - ->update($values); - } - - /** - * Remove a custom filter - * - * @access public - * @param integer $filter_id - * @return bool - */ - public function remove($filter_id) - { - return $this->db->table(self::TABLE)->eq('id', $filter_id)->remove(); - } -} diff --git a/sources/app/Model/FileModel.php b/sources/app/Model/FileModel.php deleted file mode 100644 index 8cdea9a..0000000 --- a/sources/app/Model/FileModel.php +++ /dev/null @@ -1,378 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Exception; -use Kanboard\Core\Base; -use Kanboard\Core\Thumbnail; -use Kanboard\Event\FileEvent; -use Kanboard\Core\ObjectStorage\ObjectStorageException; - -/** - * Base File Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -abstract class FileModel extends Base -{ - /** - * Get the table - * - * @abstract - * @access protected - * @return string - */ - abstract protected function getTable(); - - /** - * Define the foreign key - * - * @abstract - * @access protected - * @return string - */ - abstract protected function getForeignKey(); - - /** - * Get the path prefix - * - * @abstract - * @access protected - * @return string - */ - abstract protected function getPathPrefix(); - - /** - * Get event name - * - * @abstract - * @access protected - * @return string - */ - abstract protected function getEventName(); - - /** - * Get PicoDb query to get all files - * - * @access protected - * @return \PicoDb\Table - */ - protected function getQuery() - { - return $this->db - ->table($this->getTable()) - ->columns( - $this->getTable().'.id', - $this->getTable().'.name', - $this->getTable().'.path', - $this->getTable().'.is_image', - $this->getTable().'.'.$this->getForeignKey(), - $this->getTable().'.date', - $this->getTable().'.user_id', - $this->getTable().'.size', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name as user_name' - ) - ->join(UserModel::TABLE, 'id', 'user_id') - ->asc($this->getTable().'.name'); - } - - /** - * Get a file by the id - * - * @access public - * @param integer $file_id File id - * @return array - */ - public function getById($file_id) - { - return $this->db->table($this->getTable())->eq('id', $file_id)->findOne(); - } - - /** - * Get all files - * - * @access public - * @param integer $id - * @return array - */ - public function getAll($id) - { - return $this->getQuery()->eq($this->getForeignKey(), $id)->findAll(); - } - - /** - * Get all images - * - * @access public - * @param integer $id - * @return array - */ - public function getAllImages($id) - { - return $this->getQuery()->eq($this->getForeignKey(), $id)->eq('is_image', 1)->findAll(); - } - - /** - * Get all files without images - * - * @access public - * @param integer $id - * @return array - */ - public function getAllDocuments($id) - { - return $this->getQuery()->eq($this->getForeignKey(), $id)->eq('is_image', 0)->findAll(); - } - - /** - * Create a file entry in the database - * - * @access public - * @param integer $id Foreign key - * @param string $name Filename - * @param string $path Path on the disk - * @param integer $size File size - * @return bool|integer - */ - public function create($id, $name, $path, $size) - { - $values = array( - $this->getForeignKey() => $id, - 'name' => substr($name, 0, 255), - 'path' => $path, - 'is_image' => $this->isImage($name) ? 1 : 0, - 'size' => $size, - 'user_id' => $this->userSession->getId() ?: 0, - 'date' => time(), - ); - - $result = $this->db->table($this->getTable())->insert($values); - - if ($result) { - $file_id = (int) $this->db->getLastId(); - $event = new FileEvent($values + array('file_id' => $file_id)); - $this->dispatcher->dispatch($this->getEventName(), $event); - return $file_id; - } - - return false; - } - - /** - * Remove all files - * - * @access public - * @param integer $id - * @return bool - */ - public function removeAll($id) - { - $file_ids = $this->db->table($this->getTable())->eq($this->getForeignKey(), $id)->asc('id')->findAllByColumn('id'); - $results = array(); - - foreach ($file_ids as $file_id) { - $results[] = $this->remove($file_id); - } - - return ! in_array(false, $results, true); - } - - /** - * Remove a file - * - * @access public - * @param integer $file_id File id - * @return bool - */ - public function remove($file_id) - { - try { - $file = $this->getById($file_id); - $this->objectStorage->remove($file['path']); - - if ($file['is_image'] == 1) { - $this->objectStorage->remove($this->getThumbnailPath($file['path'])); - } - - return $this->db->table($this->getTable())->eq('id', $file['id'])->remove(); - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - return false; - } - } - - /** - * Check if a filename is an image (file types that can be shown as thumbnail) - * - * @access public - * @param string $filename Filename - * @return bool - */ - public function isImage($filename) - { - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - - switch ($extension) { - case 'jpeg': - case 'jpg': - case 'png': - case 'gif': - return true; - } - - return false; - } - - /** - * Generate the path for a thumbnails - * - * @access public - * @param string $key Storage key - * @return string - */ - public function getThumbnailPath($key) - { - return 'thumbnails'.DIRECTORY_SEPARATOR.$key; - } - - /** - * Generate the path for a new filename - * - * @access public - * @param integer $id Foreign key - * @param string $filename Filename - * @return string - */ - public function generatePath($id, $filename) - { - return $this->getPathPrefix().DIRECTORY_SEPARATOR.$id.DIRECTORY_SEPARATOR.hash('sha1', $filename.time()); - } - - /** - * Upload multiple files - * - * @access public - * @param integer $id - * @param array $files - * @return bool - */ - public function uploadFiles($id, array $files) - { - try { - if (empty($files)) { - return false; - } - - foreach (array_keys($files['error']) as $key) { - $file = array( - 'name' => $files['name'][$key], - 'tmp_name' => $files['tmp_name'][$key], - 'size' => $files['size'][$key], - 'error' => $files['error'][$key], - ); - - $this->uploadFile($id, $file); - } - - return true; - } catch (Exception $e) { - $this->logger->error($e->getMessage()); - return false; - } - } - - /** - * Upload a file - * - * @access public - * @param integer $id - * @param array $file - * @throws Exception - */ - public function uploadFile($id, array $file) - { - if ($file['error'] == UPLOAD_ERR_OK && $file['size'] > 0) { - $destination_filename = $this->generatePath($id, $file['name']); - - if ($this->isImage($file['name'])) { - $this->generateThumbnailFromFile($file['tmp_name'], $destination_filename); - } - - $this->objectStorage->moveUploadedFile($file['tmp_name'], $destination_filename); - $this->create($id, $file['name'], $destination_filename, $file['size']); - } else { - throw new Exception('File not uploaded: '.var_export($file['error'], true)); - } - } - - /** - * Handle file upload (base64 encoded content) - * - * @access public - * @param integer $id - * @param string $original_filename - * @param string $blob - * @return bool|integer - */ - public function uploadContent($id, $original_filename, $blob) - { - try { - $data = base64_decode($blob); - - if (empty($data)) { - return false; - } - - $destination_filename = $this->generatePath($id, $original_filename); - $this->objectStorage->put($destination_filename, $data); - - if ($this->isImage($original_filename)) { - $this->generateThumbnailFromData($destination_filename, $data); - } - - return $this->create( - $id, - $original_filename, - $destination_filename, - strlen($data) - ); - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - return false; - } - } - - /** - * Generate thumbnail from a blob - * - * @access public - * @param string $destination_filename - * @param string $data - */ - public function generateThumbnailFromData($destination_filename, &$data) - { - $blob = Thumbnail::createFromString($data) - ->resize() - ->toString(); - - $this->objectStorage->put($this->getThumbnailPath($destination_filename), $blob); - } - - /** - * Generate thumbnail from a local file - * - * @access public - * @param string $uploaded_filename - * @param string $destination_filename - */ - public function generateThumbnailFromFile($uploaded_filename, $destination_filename) - { - $blob = Thumbnail::createFromFile($uploaded_filename) - ->resize() - ->toString(); - - $this->objectStorage->put($this->getThumbnailPath($destination_filename), $blob); - } -} diff --git a/sources/app/Model/GroupMemberModel.php b/sources/app/Model/GroupMemberModel.php deleted file mode 100644 index a207778..0000000 --- a/sources/app/Model/GroupMemberModel.php +++ /dev/null @@ -1,130 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Group Member Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class GroupMemberModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'group_has_users'; - - /** - * Get query to fetch all users - * - * @access public - * @param integer $group_id - * @return \PicoDb\Table - */ - public function getQuery($group_id) - { - return $this->db->table(self::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id') - ->eq('group_id', $group_id); - } - - /** - * Get all users - * - * @access public - * @param integer $group_id - * @return array - */ - public function getMembers($group_id) - { - return $this->getQuery($group_id)->findAll(); - } - - /** - * Get all not members - * - * @access public - * @param integer $group_id - * @return array - */ - public function getNotMembers($group_id) - { - $subquery = $this->db->table(self::TABLE) - ->columns('user_id') - ->eq('group_id', $group_id); - - return $this->db->table(UserModel::TABLE) - ->notInSubquery('id', $subquery) - ->findAll(); - } - - /** - * Add user to a group - * - * @access public - * @param integer $group_id - * @param integer $user_id - * @return boolean - */ - public function addUser($group_id, $user_id) - { - return $this->db->table(self::TABLE)->insert(array( - 'group_id' => $group_id, - 'user_id' => $user_id, - )); - } - - /** - * Remove user from a group - * - * @access public - * @param integer $group_id - * @param integer $user_id - * @return boolean - */ - public function removeUser($group_id, $user_id) - { - return $this->db->table(self::TABLE) - ->eq('group_id', $group_id) - ->eq('user_id', $user_id) - ->remove(); - } - - /** - * Check if a user is member - * - * @access public - * @param integer $group_id - * @param integer $user_id - * @return boolean - */ - public function isMember($group_id, $user_id) - { - return $this->db->table(self::TABLE) - ->eq('group_id', $group_id) - ->eq('user_id', $user_id) - ->exists(); - } - - /** - * Get all groups for a given user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getGroups($user_id) - { - return $this->db->table(self::TABLE) - ->columns(GroupModel::TABLE.'.id', GroupModel::TABLE.'.external_id', GroupModel::TABLE.'.name') - ->join(GroupModel::TABLE, 'id', 'group_id') - ->eq(self::TABLE.'.user_id', $user_id) - ->asc(GroupModel::TABLE.'.name') - ->findAll(); - } -} diff --git a/sources/app/Model/GroupModel.php b/sources/app/Model/GroupModel.php deleted file mode 100644 index 0a97557..0000000 --- a/sources/app/Model/GroupModel.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Group Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class GroupModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'groups'; - - /** - * Get query to fetch all groups - * - * @access public - * @return \PicoDb\Table - */ - public function getQuery() - { - return $this->db->table(self::TABLE); - } - - /** - * Get a specific group by id - * - * @access public - * @param integer $group_id - * @return array - */ - public function getById($group_id) - { - return $this->getQuery()->eq('id', $group_id)->findOne(); - } - - /** - * Get a specific group by external id - * - * @access public - * @param integer $external_id - * @return array - */ - public function getByExternalId($external_id) - { - return $this->getQuery()->eq('external_id', $external_id)->findOne(); - } - - /** - * Get all groups - * - * @access public - * @return array - */ - public function getAll() - { - return $this->getQuery()->asc('name')->findAll(); - } - - /** - * Search groups by name - * - * @access public - * @param string $input - * @return array - */ - public function search($input) - { - return $this->db->table(self::TABLE)->ilike('name', '%'.$input.'%')->asc('name')->findAll(); - } - - /** - * Remove a group - * - * @access public - * @param integer $group_id - * @return boolean - */ - public function remove($group_id) - { - return $this->db->table(self::TABLE)->eq('id', $group_id)->remove(); - } - - /** - * Create a new group - * - * @access public - * @param string $name - * @param string $external_id - * @return integer|boolean - */ - public function create($name, $external_id = '') - { - return $this->db->table(self::TABLE)->persist(array( - 'name' => $name, - 'external_id' => $external_id, - )); - } - - /** - * Update existing group - * - * @access public - * @param array $values - * @return boolean - */ - public function update(array $values) - { - return $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values); - } -} diff --git a/sources/app/Model/LanguageModel.php b/sources/app/Model/LanguageModel.php deleted file mode 100644 index eb6de00..0000000 --- a/sources/app/Model/LanguageModel.php +++ /dev/null @@ -1,179 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Translator; - -/** - * Class Language - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class LanguageModel extends Base -{ - /** - * Get all language codes - * - * @static - * @access public - * @return string[] - */ - public static function getCodes() - { - return array( - 'id_ID', - 'bs_BA', - 'cs_CZ', - 'da_DK', - 'de_DE', - 'en_US', - 'es_ES', - 'fr_FR', - 'el_GR', - 'it_IT', - 'hu_HU', - 'my_MY', - 'nl_NL', - 'nb_NO', - 'pl_PL', - 'pt_PT', - 'pt_BR', - 'ru_RU', - 'sr_Latn_RS', - 'fi_FI', - 'sv_SE', - 'tr_TR', - 'ko_KR', - 'zh_CN', - 'ja_JP', - 'th_TH', - ); - } - - /** - * Find language code - * - * @static - * @access public - * @param string $code - * @return string - */ - public static function findCode($code) - { - $code = str_replace('-', '_', $code); - return in_array($code, self::getCodes()) ? $code : ''; - } - - /** - * Get available languages - * - * @access public - * @param boolean $prepend Prepend a default value - * @return array - */ - public function getLanguages($prepend = false) - { - // Sorted by value - $languages = array( - 'id_ID' => 'Bahasa Indonesia', - 'bs_BA' => 'Bosanski', - 'cs_CZ' => 'Čeština', - 'da_DK' => 'Dansk', - 'de_DE' => 'Deutsch', - 'en_US' => 'English', - 'es_ES' => 'Español', - 'fr_FR' => 'Français', - 'el_GR' => 'Grec', - 'it_IT' => 'Italiano', - 'hu_HU' => 'Magyar', - 'my_MY' => 'Melayu', - 'nl_NL' => 'Nederlands', - 'nb_NO' => 'Norsk', - 'pl_PL' => 'Polski', - 'pt_PT' => 'Português', - 'pt_BR' => 'Português (Brasil)', - 'ru_RU' => 'Русский', - 'sr_Latn_RS' => 'Srpski', - 'fi_FI' => 'Suomi', - 'sv_SE' => 'Svenska', - 'tr_TR' => 'Türkçe', - 'ko_KR' => '한국어', - 'zh_CN' => '中文(简体)', - 'ja_JP' => '日本語', - 'th_TH' => 'ไทย', - ); - - if ($prepend) { - return array('' => t('Application default')) + $languages; - } - - return $languages; - } - - /** - * Get javascript language code - * - * @access public - * @return string - */ - public function getJsLanguageCode() - { - $languages = array( - 'cs_CZ' => 'cs', - 'da_DK' => 'da', - 'de_DE' => 'de', - 'en_US' => 'en', - 'es_ES' => 'es', - 'fr_FR' => 'fr', - 'it_IT' => 'it', - 'hu_HU' => 'hu', - 'nl_NL' => 'nl', - 'nb_NO' => 'nb', - 'pl_PL' => 'pl', - 'pt_PT' => 'pt', - 'pt_BR' => 'pt-br', - 'ru_RU' => 'ru', - 'sr_Latn_RS' => 'sr', - 'fi_FI' => 'fi', - 'sv_SE' => 'sv', - 'tr_TR' => 'tr', - 'ko_KR' => 'ko', - 'zh_CN' => 'zh-cn', - 'ja_JP' => 'ja', - 'th_TH' => 'th', - 'id_ID' => 'id', - 'el_GR' => 'el', - ); - - $lang = $this->getCurrentLanguage(); - - return isset($languages[$lang]) ? $languages[$lang] : 'en'; - } - - /** - * Get current language - * - * @access public - * @return string - */ - public function getCurrentLanguage() - { - if ($this->userSession->isLogged() && ! empty($this->sessionStorage->user['language'])) { - return $this->sessionStorage->user['language']; - } - - return $this->configModel->get('application_language', 'en_US'); - } - - /** - * Load translations for the current language - * - * @access public - */ - public function loadCurrentLanguage() - { - Translator::load($this->getCurrentLanguage()); - } -} diff --git a/sources/app/Model/LastLoginModel.php b/sources/app/Model/LastLoginModel.php deleted file mode 100644 index caaa4a8..0000000 --- a/sources/app/Model/LastLoginModel.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * LastLogin model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class LastLoginModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'last_logins'; - - /** - * Number of connections to keep for history - * - * @var integer - */ - const NB_LOGINS = 10; - - /** - * Create a new record - * - * @access public - * @param string $auth_type Authentication method - * @param integer $user_id User id - * @param string $ip IP Address - * @param string $user_agent User Agent - * @return boolean - */ - public function create($auth_type, $user_id, $ip, $user_agent) - { - $this->cleanup($user_id); - - return $this->db - ->table(self::TABLE) - ->insert(array( - 'auth_type' => $auth_type, - 'user_id' => $user_id, - 'ip' => $ip, - 'user_agent' => substr($user_agent, 0, 255), - 'date_creation' => time(), - )); - } - - /** - * Cleanup login history - * - * @access public - * @param integer $user_id - */ - public function cleanup($user_id) - { - $connections = $this->db - ->table(self::TABLE) - ->eq('user_id', $user_id) - ->desc('id') - ->findAllByColumn('id'); - - if (count($connections) >= self::NB_LOGINS) { - $this->db->table(self::TABLE) - ->eq('user_id', $user_id) - ->notIn('id', array_slice($connections, 0, self::NB_LOGINS - 1)) - ->remove(); - } - } - - /** - * Get the last connections for a given user - * - * @access public - * @param integer $user_id User id - * @return array - */ - public function getAll($user_id) - { - return $this->db - ->table(self::TABLE) - ->eq('user_id', $user_id) - ->desc('id') - ->columns('id', 'auth_type', 'ip', 'user_agent', 'date_creation') - ->findAll(); - } -} diff --git a/sources/app/Model/LinkModel.php b/sources/app/Model/LinkModel.php deleted file mode 100644 index b72c753..0000000 --- a/sources/app/Model/LinkModel.php +++ /dev/null @@ -1,178 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use PDO; -use Kanboard\Core\Base; - -/** - * Link model - * - * @package Kanboard\Model - * @author Olivier Maridat - * @author Frederic Guillot - */ -class LinkModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'links'; - - /** - * Get a link by id - * - * @access public - * @param integer $link_id Link id - * @return array - */ - public function getById($link_id) - { - return $this->db->table(self::TABLE)->eq('id', $link_id)->findOne(); - } - - /** - * Get a link by name - * - * @access public - * @param string $label - * @return array - */ - public function getByLabel($label) - { - return $this->db->table(self::TABLE)->eq('label', $label)->findOne(); - } - - /** - * Get the opposite link id - * - * @access public - * @param integer $link_id Link id - * @return integer - */ - public function getOppositeLinkId($link_id) - { - return $this->db->table(self::TABLE)->eq('id', $link_id)->findOneColumn('opposite_id') ?: $link_id; - } - - /** - * Get all links - * - * @access public - * @return array - */ - public function getAll() - { - return $this->db->table(self::TABLE)->findAll(); - } - - /** - * Get merged links - * - * @access public - * @return array - */ - public function getMergedList() - { - return $this->db - ->execute(' - SELECT - links.id, links.label, opposite.label as opposite_label - FROM links - LEFT JOIN links AS opposite ON opposite.id=links.opposite_id - ') - ->fetchAll(PDO::FETCH_ASSOC); - } - - /** - * Get label list - * - * @access public - * @param integer $exclude_id Exclude this link - * @param boolean $prepend Prepend default value - * @return array - */ - public function getList($exclude_id = 0, $prepend = true) - { - $labels = $this->db->hashtable(self::TABLE)->neq('id', $exclude_id)->asc('id')->getAll('id', 'label'); - - foreach ($labels as &$value) { - $value = t($value); - } - - return $prepend ? array('') + $labels : $labels; - } - - /** - * Create a new link label - * - * @access public - * @param string $label - * @param string $opposite_label - * @return boolean|integer - */ - public function create($label, $opposite_label = '') - { - $this->db->startTransaction(); - - if (! $this->db->table(self::TABLE)->insert(array('label' => $label))) { - $this->db->cancelTransaction(); - return false; - } - - $label_id = $this->db->getLastId(); - - if (! empty($opposite_label)) { - $this->db - ->table(self::TABLE) - ->insert(array( - 'label' => $opposite_label, - 'opposite_id' => $label_id, - )); - - $this->db - ->table(self::TABLE) - ->eq('id', $label_id) - ->update(array( - 'opposite_id' => $this->db->getLastId() - )); - } - - $this->db->closeTransaction(); - - return (int) $label_id; - } - - /** - * Update a link - * - * @access public - * @param array $values - * @return boolean - */ - public function update(array $values) - { - return $this->db - ->table(self::TABLE) - ->eq('id', $values['id']) - ->update(array( - 'label' => $values['label'], - 'opposite_id' => $values['opposite_id'], - )); - } - - /** - * Remove a link a the relation to its opposite - * - * @access public - * @param integer $link_id - * @return boolean - */ - public function remove($link_id) - { - $this->db->table(self::TABLE)->eq('opposite_id', $link_id)->update(array('opposite_id' => 0)); - return $this->db->table(self::TABLE)->eq('id', $link_id)->remove(); - } -} diff --git a/sources/app/Model/MetadataModel.php b/sources/app/Model/MetadataModel.php deleted file mode 100644 index 6177e5f..0000000 --- a/sources/app/Model/MetadataModel.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Metadata - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -abstract class MetadataModel extends Base -{ - /** - * Get the table - * - * @abstract - * @access protected - * @return string - */ - abstract protected function getTable(); - - /** - * Define the entity key - * - * @abstract - * @access protected - * @return string - */ - abstract protected function getEntityKey(); - - /** - * Get all metadata for the entity - * - * @access public - * @param integer $entity_id - * @return array - */ - public function getAll($entity_id) - { - return $this->db - ->hashtable($this->getTable()) - ->eq($this->getEntityKey(), $entity_id) - ->asc('name') - ->getAll('name', 'value'); - } - - /** - * Get a metadata for the given entity - * - * @access public - * @param integer $entity_id - * @param string $name - * @param string $default - * @return mixed - */ - public function get($entity_id, $name, $default = '') - { - return $this->db - ->table($this->getTable()) - ->eq($this->getEntityKey(), $entity_id) - ->eq('name', $name) - ->findOneColumn('value') ?: $default; - } - - /** - * Return true if a metadata exists - * - * @access public - * @param integer $entity_id - * @param string $name - * @return boolean - */ - public function exists($entity_id, $name) - { - return $this->db - ->table($this->getTable()) - ->eq($this->getEntityKey(), $entity_id) - ->eq('name', $name) - ->exists(); - } - - /** - * Update or insert new metadata - * - * @access public - * @param integer $entity_id - * @param array $values - * @return boolean - */ - public function save($entity_id, array $values) - { - $results = array(); - $user_id = $this->userSession->getId(); - $timestamp = time(); - - $this->db->startTransaction(); - - foreach ($values as $key => $value) { - if ($this->exists($entity_id, $key)) { - $results[] = $this->db->table($this->getTable()) - ->eq($this->getEntityKey(), $entity_id) - ->eq('name', $key)->update(array( - 'value' => $value, - 'changed_on' => $timestamp, - 'changed_by' => $user_id, - )); - } else { - $results[] = $this->db->table($this->getTable())->insert(array( - 'name' => $key, - 'value' => $value, - $this->getEntityKey() => $entity_id, - 'changed_on' => $timestamp, - 'changed_by' => $user_id, - )); - } - } - - $this->db->closeTransaction(); - return ! in_array(false, $results, true); - } - - /** - * Remove a metadata - * - * @access public - * @param integer $entity_id - * @param string $name - * @return bool - */ - public function remove($entity_id, $name) - { - return $this->db->table($this->getTable()) - ->eq($this->getEntityKey(), $entity_id) - ->eq('name', $name) - ->remove(); - } -} diff --git a/sources/app/Model/NotificationModel.php b/sources/app/Model/NotificationModel.php deleted file mode 100644 index 4d697b5..0000000 --- a/sources/app/Model/NotificationModel.php +++ /dev/null @@ -1,173 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Notification - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class NotificationModel extends Base -{ - /** - * Get the event title with author - * - * @access public - * @param string $event_author - * @param string $event_name - * @param array $event_data - * @return string - */ - public function getTitleWithAuthor($event_author, $event_name, array $event_data) - { - switch ($event_name) { - case TaskModel::EVENT_ASSIGNEE_CHANGE: - $assignee = $event_data['task']['assignee_name'] ?: $event_data['task']['assignee_username']; - - if (! empty($assignee)) { - return e('%s change the assignee of the task #%d to %s', $event_author, $event_data['task']['id'], $assignee); - } - - return e('%s remove the assignee of the task %s', $event_author, e('#%d', $event_data['task']['id'])); - case TaskModel::EVENT_UPDATE: - return e('%s updated the task #%d', $event_author, $event_data['task']['id']); - case TaskModel::EVENT_CREATE: - return e('%s created the task #%d', $event_author, $event_data['task']['id']); - case TaskModel::EVENT_CLOSE: - return e('%s closed the task #%d', $event_author, $event_data['task']['id']); - case TaskModel::EVENT_OPEN: - return e('%s open the task #%d', $event_author, $event_data['task']['id']); - case TaskModel::EVENT_MOVE_COLUMN: - return e( - '%s moved the task #%d to the column "%s"', - $event_author, - $event_data['task']['id'], - $event_data['task']['column_title'] - ); - case TaskModel::EVENT_MOVE_POSITION: - return e( - '%s moved the task #%d to the position %d in the column "%s"', - $event_author, - $event_data['task']['id'], - $event_data['task']['position'], - $event_data['task']['column_title'] - ); - case TaskModel::EVENT_MOVE_SWIMLANE: - if ($event_data['task']['swimlane_id'] == 0) { - return e('%s moved the task #%d to the first swimlane', $event_author, $event_data['task']['id']); - } - - return e( - '%s moved the task #%d to the swimlane "%s"', - $event_author, - $event_data['task']['id'], - $event_data['task']['swimlane_name'] - ); - case SubtaskModel::EVENT_UPDATE: - return e('%s updated a subtask for the task #%d', $event_author, $event_data['task']['id']); - case SubtaskModel::EVENT_CREATE: - return e('%s created a subtask for the task #%d', $event_author, $event_data['task']['id']); - case CommentModel::EVENT_UPDATE: - return e('%s updated a comment on the task #%d', $event_author, $event_data['task']['id']); - case CommentModel::EVENT_CREATE: - return e('%s commented on the task #%d', $event_author, $event_data['task']['id']); - case TaskFileModel::EVENT_CREATE: - return e('%s attached a file to the task #%d', $event_author, $event_data['task']['id']); - case TaskModel::EVENT_USER_MENTION: - return e('%s mentioned you in the task #%d', $event_author, $event_data['task']['id']); - case CommentModel::EVENT_USER_MENTION: - return e('%s mentioned you in a comment on the task #%d', $event_author, $event_data['task']['id']); - default: - return e('Notification'); - } - } - - /** - * Get the event title without author - * - * @access public - * @param string $event_name - * @param array $event_data - * @return string - */ - public function getTitleWithoutAuthor($event_name, array $event_data) - { - switch ($event_name) { - case TaskFileModel::EVENT_CREATE: - return e('New attachment on task #%d: %s', $event_data['file']['task_id'], $event_data['file']['name']); - case CommentModel::EVENT_CREATE: - return e('New comment on task #%d', $event_data['comment']['task_id']); - case CommentModel::EVENT_UPDATE: - return e('Comment updated on task #%d', $event_data['comment']['task_id']); - case SubtaskModel::EVENT_CREATE: - return e('New subtask on task #%d', $event_data['subtask']['task_id']); - case SubtaskModel::EVENT_UPDATE: - return e('Subtask updated on task #%d', $event_data['subtask']['task_id']); - case TaskModel::EVENT_CREATE: - return e('New task #%d: %s', $event_data['task']['id'], $event_data['task']['title']); - case TaskModel::EVENT_UPDATE: - return e('Task updated #%d', $event_data['task']['id']); - case TaskModel::EVENT_CLOSE: - return e('Task #%d closed', $event_data['task']['id']); - case TaskModel::EVENT_OPEN: - return e('Task #%d opened', $event_data['task']['id']); - case TaskModel::EVENT_MOVE_COLUMN: - return e('Column changed for task #%d', $event_data['task']['id']); - case TaskModel::EVENT_MOVE_POSITION: - return e('New position for task #%d', $event_data['task']['id']); - case TaskModel::EVENT_MOVE_SWIMLANE: - return e('Swimlane changed for task #%d', $event_data['task']['id']); - case TaskModel::EVENT_ASSIGNEE_CHANGE: - return e('Assignee changed on task #%d', $event_data['task']['id']); - case TaskModel::EVENT_OVERDUE: - $nb = count($event_data['tasks']); - return $nb > 1 ? e('%d overdue tasks', $nb) : e('Task #%d is overdue', $event_data['tasks'][0]['id']); - case TaskModel::EVENT_USER_MENTION: - return e('You were mentioned in the task #%d', $event_data['task']['id']); - case CommentModel::EVENT_USER_MENTION: - return e('You were mentioned in a comment on the task #%d', $event_data['task']['id']); - default: - return e('Notification'); - } - } - - /** - * Get task id from event - * - * @access public - * @param string $event_name - * @param array $event_data - * @return integer - */ - public function getTaskIdFromEvent($event_name, array $event_data) - { - switch ($event_name) { - case TaskFileModel::EVENT_CREATE: - return $event_data['file']['task_id']; - case CommentModel::EVENT_CREATE: - case CommentModel::EVENT_UPDATE: - return $event_data['comment']['task_id']; - case SubtaskModel::EVENT_CREATE: - case SubtaskModel::EVENT_UPDATE: - return $event_data['subtask']['task_id']; - case TaskModel::EVENT_CREATE: - case TaskModel::EVENT_UPDATE: - case TaskModel::EVENT_CLOSE: - case TaskModel::EVENT_OPEN: - case TaskModel::EVENT_MOVE_COLUMN: - case TaskModel::EVENT_MOVE_POSITION: - case TaskModel::EVENT_MOVE_SWIMLANE: - case TaskModel::EVENT_ASSIGNEE_CHANGE: - case CommentModel::EVENT_USER_MENTION: - case TaskModel::EVENT_USER_MENTION: - return $event_data['task']['id']; - case TaskModel::EVENT_OVERDUE: - return $event_data['tasks'][0]['id']; - default: - return 0; - } - } -} diff --git a/sources/app/Model/NotificationTypeModel.php b/sources/app/Model/NotificationTypeModel.php deleted file mode 100644 index 432832e..0000000 --- a/sources/app/Model/NotificationTypeModel.php +++ /dev/null @@ -1,128 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Pimple\Container; -use Kanboard\Core\Base; - -/** - * Notification Type - * - * @package model - * @author Frederic Guillot - */ -abstract class NotificationTypeModel extends Base -{ - /** - * Container - * - * @access private - * @var \Pimple\Container - */ - private $classes; - - /** - * Notification type labels - * - * @access private - * @var array - */ - private $labels = array(); - - /** - * Hidden notification types - * - * @access private - * @var array - */ - private $hiddens = array(); - - /** - * Constructor - * - * @access public - * @param \Pimple\Container $container - */ - public function __construct(Container $container) - { - parent::__construct($container); - $this->classes = new Container; - } - - /** - * Add a new notification type - * - * @access public - * @param string $type - * @param string $label - * @param string $class - * @param boolean $hidden - * @return NotificationTypeModel - */ - public function setType($type, $label, $class, $hidden = false) - { - $container = $this->container; - - if ($hidden) { - $this->hiddens[] = $type; - } else { - $this->labels[$type] = $label; - } - - $this->classes[$type] = function () use ($class, $container) { - return new $class($container); - }; - - return $this; - } - - /** - * Get mail notification type instance - * - * @access public - * @param string $type - * @return \Kanboard\Core\Notification\NotificationInterface - */ - public function getType($type) - { - return $this->classes[$type]; - } - - /** - * Get all notification types with labels - * - * @access public - * @return array - */ - public function getTypes() - { - return $this->labels; - } - - /** - * Get all hidden notification types - * - * @access public - * @return array - */ - public function getHiddenTypes() - { - return $this->hiddens; - } - - /** - * Keep only loaded notification types - * - * @access public - * @param string[] $types - * @return array - */ - public function filterTypes(array $types) - { - $classes = $this->classes; - - return array_filter($types, function ($type) use ($classes) { - return isset($classes[$type]); - }); - } -} diff --git a/sources/app/Model/PasswordResetModel.php b/sources/app/Model/PasswordResetModel.php deleted file mode 100644 index d7c7496..0000000 --- a/sources/app/Model/PasswordResetModel.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Password Reset Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class PasswordResetModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'password_reset'; - - /** - * Token duration (30 minutes) - * - * @var integer - */ - const DURATION = 1800; - - /** - * Get all tokens - * - * @access public - * @param integer $user_id - * @return array - */ - public function getAll($user_id) - { - return $this->db->table(self::TABLE)->eq('user_id', $user_id)->desc('date_creation')->limit(100)->findAll(); - } - - /** - * Generate a new reset token for a user - * - * @access public - * @param string $username - * @param integer $expiration - * @return boolean|string - */ - public function create($username, $expiration = 0) - { - $user_id = $this->db->table(UserModel::TABLE)->eq('username', $username)->neq('email', '')->notNull('email')->findOneColumn('id'); - - if (! $user_id) { - return false; - } - - $token = $this->token->getToken(); - - $result = $this->db->table(self::TABLE)->insert(array( - 'token' => $token, - 'user_id' => $user_id, - 'date_expiration' => $expiration ?: time() + self::DURATION, - 'date_creation' => time(), - 'ip' => $this->request->getIpAddress(), - 'user_agent' => $this->request->getUserAgent(), - 'is_active' => 1, - )); - - return $result ? $token : false; - } - - /** - * Get user id from the token - * - * @access public - * @param string $token - * @return integer - */ - public function getUserIdByToken($token) - { - return $this->db->table(self::TABLE)->eq('token', $token)->eq('is_active', 1)->gte('date_expiration', time())->findOneColumn('user_id'); - } - - /** - * Disable all tokens for a user - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function disable($user_id) - { - return $this->db->table(self::TABLE)->eq('user_id', $user_id)->update(array('is_active' => 0)); - } -} diff --git a/sources/app/Model/ProjectActivityModel.php b/sources/app/Model/ProjectActivityModel.php deleted file mode 100644 index 380ea12..0000000 --- a/sources/app/Model/ProjectActivityModel.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use PicoDb\Table; - -/** - * Project activity model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectActivityModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'project_activities'; - - /** - * Maximum number of events - * - * @var integer - */ - const MAX_EVENTS = 1000; - - /** - * Add a new event for the project - * - * @access public - * @param integer $project_id Project id - * @param integer $task_id Task id - * @param integer $creator_id User id - * @param string $event_name Event name - * @param array $data Event data (will be serialized) - * @return boolean - */ - public function createEvent($project_id, $task_id, $creator_id, $event_name, array $data) - { - $values = array( - 'project_id' => $project_id, - 'task_id' => $task_id, - 'creator_id' => $creator_id, - 'event_name' => $event_name, - 'date_creation' => time(), - 'data' => json_encode($data), - ); - - $this->cleanup(self::MAX_EVENTS - 1); - return $this->db->table(self::TABLE)->insert($values); - } - - /** - * Get query - * - * @access public - * @return Table - */ - public function getQuery() - { - return $this - ->db - ->table(ProjectActivityModel::TABLE) - ->columns( - ProjectActivityModel::TABLE.'.*', - 'uc.username AS author_username', - 'uc.name AS author_name', - 'uc.email', - 'uc.avatar_path' - ) - ->join(TaskModel::TABLE, 'id', 'task_id') - ->join(ProjectModel::TABLE, 'id', 'project_id') - ->left(UserModel::TABLE, 'uc', 'id', ProjectActivityModel::TABLE, 'creator_id'); - } - - /** - * Remove old event entries to avoid large table - * - * @access public - * @param integer $max Maximum number of items to keep in the table - */ - public function cleanup($max) - { - $total = $this->db->table(self::TABLE)->count(); - - if ($total > $max) { - $ids = $this->db->table(self::TABLE)->asc('id')->limit($total - $max)->findAllByColumn('id'); - $this->db->table(self::TABLE)->in('id', $ids)->remove(); - } - } -} diff --git a/sources/app/Model/ProjectDailyColumnStatsModel.php b/sources/app/Model/ProjectDailyColumnStatsModel.php deleted file mode 100644 index a0f14cf..0000000 --- a/sources/app/Model/ProjectDailyColumnStatsModel.php +++ /dev/null @@ -1,254 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Project Daily Column Stats - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectDailyColumnStatsModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'project_daily_column_stats'; - - /** - * Update daily totals for the project and for each column - * - * "total" is the number open of tasks in the column - * "score" is the sum of tasks score in the column - * - * @access public - * @param integer $project_id Project id - * @param string $date Record date (YYYY-MM-DD) - * @return boolean - */ - public function updateTotals($project_id, $date) - { - $this->db->startTransaction(); - $this->db->table(self::TABLE)->eq('project_id', $project_id)->eq('day', $date)->remove(); - - foreach ($this->getStatsByColumns($project_id) as $column_id => $column) { - $this->db->table(self::TABLE)->insert(array( - 'day' => $date, - 'project_id' => $project_id, - 'column_id' => $column_id, - 'total' => $column['total'], - 'score' => $column['score'], - )); - } - - $this->db->closeTransaction(); - - return true; - } - - /** - * Count the number of recorded days for the data range - * - * @access public - * @param integer $project_id Project id - * @param string $from Start date (ISO format YYYY-MM-DD) - * @param string $to End date - * @return integer - */ - public function countDays($project_id, $from, $to) - { - return $this->db->table(self::TABLE) - ->eq('project_id', $project_id) - ->gte('day', $from) - ->lte('day', $to) - ->findOneColumn('COUNT(DISTINCT day)'); - } - - /** - * Get aggregated metrics for the project within a data range - * - * [ - * ['Date', 'Column1', 'Column2'], - * ['2014-11-16', 2, 5], - * ['2014-11-17', 20, 15], - * ] - * - * @access public - * @param integer $project_id Project id - * @param string $from Start date (ISO format YYYY-MM-DD) - * @param string $to End date - * @param string $field Column to aggregate - * @return array - */ - public function getAggregatedMetrics($project_id, $from, $to, $field = 'total') - { - $columns = $this->columnModel->getList($project_id); - $metrics = $this->getMetrics($project_id, $from, $to); - return $this->buildAggregate($metrics, $columns, $field); - } - - /** - * Fetch metrics - * - * @access public - * @param integer $project_id Project id - * @param string $from Start date (ISO format YYYY-MM-DD) - * @param string $to End date - * @return array - */ - public function getMetrics($project_id, $from, $to) - { - return $this->db->table(self::TABLE) - ->eq('project_id', $project_id) - ->gte('day', $from) - ->lte('day', $to) - ->asc(self::TABLE.'.day') - ->findAll(); - } - - /** - * Build aggregate - * - * @access private - * @param array $metrics - * @param array $columns - * @param string $field - * @return array - */ - private function buildAggregate(array &$metrics, array &$columns, $field) - { - $column_ids = array_keys($columns); - $days = array_unique(array_column($metrics, 'day')); - $rows = array(array_merge(array(e('Date')), array_values($columns))); - - foreach ($days as $day) { - $rows[] = $this->buildRowAggregate($metrics, $column_ids, $day, $field); - } - - return $rows; - } - - /** - * Build one row of the aggregate - * - * @access private - * @param array $metrics - * @param array $column_ids - * @param string $day - * @param string $field - * @return array - */ - private function buildRowAggregate(array &$metrics, array &$column_ids, $day, $field) - { - $row = array($day); - - foreach ($column_ids as $column_id) { - $row[] = $this->findValueInMetrics($metrics, $day, $column_id, $field); - } - - return $row; - } - - /** - * Find the value in the metrics - * - * @access private - * @param array $metrics - * @param string $day - * @param string $column_id - * @param string $field - * @return integer - */ - private function findValueInMetrics(array &$metrics, $day, $column_id, $field) - { - foreach ($metrics as $metric) { - if ($metric['day'] === $day && $metric['column_id'] == $column_id) { - return (int) $metric[$field]; - } - } - - return 0; - } - - /** - * Get number of tasks and score by columns - * - * @access private - * @param integer $project_id - * @return array - */ - private function getStatsByColumns($project_id) - { - $totals = $this->getTotalByColumns($project_id); - $scores = $this->getScoreByColumns($project_id); - $columns = array(); - - foreach ($totals as $column_id => $total) { - $columns[$column_id] = array('total' => $total, 'score' => 0); - } - - foreach ($scores as $column_id => $score) { - $columns[$column_id]['score'] = (int) $score; - } - - return $columns; - } - - /** - * Get number of tasks and score by columns - * - * @access private - * @param integer $project_id - * @return array - */ - private function getScoreByColumns($project_id) - { - $stats = $this->db->table(TaskModel::TABLE) - ->columns('column_id', 'SUM(score) AS score') - ->eq('project_id', $project_id) - ->eq('is_active', TaskModel::STATUS_OPEN) - ->notNull('score') - ->groupBy('column_id') - ->findAll(); - - return array_column($stats, 'score', 'column_id'); - } - - /** - * Get number of tasks and score by columns - * - * @access private - * @param integer $project_id - * @return array - */ - private function getTotalByColumns($project_id) - { - $stats = $this->db->table(TaskModel::TABLE) - ->columns('column_id', 'COUNT(*) AS total') - ->eq('project_id', $project_id) - ->in('is_active', $this->getTaskStatusConfig()) - ->groupBy('column_id') - ->findAll(); - - return array_column($stats, 'total', 'column_id'); - } - - /** - * Get task status to use for total calculation - * - * @access private - * @return array - */ - private function getTaskStatusConfig() - { - if ($this->configModel->get('cfd_include_closed_tasks') == 1) { - return array(TaskModel::STATUS_OPEN, TaskModel::STATUS_CLOSED); - } - - return array(TaskModel::STATUS_OPEN); - } -} diff --git a/sources/app/Model/ProjectDailyStatsModel.php b/sources/app/Model/ProjectDailyStatsModel.php deleted file mode 100644 index 0754d26..0000000 --- a/sources/app/Model/ProjectDailyStatsModel.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Project Daily Stats - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectDailyStatsModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'project_daily_stats'; - - /** - * Update daily totals for the project - * - * @access public - * @param integer $project_id Project id - * @param string $date Record date (YYYY-MM-DD) - * @return boolean - */ - public function updateTotals($project_id, $date) - { - $this->db->startTransaction(); - - $lead_cycle_time = $this->averageLeadCycleTimeAnalytic->build($project_id); - - $this->db->table(self::TABLE)->eq('day', $date)->eq('project_id', $project_id)->remove(); - - $this->db->table(self::TABLE)->insert(array( - 'day' => $date, - 'project_id' => $project_id, - 'avg_lead_time' => $lead_cycle_time['avg_lead_time'], - 'avg_cycle_time' => $lead_cycle_time['avg_cycle_time'], - )); - - $this->db->closeTransaction(); - - return true; - } - - /** - * Get raw metrics for the project within a data range - * - * @access public - * @param integer $project_id Project id - * @param string $from Start date (ISO format YYYY-MM-DD) - * @param string $to End date - * @return array - */ - public function getRawMetrics($project_id, $from, $to) - { - $metrics = $this->db->table(self::TABLE) - ->columns('day', 'avg_lead_time', 'avg_cycle_time') - ->eq('project_id', $project_id) - ->gte('day', $from) - ->lte('day', $to) - ->asc('day') - ->findAll(); - - foreach ($metrics as &$metric) { - $metric['avg_lead_time'] = (int) $metric['avg_lead_time']; - $metric['avg_cycle_time'] = (int) $metric['avg_cycle_time']; - } - - return $metrics; - } -} diff --git a/sources/app/Model/ProjectDuplicationModel.php b/sources/app/Model/ProjectDuplicationModel.php deleted file mode 100644 index 94b83c8..0000000 --- a/sources/app/Model/ProjectDuplicationModel.php +++ /dev/null @@ -1,181 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Security\Role; - -/** - * Project Duplication - * - * @package Kanboard\Model - * @author Frederic Guillot - * @author Antonio Rabelo - */ -class ProjectDuplicationModel extends Base -{ - /** - * Get list of optional models to duplicate - * - * @access public - * @return string[] - */ - public function getOptionalSelection() - { - return array( - 'categoryModel', - 'projectPermissionModel', - 'actionModel', - 'swimlaneModel', - 'tagDuplicationModel', - 'projectMetadataModel', - 'projectTaskDuplicationModel', - ); - } - - /** - * Get list of all possible models to duplicate - * - * @access public - * @return string[] - */ - public function getPossibleSelection() - { - return array( - 'boardModel', - 'categoryModel', - 'projectPermissionModel', - 'actionModel', - 'swimlaneModel', - 'tagDuplicationModel', - 'projectMetadataModel', - 'projectTaskDuplicationModel', - ); - } - - /** - * Get a valid project name for the duplication - * - * @access public - * @param string $name Project name - * @param integer $max_length Max length allowed - * @return string - */ - public function getClonedProjectName($name, $max_length = 50) - { - $suffix = ' ('.t('Clone').')'; - - if (strlen($name.$suffix) > $max_length) { - $name = substr($name, 0, $max_length - strlen($suffix)); - } - - return $name.$suffix; - } - - /** - * Clone a project with all settings - * - * @param integer $src_project_id Project Id - * @param array $selection Selection of optional project parts to duplicate - * @param integer $owner_id Owner of the project - * @param string $name Name of the project - * @param boolean $private Force the project to be private - * @return integer Cloned Project Id - */ - public function duplicate($src_project_id, $selection = array('projectPermissionModel', 'categoryModel', 'actionModel'), $owner_id = 0, $name = null, $private = null) - { - $this->db->startTransaction(); - - // Get the cloned project Id - $dst_project_id = $this->copy($src_project_id, $owner_id, $name, $private); - - if ($dst_project_id === false) { - $this->db->cancelTransaction(); - return false; - } - - // Clone Columns, Categories, Permissions and Actions - foreach ($this->getPossibleSelection() as $model) { - - // Skip if optional part has not been selected - if (in_array($model, $this->getOptionalSelection()) && ! in_array($model, $selection)) { - continue; - } - - // Skip permissions for private projects - if ($private && $model === 'projectPermissionModel') { - continue; - } - - if (! $this->$model->duplicate($src_project_id, $dst_project_id)) { - $this->db->cancelTransaction(); - return false; - } - } - - if (! $this->makeOwnerManager($dst_project_id, $owner_id)) { - $this->db->cancelTransaction(); - return false; - } - - $this->db->closeTransaction(); - - return (int) $dst_project_id; - } - - /** - * Create a project from another one - * - * @access private - * @param integer $src_project_id - * @param integer $owner_id - * @param string $name - * @param boolean $private - * @return integer - */ - private function copy($src_project_id, $owner_id = 0, $name = null, $private = null) - { - $project = $this->projectModel->getById($src_project_id); - $is_private = empty($project['is_private']) ? 0 : 1; - - $values = array( - 'name' => $name ?: $this->getClonedProjectName($project['name']), - 'is_active' => 1, - 'last_modified' => time(), - 'token' => '', - 'is_public' => 0, - 'is_private' => $private ? 1 : $is_private, - 'owner_id' => $owner_id, - 'priority_default' => $project['priority_default'], - 'priority_start' => $project['priority_start'], - 'priority_end' => $project['priority_end'], - ); - - if (! $this->db->table(ProjectModel::TABLE)->save($values)) { - return false; - } - - return $this->db->getLastId(); - } - - /** - * Make sure that the creator of the duplicated project is alsp owner - * - * @access private - * @param integer $dst_project_id - * @param integer $owner_id - * @return boolean - */ - private function makeOwnerManager($dst_project_id, $owner_id) - { - if ($owner_id > 0) { - $this->projectUserRoleModel->removeUser($dst_project_id, $owner_id); - - if (! $this->projectUserRoleModel->addUser($dst_project_id, $owner_id, Role::PROJECT_MANAGER)) { - return false; - } - } - - return true; - } -} diff --git a/sources/app/Model/ProjectFileModel.php b/sources/app/Model/ProjectFileModel.php deleted file mode 100644 index b464bb2..0000000 --- a/sources/app/Model/ProjectFileModel.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * Project File Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectFileModel extends FileModel -{ - /** - * Table name - * - * @var string - */ - const TABLE = 'project_has_files'; - - /** - * Events - * - * @var string - */ - const EVENT_CREATE = 'project.file.create'; - - /** - * Get the table - * - * @abstract - * @access protected - * @return string - */ - protected function getTable() - { - return self::TABLE; - } - - /** - * Define the foreign key - * - * @abstract - * @access protected - * @return string - */ - protected function getForeignKey() - { - return 'project_id'; - } - - /** - * Define the path prefix - * - * @abstract - * @access protected - * @return string - */ - protected function getPathPrefix() - { - return 'projects'; - } - - /** - * Get event name - * - * @abstract - * @access protected - * @return string - */ - protected function getEventName() - { - return self::EVENT_CREATE; - } -} diff --git a/sources/app/Model/ProjectGroupRoleModel.php b/sources/app/Model/ProjectGroupRoleModel.php deleted file mode 100644 index 2729d5a..0000000 --- a/sources/app/Model/ProjectGroupRoleModel.php +++ /dev/null @@ -1,191 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Security\Role; - -/** - * Project Group Role - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectGroupRoleModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'project_has_groups'; - - /** - * Get the list of project visible by the given user according to groups - * - * @access public - * @param integer $user_id - * @param array $status - * @return array - */ - public function getProjectsByUser($user_id, $status = array(ProjectModel::ACTIVE, ProjectModel::INACTIVE)) - { - return $this->db - ->hashtable(ProjectModel::TABLE) - ->join(self::TABLE, 'project_id', 'id') - ->join(GroupMemberModel::TABLE, 'group_id', 'group_id', self::TABLE) - ->eq(GroupMemberModel::TABLE.'.user_id', $user_id) - ->in(ProjectModel::TABLE.'.is_active', $status) - ->getAll(ProjectModel::TABLE.'.id', ProjectModel::TABLE.'.name'); - } - - /** - * For a given project get the role of the specified user - * - * @access public - * @param integer $project_id - * @param integer $user_id - * @return string - */ - public function getUserRole($project_id, $user_id) - { - $roles = $this->db->table(self::TABLE) - ->join(GroupMemberModel::TABLE, 'group_id', 'group_id', self::TABLE) - ->eq(GroupMemberModel::TABLE.'.user_id', $user_id) - ->eq(self::TABLE.'.project_id', $project_id) - ->findAllByColumn('role'); - - return $this->projectAccessMap->getHighestRole($roles); - } - - /** - * Get all groups associated directly to the project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getGroups($project_id) - { - return $this->db->table(self::TABLE) - ->columns(GroupModel::TABLE.'.id', GroupModel::TABLE.'.name', self::TABLE.'.role') - ->join(GroupModel::TABLE, 'id', 'group_id') - ->eq('project_id', $project_id) - ->asc('name') - ->findAll(); - } - - /** - * From groups get all users associated to the project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getUsers($project_id) - { - return $this->db->table(self::TABLE) - ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name', self::TABLE.'.role') - ->join(GroupMemberModel::TABLE, 'group_id', 'group_id', self::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id', GroupMemberModel::TABLE) - ->eq(self::TABLE.'.project_id', $project_id) - ->asc(UserModel::TABLE.'.username') - ->findAll(); - } - - /** - * From groups get all users assignable to tasks - * - * @access public - * @param integer $project_id - * @return array - */ - public function getAssignableUsers($project_id) - { - return $this->db->table(UserModel::TABLE) - ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name') - ->join(GroupMemberModel::TABLE, 'user_id', 'id', UserModel::TABLE) - ->join(self::TABLE, 'group_id', 'group_id', GroupMemberModel::TABLE) - ->eq(self::TABLE.'.project_id', $project_id) - ->eq(UserModel::TABLE.'.is_active', 1) - ->in(self::TABLE.'.role', array(Role::PROJECT_MANAGER, Role::PROJECT_MEMBER)) - ->asc(UserModel::TABLE.'.username') - ->findAll(); - } - - /** - * Add a group to the project - * - * @access public - * @param integer $project_id - * @param integer $group_id - * @param string $role - * @return boolean - */ - public function addGroup($project_id, $group_id, $role) - { - return $this->db->table(self::TABLE)->insert(array( - 'group_id' => $group_id, - 'project_id' => $project_id, - 'role' => $role, - )); - } - - /** - * Remove a group from the project - * - * @access public - * @param integer $project_id - * @param integer $group_id - * @return boolean - */ - public function removeGroup($project_id, $group_id) - { - return $this->db->table(self::TABLE)->eq('group_id', $group_id)->eq('project_id', $project_id)->remove(); - } - - /** - * Change a group role for the project - * - * @access public - * @param integer $project_id - * @param integer $group_id - * @param string $role - * @return boolean - */ - public function changeGroupRole($project_id, $group_id, $role) - { - return $this->db->table(self::TABLE) - ->eq('group_id', $group_id) - ->eq('project_id', $project_id) - ->update(array( - 'role' => $role, - )); - } - - /** - * Copy group access from a project to another one - * - * @param integer $project_src_id Project Template - * @param integer $project_dst_id Project that receives the copy - * @return boolean - */ - public function duplicate($project_src_id, $project_dst_id) - { - $rows = $this->db->table(self::TABLE)->eq('project_id', $project_src_id)->findAll(); - - foreach ($rows as $row) { - $result = $this->db->table(self::TABLE)->save(array( - 'project_id' => $project_dst_id, - 'group_id' => $row['group_id'], - 'role' => $row['role'], - )); - - if (! $result) { - return false; - } - } - - return true; - } -} diff --git a/sources/app/Model/ProjectMetadataModel.php b/sources/app/Model/ProjectMetadataModel.php deleted file mode 100644 index 760acd7..0000000 --- a/sources/app/Model/ProjectMetadataModel.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * Project Metadata - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectMetadataModel extends MetadataModel -{ - /** - * Get the table - * - * @abstract - * @access protected - * @return string - */ - protected function getTable() - { - return 'project_has_metadata'; - } - - /** - * Define the entity key - * - * @access protected - * @return string - */ - protected function getEntityKey() - { - return 'project_id'; - } - - /** - * Helper method to duplicate all metadata to another project - * - * @access public - * @param integer $src_project_id - * @param integer $dst_project_id - * @return boolean - */ - public function duplicate($src_project_id, $dst_project_id) - { - $metadata = $this->getAll($src_project_id); - - if (! $this->save($dst_project_id, $metadata)) { - return false; - } - - return true; - } -} diff --git a/sources/app/Model/ProjectModel.php b/sources/app/Model/ProjectModel.php deleted file mode 100644 index 850531c..0000000 --- a/sources/app/Model/ProjectModel.php +++ /dev/null @@ -1,515 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Security\Token; -use Kanboard\Core\Security\Role; - -/** - * Project model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectModel extends Base -{ - /** - * SQL table name for projects - * - * @var string - */ - const TABLE = 'projects'; - - /** - * Value for active project - * - * @var integer - */ - const ACTIVE = 1; - - /** - * Value for inactive project - * - * @var integer - */ - const INACTIVE = 0; - - /** - * Value for private project - * - * @var integer - */ - const TYPE_PRIVATE = 1; - - /** - * Value for team project - * - * @var integer - */ - const TYPE_TEAM = 0; - - /** - * Get a project by the id - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getById($project_id) - { - return $this->db->table(self::TABLE)->eq('id', $project_id)->findOne(); - } - - /** - * Get a project by id with owner name - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getByIdWithOwner($project_id) - { - return $this->db->table(self::TABLE) - ->columns(self::TABLE.'.*', UserModel::TABLE.'.username AS owner_username', UserModel::TABLE.'.name AS owner_name') - ->eq(self::TABLE.'.id', $project_id) - ->join(UserModel::TABLE, 'id', 'owner_id') - ->findOne(); - } - - /** - * Get a project by the name - * - * @access public - * @param string $name Project name - * @return array - */ - public function getByName($name) - { - return $this->db->table(self::TABLE)->eq('name', $name)->findOne(); - } - - /** - * Get a project by the identifier (code) - * - * @access public - * @param string $identifier - * @return array|boolean - */ - public function getByIdentifier($identifier) - { - if (empty($identifier)) { - return false; - } - - return $this->db->table(self::TABLE)->eq('identifier', strtoupper($identifier))->findOne(); - } - - /** - * Fetch project data by using the token - * - * @access public - * @param string $token Token - * @return array|boolean - */ - public function getByToken($token) - { - if (empty($token)) { - return false; - } - - return $this->db->table(self::TABLE)->eq('token', $token)->eq('is_public', 1)->findOne(); - } - - /** - * Return the first project from the database (no sorting) - * - * @access public - * @return array - */ - public function getFirst() - { - return $this->db->table(self::TABLE)->findOne(); - } - - /** - * Return true if the project is private - * - * @access public - * @param integer $project_id Project id - * @return boolean - */ - public function isPrivate($project_id) - { - return $this->db->table(self::TABLE)->eq('id', $project_id)->eq('is_private', 1)->exists(); - } - - /** - * Get all projects - * - * @access public - * @return array - */ - public function getAll() - { - return $this->db->table(self::TABLE)->asc('name')->findAll(); - } - - /** - * Get all projects with given Ids - * - * @access public - * @param integer[] $project_ids - * @return array - */ - public function getAllByIds(array $project_ids) - { - if (empty($project_ids)) { - return array(); - } - - return $this->db->table(self::TABLE)->in('id', $project_ids)->asc('name')->findAll(); - } - - /** - * Get all project ids - * - * @access public - * @return array - */ - public function getAllIds() - { - return $this->db->table(self::TABLE)->asc('name')->findAllByColumn('id'); - } - - /** - * Return the list of all projects - * - * @access public - * @param bool $prepend If true, prepend to the list the value 'None' - * @return array - */ - public function getList($prepend = true) - { - if ($prepend) { - return array(t('None')) + $this->db->hashtable(self::TABLE)->asc('name')->getAll('id', 'name'); - } - - return $this->db->hashtable(self::TABLE)->asc('name')->getAll('id', 'name'); - } - - /** - * Get all projects with all its data for a given status - * - * @access public - * @param integer $status Project status: self::ACTIVE or self:INACTIVE - * @return array - */ - public function getAllByStatus($status) - { - return $this->db - ->table(self::TABLE) - ->asc('name') - ->eq('is_active', $status) - ->findAll(); - } - - /** - * Get a list of project by status - * - * @access public - * @param integer $status Project status: self::ACTIVE or self:INACTIVE - * @return array - */ - public function getListByStatus($status) - { - return $this->db - ->hashtable(self::TABLE) - ->asc('name') - ->eq('is_active', $status) - ->getAll('id', 'name'); - } - - /** - * Return the number of projects by status - * - * @access public - * @param integer $status Status: self::ACTIVE or self:INACTIVE - * @return integer - */ - public function countByStatus($status) - { - return $this->db - ->table(self::TABLE) - ->eq('is_active', $status) - ->count(); - } - - /** - * Gather some task metrics for a given project - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getTaskStats($project_id) - { - $stats = array(); - $stats['nb_active_tasks'] = 0; - $columns = $this->columnModel->getAll($project_id); - $column_stats = $this->boardModel->getColumnStats($project_id); - - foreach ($columns as &$column) { - $column['nb_active_tasks'] = isset($column_stats[$column['id']]) ? $column_stats[$column['id']] : 0; - $stats['nb_active_tasks'] += $column['nb_active_tasks']; - } - - $stats['columns'] = $columns; - $stats['nb_tasks'] = $this->taskFinderModel->countByProjectId($project_id); - $stats['nb_inactive_tasks'] = $stats['nb_tasks'] - $stats['nb_active_tasks']; - - return $stats; - } - - /** - * Get stats for each column of a project - * - * @access public - * @param array $project - * @return array - */ - public function getColumnStats(array &$project) - { - $project['columns'] = $this->columnModel->getAll($project['id']); - $project['nb_active_tasks'] = 0; - $stats = $this->boardModel->getColumnStats($project['id']); - - foreach ($project['columns'] as &$column) { - $column['nb_tasks'] = isset($stats[$column['id']]) ? $stats[$column['id']] : 0; - $project['nb_active_tasks'] += $column['nb_tasks']; - } - - return $project; - } - - /** - * Apply column stats to a collection of projects (filter callback) - * - * @access public - * @param array $projects - * @return array - */ - public function applyColumnStats(array $projects) - { - foreach ($projects as &$project) { - $this->getColumnStats($project); - } - - return $projects; - } - - /** - * Get project summary for a list of project - * - * @access public - * @param array $project_ids List of project id - * @return \PicoDb\Table - */ - public function getQueryColumnStats(array $project_ids) - { - if (empty($project_ids)) { - return $this->db->table(ProjectModel::TABLE)->limit(0); - } - - return $this->db - ->table(ProjectModel::TABLE) - ->columns(self::TABLE.'.*', UserModel::TABLE.'.username AS owner_username', UserModel::TABLE.'.name AS owner_name') - ->join(UserModel::TABLE, 'id', 'owner_id') - ->in(self::TABLE.'.id', $project_ids) - ->callback(array($this, 'applyColumnStats')); - } - - /** - * Create a project - * - * @access public - * @param array $values Form values - * @param integer $user_id User who create the project - * @param bool $add_user Automatically add the user - * @return integer Project id - */ - public function create(array $values, $user_id = 0, $add_user = false) - { - $this->db->startTransaction(); - - $values['token'] = ''; - $values['last_modified'] = time(); - $values['is_private'] = empty($values['is_private']) ? 0 : 1; - $values['owner_id'] = $user_id; - - if (! empty($values['identifier'])) { - $values['identifier'] = strtoupper($values['identifier']); - } - - $this->helper->model->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end')); - - if (! $this->db->table(self::TABLE)->save($values)) { - $this->db->cancelTransaction(); - return false; - } - - $project_id = $this->db->getLastId(); - - if (! $this->boardModel->create($project_id, $this->boardModel->getUserColumns())) { - $this->db->cancelTransaction(); - return false; - } - - if ($add_user && $user_id) { - $this->projectUserRoleModel->addUser($project_id, $user_id, Role::PROJECT_MANAGER); - } - - $this->categoryModel->createDefaultCategories($project_id); - - $this->db->closeTransaction(); - - return (int) $project_id; - } - - /** - * Check if the project have been modified - * - * @access public - * @param integer $project_id Project id - * @param integer $timestamp Timestamp - * @return bool - */ - public function isModifiedSince($project_id, $timestamp) - { - return (bool) $this->db->table(self::TABLE) - ->eq('id', $project_id) - ->gt('last_modified', $timestamp) - ->count(); - } - - /** - * Update modification date - * - * @access public - * @param integer $project_id Project id - * @return bool - */ - public function updateModificationDate($project_id) - { - return $this->db->table(self::TABLE)->eq('id', $project_id)->update(array( - 'last_modified' => time() - )); - } - - /** - * Update a project - * - * @access public - * @param array $values Form values - * @return bool - */ - public function update(array $values) - { - if (! empty($values['identifier'])) { - $values['identifier'] = strtoupper($values['identifier']); - } - - $this->helper->model->convertIntegerFields($values, array('priority_default', 'priority_start', 'priority_end')); - - return $this->exists($values['id']) && - $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); - } - - /** - * Remove a project - * - * @access public - * @param integer $project_id Project id - * @return bool - */ - public function remove($project_id) - { - return $this->db->table(self::TABLE)->eq('id', $project_id)->remove(); - } - - /** - * Return true if the project exists - * - * @access public - * @param integer $project_id Project id - * @return boolean - */ - public function exists($project_id) - { - return $this->db->table(self::TABLE)->eq('id', $project_id)->exists(); - } - - /** - * Enable a project - * - * @access public - * @param integer $project_id Project id - * @return bool - */ - public function enable($project_id) - { - return $this->exists($project_id) && - $this->db - ->table(self::TABLE) - ->eq('id', $project_id) - ->update(array('is_active' => 1)); - } - - /** - * Disable a project - * - * @access public - * @param integer $project_id Project id - * @return bool - */ - public function disable($project_id) - { - return $this->exists($project_id) && - $this->db - ->table(self::TABLE) - ->eq('id', $project_id) - ->update(array('is_active' => 0)); - } - - /** - * Enable public access for a project - * - * @access public - * @param integer $project_id Project id - * @return bool - */ - public function enablePublicAccess($project_id) - { - return $this->exists($project_id) && - $this->db - ->table(self::TABLE) - ->eq('id', $project_id) - ->save(array('is_public' => 1, 'token' => Token::getToken())); - } - - /** - * Disable public access for a project - * - * @access public - * @param integer $project_id Project id - * @return bool - */ - public function disablePublicAccess($project_id) - { - return $this->exists($project_id) && - $this->db - ->table(self::TABLE) - ->eq('id', $project_id) - ->save(array('is_public' => 0, 'token' => '')); - } -} diff --git a/sources/app/Model/ProjectNotificationModel.php b/sources/app/Model/ProjectNotificationModel.php deleted file mode 100644 index aeeee4c..0000000 --- a/sources/app/Model/ProjectNotificationModel.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Project Notification - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectNotificationModel extends Base -{ - /** - * Send notifications - * - * @access public - * @param integer $project_id - * @param string $event_name - * @param array $event_data - */ - public function sendNotifications($project_id, $event_name, array $event_data) - { - $project = $this->projectModel->getById($project_id); - - $types = array_merge( - $this->projectNotificationTypeModel->getHiddenTypes(), - $this->projectNotificationTypeModel->getSelectedTypes($project_id) - ); - - foreach ($types as $type) { - $this->projectNotificationTypeModel->getType($type)->notifyProject($project, $event_name, $event_data); - } - } - - /** - * Save settings for the given project - * - * @access public - * @param integer $project_id - * @param array $values - */ - public function saveSettings($project_id, array $values) - { - $this->db->startTransaction(); - - $types = empty($values['notification_types']) ? array() : array_keys($values['notification_types']); - $this->projectNotificationTypeModel->saveSelectedTypes($project_id, $types); - - $this->db->closeTransaction(); - } - - /** - * Read user settings to display the form - * - * @access public - * @param integer $project_id - * @return array - */ - public function readSettings($project_id) - { - return array( - 'notification_types' => $this->projectNotificationTypeModel->getSelectedTypes($project_id), - ); - } -} diff --git a/sources/app/Model/ProjectNotificationTypeModel.php b/sources/app/Model/ProjectNotificationTypeModel.php deleted file mode 100644 index aeec77f..0000000 --- a/sources/app/Model/ProjectNotificationTypeModel.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * Project Notification Type - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectNotificationTypeModel extends NotificationTypeModel -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'project_has_notification_types'; - - /** - * Get selected notification types for a given project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getSelectedTypes($project_id) - { - $types = $this->db - ->table(self::TABLE) - ->eq('project_id', $project_id) - ->asc('notification_type') - ->findAllByColumn('notification_type'); - - return $this->filterTypes($types); - } - - /** - * Save notification types for a given project - * - * @access public - * @param integer $project_id - * @param string[] $types - * @return boolean - */ - public function saveSelectedTypes($project_id, array $types) - { - $results = array(); - $this->db->table(self::TABLE)->eq('project_id', $project_id)->remove(); - - foreach ($types as $type) { - $results[] = $this->db->table(self::TABLE)->insert(array('project_id' => $project_id, 'notification_type' => $type)); - } - - return ! in_array(false, $results, true); - } -} diff --git a/sources/app/Model/ProjectPermissionModel.php b/sources/app/Model/ProjectPermissionModel.php deleted file mode 100644 index a7c1857..0000000 --- a/sources/app/Model/ProjectPermissionModel.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Security\Role; -use Kanboard\Filter\ProjectGroupRoleProjectFilter; -use Kanboard\Filter\ProjectGroupRoleUsernameFilter; -use Kanboard\Filter\ProjectUserRoleProjectFilter; -use Kanboard\Filter\ProjectUserRoleUsernameFilter; - -/** - * Project Permission - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectPermissionModel extends Base -{ - /** - * Get query for project users overview - * - * @access public - * @param array $project_ids - * @param string $role - * @return \PicoDb\Table - */ - public function getQueryByRole(array $project_ids, $role) - { - if (empty($project_ids)) { - $project_ids = array(-1); - } - - return $this - ->db - ->table(ProjectUserRoleModel::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id') - ->join(ProjectModel::TABLE, 'id', 'project_id') - ->eq(ProjectUserRoleModel::TABLE.'.role', $role) - ->eq(ProjectModel::TABLE.'.is_private', 0) - ->in(ProjectModel::TABLE.'.id', $project_ids) - ->columns( - UserModel::TABLE.'.id', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name', - ProjectModel::TABLE.'.name AS project_name', - ProjectModel::TABLE.'.id' - ); - } - - /** - * Get all usernames (fetch users from groups) - * - * @access public - * @param integer $project_id - * @param string $input - * @return array - */ - public function findUsernames($project_id, $input) - { - $userMembers = $this->projectUserRoleQuery - ->withFilter(new ProjectUserRoleProjectFilter($project_id)) - ->withFilter(new ProjectUserRoleUsernameFilter($input)) - ->getQuery() - ->findAllByColumn('username'); - - $groupMembers = $this->projectGroupRoleQuery - ->withFilter(new ProjectGroupRoleProjectFilter($project_id)) - ->withFilter(new ProjectGroupRoleUsernameFilter($input)) - ->getQuery() - ->findAllByColumn('username'); - - $members = array_unique(array_merge($userMembers, $groupMembers)); - - sort($members); - - return $members; - } - - /** - * Return true if everybody is allowed for the project - * - * @access public - * @param integer $project_id Project id - * @return bool - */ - public function isEverybodyAllowed($project_id) - { - return $this->db - ->table(ProjectModel::TABLE) - ->eq('id', $project_id) - ->eq('is_everybody_allowed', 1) - ->exists(); - } - - /** - * Return true if the user is allowed to access a project - * - * @param integer $project_id - * @param integer $user_id - * @return boolean - */ - public function isUserAllowed($project_id, $user_id) - { - if ($this->userSession->isAdmin()) { - return true; - } - - return in_array( - $this->projectUserRoleModel->getUserRole($project_id, $user_id), - array(Role::PROJECT_MANAGER, Role::PROJECT_MEMBER, Role::PROJECT_VIEWER) - ); - } - - /** - * Return true if the user is assignable - * - * @access public - * @param integer $project_id - * @param integer $user_id - * @return boolean - */ - public function isAssignable($project_id, $user_id) - { - return $this->userModel->isActive($user_id) && - in_array($this->projectUserRoleModel->getUserRole($project_id, $user_id), array(Role::PROJECT_MEMBER, Role::PROJECT_MANAGER)); - } - - /** - * Return true if the user is member - * - * @access public - * @param integer $project_id - * @param integer $user_id - * @return boolean - */ - public function isMember($project_id, $user_id) - { - return in_array($this->projectUserRoleModel->getUserRole($project_id, $user_id), array(Role::PROJECT_MEMBER, Role::PROJECT_MANAGER, Role::PROJECT_VIEWER)); - } - - /** - * Get active project ids by user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getActiveProjectIds($user_id) - { - return array_keys($this->projectUserRoleModel->getActiveProjectsByUser($user_id)); - } - - /** - * Copy permissions to another project - * - * @param integer $project_src_id Project Template - * @param integer $project_dst_id Project that receives the copy - * @return boolean - */ - public function duplicate($project_src_id, $project_dst_id) - { - return $this->projectUserRoleModel->duplicate($project_src_id, $project_dst_id) && - $this->projectGroupRoleModel->duplicate($project_src_id, $project_dst_id); - } -} diff --git a/sources/app/Model/ProjectTaskDuplicationModel.php b/sources/app/Model/ProjectTaskDuplicationModel.php deleted file mode 100644 index 5d2e132..0000000 --- a/sources/app/Model/ProjectTaskDuplicationModel.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Project Task Duplication Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectTaskDuplicationModel extends Base -{ - /** - * Duplicate all tasks to another project - * - * @access public - * @param integer $src_project_id - * @param integer $dst_project_id - * @return boolean - */ - public function duplicate($src_project_id, $dst_project_id) - { - $task_ids = $this->taskFinderModel->getAllIds($src_project_id, array(TaskModel::STATUS_OPEN, TaskModel::STATUS_CLOSED)); - - foreach ($task_ids as $task_id) { - if (! $this->taskProjectDuplicationModel->duplicateToProject($task_id, $dst_project_id)) { - return false; - } - } - - return true; - } -} diff --git a/sources/app/Model/ProjectTaskPriorityModel.php b/sources/app/Model/ProjectTaskPriorityModel.php deleted file mode 100644 index c1a0257..0000000 --- a/sources/app/Model/ProjectTaskPriorityModel.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Project Task Priority Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectTaskPriorityModel extends Base -{ - /** - * Get Priority range from a project - * - * @access public - * @param array $project - * @return array - */ - public function getPriorities(array $project) - { - $range = range($project['priority_start'], $project['priority_end']); - return array_combine($range, $range); - } - - /** - * Get task priority settings - * - * @access public - * @param int $project_id - * @return array|null - */ - public function getPrioritySettings($project_id) - { - return $this->db - ->table(ProjectModel::TABLE) - ->columns('priority_default', 'priority_start', 'priority_end') - ->eq('id', $project_id) - ->findOne(); - } - - /** - * Get default task priority - * - * @access public - * @param int $project_id - * @return int - */ - public function getDefaultPriority($project_id) - { - return $this->db->table(ProjectModel::TABLE)->eq('id', $project_id)->findOneColumn('priority_default') ?: 0; - } - - /** - * Get priority for a destination project - * - * @access public - * @param integer $dst_project_id - * @param integer $priority - * @return integer - */ - public function getPriorityForProject($dst_project_id, $priority) - { - $settings = $this->getPrioritySettings($dst_project_id); - - if ($priority >= $settings['priority_start'] && $priority <= $settings['priority_end']) { - return $priority; - } - - return $settings['priority_default']; - } -} diff --git a/sources/app/Model/ProjectUserRoleModel.php b/sources/app/Model/ProjectUserRoleModel.php deleted file mode 100644 index a0df0cf..0000000 --- a/sources/app/Model/ProjectUserRoleModel.php +++ /dev/null @@ -1,282 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Security\Role; - -/** - * Project User Role - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class ProjectUserRoleModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'project_has_users'; - - /** - * Get the list of active project for the given user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getActiveProjectsByUser($user_id) - { - return $this->getProjectsByUser($user_id, array(ProjectModel::ACTIVE)); - } - - /** - * Get the list of project visible for the given user - * - * @access public - * @param integer $user_id - * @param array $status - * @return array - */ - public function getProjectsByUser($user_id, $status = array(ProjectModel::ACTIVE, ProjectModel::INACTIVE)) - { - $userProjects = $this->db - ->hashtable(ProjectModel::TABLE) - ->beginOr() - ->eq(self::TABLE.'.user_id', $user_id) - ->eq(ProjectModel::TABLE.'.is_everybody_allowed', 1) - ->closeOr() - ->in(ProjectModel::TABLE.'.is_active', $status) - ->join(self::TABLE, 'project_id', 'id') - ->getAll(ProjectModel::TABLE.'.id', ProjectModel::TABLE.'.name'); - - $groupProjects = $this->projectGroupRoleModel->getProjectsByUser($user_id, $status); - $projects = $userProjects + $groupProjects; - - asort($projects); - - return $projects; - } - - /** - * For a given project get the role of the specified user - * - * @access public - * @param integer $project_id - * @param integer $user_id - * @return string - */ - public function getUserRole($project_id, $user_id) - { - $projectInfo = $this->db->table(ProjectModel::TABLE) - ->eq('id', $project_id) - ->columns('owner_id', 'is_everybody_allowed') - ->findOne(); - - if ($projectInfo['is_everybody_allowed'] == 1) { - return $projectInfo['owner_id'] == $user_id ? Role::PROJECT_MANAGER : Role::PROJECT_MEMBER; - } - - $role = $this->db->table(self::TABLE)->eq('user_id', $user_id)->eq('project_id', $project_id)->findOneColumn('role'); - - if (empty($role)) { - $role = $this->projectGroupRoleModel->getUserRole($project_id, $user_id); - } - - return $role; - } - - /** - * Get all users associated directly to the project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getUsers($project_id) - { - return $this->db->table(self::TABLE) - ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name', self::TABLE.'.role') - ->join(UserModel::TABLE, 'id', 'user_id') - ->eq('project_id', $project_id) - ->asc(UserModel::TABLE.'.username') - ->asc(UserModel::TABLE.'.name') - ->findAll(); - } - - /** - * Get all users (fetch users from groups) - * - * @access public - * @param integer $project_id - * @return array - */ - public function getAllUsers($project_id) - { - $userMembers = $this->getUsers($project_id); - $groupMembers = $this->projectGroupRoleModel->getUsers($project_id); - $members = array_merge($userMembers, $groupMembers); - - return $this->userModel->prepareList($members); - } - - /** - * Get users grouped by role - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getAllUsersGroupedByRole($project_id) - { - $users = array(); - - $userMembers = $this->getUsers($project_id); - $groupMembers = $this->projectGroupRoleModel->getUsers($project_id); - $members = array_merge($userMembers, $groupMembers); - - foreach ($members as $user) { - if (! isset($users[$user['role']])) { - $users[$user['role']] = array(); - } - - $users[$user['role']][$user['id']] = $user['name'] ?: $user['username']; - } - - return $users; - } - - /** - * Get list of users that can be assigned to a task (only Manager and Member) - * - * @access public - * @param integer $project_id - * @return array - */ - public function getAssignableUsers($project_id) - { - if ($this->projectPermissionModel->isEverybodyAllowed($project_id)) { - return $this->userModel->getActiveUsersList(); - } - - $userMembers = $this->db->table(self::TABLE) - ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name') - ->join(UserModel::TABLE, 'id', 'user_id') - ->eq(UserModel::TABLE.'.is_active', 1) - ->eq(self::TABLE.'.project_id', $project_id) - ->in(self::TABLE.'.role', array(Role::PROJECT_MANAGER, Role::PROJECT_MEMBER)) - ->findAll(); - - $groupMembers = $this->projectGroupRoleModel->getAssignableUsers($project_id); - $members = array_merge($userMembers, $groupMembers); - - return $this->userModel->prepareList($members); - } - - /** - * Get list of users that can be assigned to a task (only Manager and Member) - * - * @access public - * @param integer $project_id Project id - * @param bool $unassigned Prepend the 'Unassigned' value - * @param bool $everybody Prepend the 'Everbody' value - * @param bool $singleUser If there is only one user return only this user - * @return array - */ - public function getAssignableUsersList($project_id, $unassigned = true, $everybody = false, $singleUser = false) - { - $users = $this->getAssignableUsers($project_id); - - if ($singleUser && count($users) === 1) { - return $users; - } - - if ($unassigned) { - $users = array(t('Unassigned')) + $users; - } - - if ($everybody) { - $users = array(UserModel::EVERYBODY_ID => t('Everybody')) + $users; - } - - return $users; - } - - /** - * Add a user to the project - * - * @access public - * @param integer $project_id - * @param integer $user_id - * @param string $role - * @return boolean - */ - public function addUser($project_id, $user_id, $role) - { - return $this->db->table(self::TABLE)->insert(array( - 'user_id' => $user_id, - 'project_id' => $project_id, - 'role' => $role, - )); - } - - /** - * Remove a user from the project - * - * @access public - * @param integer $project_id - * @param integer $user_id - * @return boolean - */ - public function removeUser($project_id, $user_id) - { - return $this->db->table(self::TABLE)->eq('user_id', $user_id)->eq('project_id', $project_id)->remove(); - } - - /** - * Change a user role for the project - * - * @access public - * @param integer $project_id - * @param integer $user_id - * @param string $role - * @return boolean - */ - public function changeUserRole($project_id, $user_id, $role) - { - return $this->db->table(self::TABLE) - ->eq('user_id', $user_id) - ->eq('project_id', $project_id) - ->update(array( - 'role' => $role, - )); - } - - /** - * Copy user access from a project to another one - * - * @param integer $project_src_id - * @param integer $project_dst_id - * @return boolean - */ - public function duplicate($project_src_id, $project_dst_id) - { - $rows = $this->db->table(self::TABLE)->eq('project_id', $project_src_id)->findAll(); - - foreach ($rows as $row) { - $result = $this->db->table(self::TABLE)->save(array( - 'project_id' => $project_dst_id, - 'user_id' => $row['user_id'], - 'role' => $row['role'], - )); - - if (! $result) { - return false; - } - } - - return true; - } -} diff --git a/sources/app/Model/RememberMeSessionModel.php b/sources/app/Model/RememberMeSessionModel.php deleted file mode 100644 index f6c8d64..0000000 --- a/sources/app/Model/RememberMeSessionModel.php +++ /dev/null @@ -1,152 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Security\Token; - -/** - * Remember Me Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class RememberMeSessionModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'remember_me'; - - /** - * Expiration (60 days) - * - * @var integer - */ - const EXPIRATION = 5184000; - - /** - * Get a remember me record - * - * @access public - * @param $token - * @param $sequence - * @return mixed - */ - public function find($token, $sequence) - { - return $this->db - ->table(self::TABLE) - ->eq('token', $token) - ->eq('sequence', $sequence) - ->gt('expiration', time()) - ->findOne(); - } - - /** - * Get all sessions for a given user - * - * @access public - * @param integer $user_id User id - * @return array - */ - public function getAll($user_id) - { - return $this->db - ->table(self::TABLE) - ->eq('user_id', $user_id) - ->desc('date_creation') - ->columns('id', 'ip', 'user_agent', 'date_creation', 'expiration') - ->findAll(); - } - - /** - * Create a new RememberMe session - * - * @access public - * @param integer $user_id User id - * @param string $ip IP Address - * @param string $user_agent User Agent - * @return array - */ - public function create($user_id, $ip, $user_agent) - { - $token = hash('sha256', $user_id.$user_agent.$ip.Token::getToken()); - $sequence = Token::getToken(); - $expiration = time() + self::EXPIRATION; - - $this->cleanup($user_id); - - $this - ->db - ->table(self::TABLE) - ->insert(array( - 'user_id' => $user_id, - 'ip' => $ip, - 'user_agent' => $user_agent, - 'token' => $token, - 'sequence' => $sequence, - 'expiration' => $expiration, - 'date_creation' => time(), - )); - - return array( - 'token' => $token, - 'sequence' => $sequence, - 'expiration' => $expiration, - ); - } - - /** - * Remove a session record - * - * @access public - * @param integer $session_id Session id - * @return mixed - */ - public function remove($session_id) - { - return $this->db - ->table(self::TABLE) - ->eq('id', $session_id) - ->remove(); - } - - /** - * Remove old sessions for a given user - * - * @access public - * @param integer $user_id User id - * @return bool - */ - public function cleanup($user_id) - { - return $this->db - ->table(self::TABLE) - ->eq('user_id', $user_id) - ->lt('expiration', time()) - ->remove(); - } - - /** - * Return a new sequence token and update the database - * - * @access public - * @param string $token Session token - * @return string - */ - public function updateSequence($token) - { - $sequence = Token::getToken(); - - $this - ->db - ->table(self::TABLE) - ->eq('token', $token) - ->update(array('sequence' => $sequence)); - - return $sequence; - } -} diff --git a/sources/app/Model/SettingModel.php b/sources/app/Model/SettingModel.php deleted file mode 100644 index 5b2ee54..0000000 --- a/sources/app/Model/SettingModel.php +++ /dev/null @@ -1,113 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Application Settings - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -abstract class SettingModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'settings'; - - /** - * Prepare data before save - * - * @abstract - * @access public - * @param array $values - * @return array - */ - abstract public function prepare(array $values); - - /** - * Get all settings - * - * @access public - * @return array - */ - public function getAll() - { - return $this->db->hashtable(self::TABLE)->getAll('option', 'value'); - } - - /** - * Get a setting value - * - * @access public - * @param string $name - * @param string $default - * @return mixed - */ - public function getOption($name, $default = '') - { - $value = $this->db - ->table(self::TABLE) - ->eq('option', $name) - ->findOneColumn('value'); - - return $value === null || $value === false || $value === '' ? $default : $value; - } - - /** - * Return true if a setting exists - * - * @access public - * @param string $name - * @return boolean - */ - public function exists($name) - { - return $this->db - ->table(self::TABLE) - ->eq('option', $name) - ->exists(); - } - - /** - * Update or insert new settings - * - * @access public - * @param array $values - * @return boolean - */ - public function save(array $values) - { - $results = array(); - $values = $this->prepare($values); - $user_id = $this->userSession->getId(); - $timestamp = time(); - - $this->db->startTransaction(); - - foreach ($values as $option => $value) { - if ($this->exists($option)) { - $results[] = $this->db->table(self::TABLE)->eq('option', $option)->update(array( - 'value' => $value, - 'changed_on' => $timestamp, - 'changed_by' => $user_id, - )); - } else { - $results[] = $this->db->table(self::TABLE)->insert(array( - 'option' => $option, - 'value' => $value, - 'changed_on' => $timestamp, - 'changed_by' => $user_id, - )); - } - } - - $this->db->closeTransaction(); - - return ! in_array(false, $results, true); - } -} diff --git a/sources/app/Model/SubtaskModel.php b/sources/app/Model/SubtaskModel.php deleted file mode 100644 index a97bddb..0000000 --- a/sources/app/Model/SubtaskModel.php +++ /dev/null @@ -1,444 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use PicoDb\Database; -use Kanboard\Core\Base; -use Kanboard\Event\SubtaskEvent; - -/** - * Subtask Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class SubtaskModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'subtasks'; - - /** - * Task "done" status - * - * @var integer - */ - const STATUS_DONE = 2; - - /** - * Task "in progress" status - * - * @var integer - */ - const STATUS_INPROGRESS = 1; - - /** - * Task "todo" status - * - * @var integer - */ - const STATUS_TODO = 0; - - /** - * Events - * - * @var string - */ - const EVENT_UPDATE = 'subtask.update'; - const EVENT_CREATE = 'subtask.create'; - const EVENT_DELETE = 'subtask.delete'; - - /** - * Get projectId from subtaskId - * - * @access public - * @param integer $subtask_id - * @return integer - */ - public function getProjectId($subtask_id) - { - return $this->db - ->table(self::TABLE) - ->eq(self::TABLE.'.id', $subtask_id) - ->join(TaskModel::TABLE, 'id', 'task_id') - ->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0; - } - - /** - * Get available status - * - * @access public - * @return string[] - */ - public function getStatusList() - { - return array( - self::STATUS_TODO => t('Todo'), - self::STATUS_INPROGRESS => t('In progress'), - self::STATUS_DONE => t('Done'), - ); - } - - /** - * Add subtask status status to the resultset - * - * @access public - * @param array $subtasks Subtasks - * @return array - */ - public function addStatusName(array $subtasks) - { - $status = $this->getStatusList(); - - foreach ($subtasks as &$subtask) { - $subtask['status_name'] = $status[$subtask['status']]; - $subtask['timer_start_date'] = isset($subtask['timer_start_date']) ? $subtask['timer_start_date'] : 0; - $subtask['is_timer_started'] = ! empty($subtask['timer_start_date']); - } - - return $subtasks; - } - - /** - * Get the query to fetch subtasks assigned to a user - * - * @access public - * @param integer $user_id User id - * @param array $status List of status - * @return \PicoDb\Table - */ - public function getUserQuery($user_id, array $status) - { - return $this->db->table(SubtaskModel::TABLE) - ->columns( - SubtaskModel::TABLE.'.*', - TaskModel::TABLE.'.project_id', - TaskModel::TABLE.'.color_id', - TaskModel::TABLE.'.title AS task_name', - ProjectModel::TABLE.'.name AS project_name' - ) - ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($user_id), 'timer_start_date') - ->eq('user_id', $user_id) - ->eq(ProjectModel::TABLE.'.is_active', ProjectModel::ACTIVE) - ->in(SubtaskModel::TABLE.'.status', $status) - ->join(TaskModel::TABLE, 'id', 'task_id') - ->join(ProjectModel::TABLE, 'id', 'project_id', TaskModel::TABLE) - ->callback(array($this, 'addStatusName')); - } - - /** - * Get all subtasks for a given task - * - * @access public - * @param integer $task_id Task id - * @return array - */ - public function getAll($task_id) - { - return $this->db - ->table(self::TABLE) - ->eq('task_id', $task_id) - ->columns( - self::TABLE.'.*', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name' - ) - ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($this->userSession->getId()), 'timer_start_date') - ->join(UserModel::TABLE, 'id', 'user_id') - ->asc(self::TABLE.'.position') - ->callback(array($this, 'addStatusName')) - ->findAll(); - } - - /** - * Get a subtask by the id - * - * @access public - * @param integer $subtask_id Subtask id - * @param bool $more Fetch more data - * @return array - */ - public function getById($subtask_id, $more = false) - { - if ($more) { - return $this->db - ->table(self::TABLE) - ->eq(self::TABLE.'.id', $subtask_id) - ->columns(self::TABLE.'.*', UserModel::TABLE.'.username', UserModel::TABLE.'.name') - ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($this->userSession->getId()), 'timer_start_date') - ->join(UserModel::TABLE, 'id', 'user_id') - ->callback(array($this, 'addStatusName')) - ->findOne(); - } - - return $this->db->table(self::TABLE)->eq('id', $subtask_id)->findOne(); - } - - /** - * Prepare data before insert/update - * - * @access public - * @param array $values Form values - */ - public function prepare(array &$values) - { - $this->helper->model->removeFields($values, array('another_subtask')); - $this->helper->model->resetFields($values, array('time_estimated', 'time_spent')); - } - - /** - * Prepare data before insert - * - * @access public - * @param array $values Form values - */ - public function prepareCreation(array &$values) - { - $this->prepare($values); - - $values['position'] = $this->getLastPosition($values['task_id']) + 1; - $values['status'] = isset($values['status']) ? $values['status'] : self::STATUS_TODO; - $values['time_estimated'] = isset($values['time_estimated']) ? $values['time_estimated'] : 0; - $values['time_spent'] = isset($values['time_spent']) ? $values['time_spent'] : 0; - $values['user_id'] = isset($values['user_id']) ? $values['user_id'] : 0; - } - - /** - * Get the position of the last column for a given project - * - * @access public - * @param integer $task_id Task id - * @return integer - */ - public function getLastPosition($task_id) - { - return (int) $this->db - ->table(self::TABLE) - ->eq('task_id', $task_id) - ->desc('position') - ->findOneColumn('position'); - } - - /** - * Create a new subtask - * - * @access public - * @param array $values Form values - * @return bool|integer - */ - public function create(array $values) - { - $this->prepareCreation($values); - $subtask_id = $this->db->table(self::TABLE)->persist($values); - - if ($subtask_id !== false) { - $this->container['dispatcher']->dispatch( - self::EVENT_CREATE, - new SubtaskEvent(array('id' => $subtask_id) + $values) - ); - } - - return $subtask_id; - } - - /** - * Update - * - * @access public - * @param array $values Form values - * @param bool $fire_events If true, will be called an event - * @return bool - */ - public function update(array $values, $fire_events = true) - { - $this->prepare($values); - $subtask = $this->getById($values['id']); - $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); - - if ($result && $fire_events) { - $event = $subtask; - $event['changes'] = array_diff_assoc($values, $subtask); - $this->container['dispatcher']->dispatch(self::EVENT_UPDATE, new SubtaskEvent($event)); - } - - return $result; - } - - /** - * Close all subtasks of a task - * - * @access public - * @param integer $task_id - * @return boolean - */ - public function closeAll($task_id) - { - return $this->db->table(self::TABLE)->eq('task_id', $task_id)->update(array('status' => self::STATUS_DONE)); - } - - /** - * Save subtask position - * - * @access public - * @param integer $task_id - * @param integer $subtask_id - * @param integer $position - * @return boolean - */ - public function changePosition($task_id, $subtask_id, $position) - { - if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('task_id', $task_id)->count()) { - return false; - } - - $subtask_ids = $this->db->table(self::TABLE)->eq('task_id', $task_id)->neq('id', $subtask_id)->asc('position')->findAllByColumn('id'); - $offset = 1; - $results = array(); - - foreach ($subtask_ids as $current_subtask_id) { - if ($offset == $position) { - $offset++; - } - - $results[] = $this->db->table(self::TABLE)->eq('id', $current_subtask_id)->update(array('position' => $offset)); - $offset++; - } - - $results[] = $this->db->table(self::TABLE)->eq('id', $subtask_id)->update(array('position' => $position)); - - return !in_array(false, $results, true); - } - - /** - * Change the status of subtask - * - * @access public - * @param integer $subtask_id - * @return boolean|integer - */ - public function toggleStatus($subtask_id) - { - $subtask = $this->getById($subtask_id); - $status = ($subtask['status'] + 1) % 3; - - $values = array( - 'id' => $subtask['id'], - 'status' => $status, - 'task_id' => $subtask['task_id'], - ); - - if (empty($subtask['user_id']) && $this->userSession->isLogged()) { - $values['user_id'] = $this->userSession->getId(); - } - - return $this->update($values) ? $status : false; - } - - /** - * Get the subtask in progress for this user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getSubtaskInProgress($user_id) - { - return $this->db->table(self::TABLE) - ->eq('status', self::STATUS_INPROGRESS) - ->eq('user_id', $user_id) - ->findOne(); - } - - /** - * Return true if the user have a subtask in progress - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function hasSubtaskInProgress($user_id) - { - return $this->configModel->get('subtask_restriction') == 1 && - $this->db->table(self::TABLE) - ->eq('status', self::STATUS_INPROGRESS) - ->eq('user_id', $user_id) - ->exists(); - } - - /** - * Remove - * - * @access public - * @param integer $subtask_id Subtask id - * @return bool - */ - public function remove($subtask_id) - { - $subtask = $this->getById($subtask_id); - $result = $this->db->table(self::TABLE)->eq('id', $subtask_id)->remove(); - - if ($result) { - $this->container['dispatcher']->dispatch(self::EVENT_DELETE, new SubtaskEvent($subtask)); - } - - return $result; - } - - /** - * Duplicate all subtasks to another task - * - * @access public - * @param integer $src_task_id Source task id - * @param integer $dst_task_id Destination task id - * @return bool - */ - public function duplicate($src_task_id, $dst_task_id) - { - return $this->db->transaction(function (Database $db) use ($src_task_id, $dst_task_id) { - - $subtasks = $db->table(SubtaskModel::TABLE) - ->columns('title', 'time_estimated', 'position') - ->eq('task_id', $src_task_id) - ->asc('position') - ->findAll(); - - foreach ($subtasks as &$subtask) { - $subtask['task_id'] = $dst_task_id; - - if (! $db->table(SubtaskModel::TABLE)->save($subtask)) { - return false; - } - } - }); - } - - /** - * Convert a subtask to a task - * - * @access public - * @param integer $project_id - * @param integer $subtask_id - * @return integer - */ - public function convertToTask($project_id, $subtask_id) - { - $subtask = $this->getById($subtask_id); - - $task_id = $this->taskCreationModel->create(array( - 'project_id' => $project_id, - 'title' => $subtask['title'], - 'time_estimated' => $subtask['time_estimated'], - 'time_spent' => $subtask['time_spent'], - 'owner_id' => $subtask['user_id'], - )); - - if ($task_id !== false) { - $this->remove($subtask_id); - } - - return $task_id; - } -} diff --git a/sources/app/Model/SubtaskTimeTrackingModel.php b/sources/app/Model/SubtaskTimeTrackingModel.php deleted file mode 100644 index 062e594..0000000 --- a/sources/app/Model/SubtaskTimeTrackingModel.php +++ /dev/null @@ -1,298 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use DateTime; -use Kanboard\Core\Base; - -/** - * Subtask time tracking - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class SubtaskTimeTrackingModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'subtask_time_tracking'; - - /** - * Get query to check if a timer is started for the given user and subtask - * - * @access public - * @param integer $user_id User id - * @return string - */ - public function getTimerQuery($user_id) - { - return sprintf( - "SELECT %s FROM %s WHERE %s='%d' AND %s='0' AND %s=%s LIMIT 1", - $this->db->escapeIdentifier('start'), - $this->db->escapeIdentifier(self::TABLE), - $this->db->escapeIdentifier('user_id'), - $user_id, - $this->db->escapeIdentifier('end'), - $this->db->escapeIdentifier('subtask_id'), - SubtaskModel::TABLE.'.id' - ); - } - - /** - * Get query for user timesheet (pagination) - * - * @access public - * @param integer $user_id User id - * @return \PicoDb\Table - */ - public function getUserQuery($user_id) - { - return $this->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.id', - self::TABLE.'.subtask_id', - self::TABLE.'.end', - self::TABLE.'.start', - self::TABLE.'.time_spent', - SubtaskModel::TABLE.'.task_id', - SubtaskModel::TABLE.'.title AS subtask_title', - TaskModel::TABLE.'.title AS task_title', - TaskModel::TABLE.'.project_id', - TaskModel::TABLE.'.color_id' - ) - ->join(SubtaskModel::TABLE, 'id', 'subtask_id') - ->join(TaskModel::TABLE, 'id', 'task_id', SubtaskModel::TABLE) - ->eq(self::TABLE.'.user_id', $user_id); - } - - /** - * Get query for task timesheet (pagination) - * - * @access public - * @param integer $task_id Task id - * @return \PicoDb\Table - */ - public function getTaskQuery($task_id) - { - return $this->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.id', - self::TABLE.'.subtask_id', - self::TABLE.'.end', - self::TABLE.'.start', - self::TABLE.'.time_spent', - self::TABLE.'.user_id', - SubtaskModel::TABLE.'.task_id', - SubtaskModel::TABLE.'.title AS subtask_title', - TaskModel::TABLE.'.project_id', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name AS user_fullname' - ) - ->join(SubtaskModel::TABLE, 'id', 'subtask_id') - ->join(TaskModel::TABLE, 'id', 'task_id', SubtaskModel::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id', self::TABLE) - ->eq(TaskModel::TABLE.'.id', $task_id); - } - - /** - * Get query for project timesheet (pagination) - * - * @access public - * @param integer $project_id Project id - * @return \PicoDb\Table - */ - public function getProjectQuery($project_id) - { - return $this->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.id', - self::TABLE.'.subtask_id', - self::TABLE.'.end', - self::TABLE.'.start', - self::TABLE.'.time_spent', - self::TABLE.'.user_id', - SubtaskModel::TABLE.'.task_id', - SubtaskModel::TABLE.'.title AS subtask_title', - TaskModel::TABLE.'.project_id', - TaskModel::TABLE.'.color_id', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name AS user_fullname' - ) - ->join(SubtaskModel::TABLE, 'id', 'subtask_id') - ->join(TaskModel::TABLE, 'id', 'task_id', SubtaskModel::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id', self::TABLE) - ->eq(TaskModel::TABLE.'.project_id', $project_id) - ->asc(self::TABLE.'.id'); - } - - /** - * Get all recorded time slots for a given user - * - * @access public - * @param integer $user_id User id - * @return array - */ - public function getUserTimesheet($user_id) - { - return $this->db - ->table(self::TABLE) - ->eq('user_id', $user_id) - ->findAll(); - } - - /** - * Return true if a timer is started for this use and subtask - * - * @access public - * @param integer $subtask_id - * @param integer $user_id - * @return boolean - */ - public function hasTimer($subtask_id, $user_id) - { - return $this->db->table(self::TABLE)->eq('subtask_id', $subtask_id)->eq('user_id', $user_id)->eq('end', 0)->exists(); - } - - /** - * Log start time - * - * @access public - * @param integer $subtask_id - * @param integer $user_id - * @return boolean - */ - public function logStartTime($subtask_id, $user_id) - { - return - ! $this->hasTimer($subtask_id, $user_id) && - $this->db - ->table(self::TABLE) - ->insert(array('subtask_id' => $subtask_id, 'user_id' => $user_id, 'start' => time(), 'end' => 0)); - } - - /** - * Log end time - * - * @access public - * @param integer $subtask_id - * @param integer $user_id - * @return boolean - */ - public function logEndTime($subtask_id, $user_id) - { - $time_spent = $this->getTimeSpent($subtask_id, $user_id); - - if ($time_spent > 0) { - $this->updateSubtaskTimeSpent($subtask_id, $time_spent); - } - - return $this->db - ->table(self::TABLE) - ->eq('subtask_id', $subtask_id) - ->eq('user_id', $user_id) - ->eq('end', 0) - ->update(array( - 'end' => time(), - 'time_spent' => $time_spent, - )); - } - - /** - * Calculate the time spent when the clock is stopped - * - * @access public - * @param integer $subtask_id - * @param integer $user_id - * @return float - */ - public function getTimeSpent($subtask_id, $user_id) - { - $hook = 'model:subtask-time-tracking:calculate:time-spent'; - $start_time = $this->db - ->table(self::TABLE) - ->eq('subtask_id', $subtask_id) - ->eq('user_id', $user_id) - ->eq('end', 0) - ->findOneColumn('start'); - - if (empty($start_time)) { - return 0; - } - - $end = new DateTime; - $start = new DateTime; - $start->setTimestamp($start_time); - - if ($this->hook->exists($hook)) { - return $this->hook->first($hook, array( - 'user_id' => $user_id, - 'start' => $start, - 'end' => $end, - )); - } - - return $this->dateParser->getHours($start, $end); - } - - /** - * Update subtask time spent - * - * @access public - * @param integer $subtask_id - * @param float $time_spent - * @return bool - */ - public function updateSubtaskTimeSpent($subtask_id, $time_spent) - { - $subtask = $this->subtaskModel->getById($subtask_id); - - // Fire the event subtask.update - return $this->subtaskModel->update(array( - 'id' => $subtask['id'], - 'time_spent' => $subtask['time_spent'] + $time_spent, - 'task_id' => $subtask['task_id'], - ), false); - } - - /** - * Update task time tracking based on subtasks time tracking - * - * @access public - * @param integer $task_id Task id - * @return bool - */ - public function updateTaskTimeTracking($task_id) - { - $values = $this->calculateSubtaskTime($task_id); - - return $this->db - ->table(TaskModel::TABLE) - ->eq('id', $task_id) - ->update($values); - } - - /** - * Sum time spent and time estimated for all subtasks - * - * @access public - * @param integer $task_id Task id - * @return array - */ - public function calculateSubtaskTime($task_id) - { - return $this->db - ->table(SubtaskModel::TABLE) - ->eq('task_id', $task_id) - ->columns( - 'SUM(time_spent) AS time_spent', - 'SUM(time_estimated) AS time_estimated' - ) - ->findOne(); - } -} diff --git a/sources/app/Model/SwimlaneModel.php b/sources/app/Model/SwimlaneModel.php deleted file mode 100644 index f20bfa2..0000000 --- a/sources/app/Model/SwimlaneModel.php +++ /dev/null @@ -1,508 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Swimlanes - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class SwimlaneModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'swimlanes'; - - /** - * Value for active swimlanes - * - * @var integer - */ - const ACTIVE = 1; - - /** - * Value for inactive swimlanes - * - * @var integer - */ - const INACTIVE = 0; - - /** - * Get a swimlane by the id - * - * @access public - * @param integer $swimlane_id Swimlane id - * @return array - */ - public function getById($swimlane_id) - { - return $this->db->table(self::TABLE)->eq('id', $swimlane_id)->findOne(); - } - - /** - * Get the swimlane name by the id - * - * @access public - * @param integer $swimlane_id Swimlane id - * @return string - */ - public function getNameById($swimlane_id) - { - return $this->db->table(self::TABLE)->eq('id', $swimlane_id)->findOneColumn('name') ?: ''; - } - - /** - * Get a swimlane id by the project and the name - * - * @access public - * @param integer $project_id Project id - * @param string $name Name - * @return integer - */ - public function getIdByName($project_id, $name) - { - return (int) $this->db->table(self::TABLE) - ->eq('project_id', $project_id) - ->eq('name', $name) - ->findOneColumn('id'); - } - - /** - * Get a swimlane by the project and the name - * - * @access public - * @param integer $project_id Project id - * @param string $name Swimlane name - * @return array - */ - public function getByName($project_id, $name) - { - return $this->db->table(self::TABLE) - ->eq('project_id', $project_id) - ->eq('name', $name) - ->findOne(); - } - - /** - * Get first active swimlane for a project - * - * @access public - * @param integer $project_id - * @return array|null - */ - public function getFirstActiveSwimlane($project_id) - { - $swimlanes = $this->getSwimlanes($project_id); - - if (empty($swimlanes)) { - return null; - } - - return $swimlanes[0]; - } - - /** - * Get default swimlane properties - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getDefault($project_id) - { - $result = $this->db - ->table(ProjectModel::TABLE) - ->eq('id', $project_id) - ->columns('id', 'default_swimlane', 'show_default_swimlane') - ->findOne(); - - if ($result['default_swimlane'] === 'Default swimlane') { - $result['default_swimlane'] = t($result['default_swimlane']); - } - - return $result; - } - - /** - * Get all swimlanes for a given project - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getAll($project_id) - { - return $this->db - ->table(self::TABLE) - ->eq('project_id', $project_id) - ->orderBy('position', 'asc') - ->findAll(); - } - - /** - * Get the list of swimlanes by status - * - * @access public - * @param integer $project_id Project id - * @param integer $status Status - * @return array - */ - public function getAllByStatus($project_id, $status = self::ACTIVE) - { - $query = $this->db - ->table(self::TABLE) - ->eq('project_id', $project_id) - ->eq('is_active', $status); - - if ($status == self::ACTIVE) { - $query->asc('position'); - } else { - $query->asc('name'); - } - - return $query->findAll(); - } - - /** - * Get active swimlanes - * - * @access public - * @param integer $project_id Project id - * @return array - */ - public function getSwimlanes($project_id) - { - $swimlanes = $this->db - ->table(self::TABLE) - ->columns('id', 'name', 'description') - ->eq('project_id', $project_id) - ->eq('is_active', self::ACTIVE) - ->orderBy('position', 'asc') - ->findAll(); - - $defaultSwimlane = $this->db - ->table(ProjectModel::TABLE) - ->eq('id', $project_id) - ->eq('show_default_swimlane', 1) - ->findOneColumn('default_swimlane'); - - if ($defaultSwimlane) { - if ($defaultSwimlane === 'Default swimlane') { - $defaultSwimlane = t($defaultSwimlane); - } - - array_unshift($swimlanes, array('id' => 0, 'name' => $defaultSwimlane)); - } - - return $swimlanes; - } - - /** - * Get list of all swimlanes - * - * @access public - * @param integer $project_id Project id - * @param boolean $prepend Prepend default value - * @param boolean $only_active Return only active swimlanes - * @return array - */ - public function getList($project_id, $prepend = false, $only_active = false) - { - $swimlanes = array(); - $default = $this->db->table(ProjectModel::TABLE)->eq('id', $project_id)->eq('show_default_swimlane', 1)->findOneColumn('default_swimlane'); - - if ($prepend) { - $swimlanes[-1] = t('All swimlanes'); - } - - if (! empty($default)) { - $swimlanes[0] = $default === 'Default swimlane' ? t($default) : $default; - } - - return $swimlanes + $this->db - ->hashtable(self::TABLE) - ->eq('project_id', $project_id) - ->in('is_active', $only_active ? array(self::ACTIVE) : array(self::ACTIVE, self::INACTIVE)) - ->orderBy('position', 'asc') - ->getAll('id', 'name'); - } - - /** - * Add a new swimlane - * - * @access public - * @param array $values Form values - * @return integer|boolean - */ - public function create($values) - { - if (! $this->projectModel->exists($values['project_id'])) { - return 0; - } - - $values['position'] = $this->getLastPosition($values['project_id']); - return $this->db->table(self::TABLE)->persist($values); - } - - /** - * Update a swimlane - * - * @access public - * @param array $values Form values - * @return bool - */ - public function update(array $values) - { - return $this->db - ->table(self::TABLE) - ->eq('id', $values['id']) - ->update($values); - } - - /** - * Update the default swimlane - * - * @access public - * @param array $values Form values - * @return bool - */ - public function updateDefault(array $values) - { - return $this->db - ->table(ProjectModel::TABLE) - ->eq('id', $values['id']) - ->update(array( - 'default_swimlane' => $values['default_swimlane'], - 'show_default_swimlane' => $values['show_default_swimlane'], - )); - } - - /** - * Enable the default swimlane - * - * @access public - * @param integer $project_id - * @return bool - */ - public function enableDefault($project_id) - { - return $this->db - ->table(ProjectModel::TABLE) - ->eq('id', $project_id) - ->update(array( - 'show_default_swimlane' => 1, - )); - } - - /** - * Disable the default swimlane - * - * @access public - * @param integer $project_id - * @return bool - */ - public function disableDefault($project_id) - { - return $this->db - ->table(ProjectModel::TABLE) - ->eq('id', $project_id) - ->update(array( - 'show_default_swimlane' => 0, - )); - } - - /** - * Get the last position of a swimlane - * - * @access public - * @param integer $project_id - * @return integer - */ - public function getLastPosition($project_id) - { - return $this->db - ->table(self::TABLE) - ->eq('project_id', $project_id) - ->eq('is_active', 1) - ->count() + 1; - } - - /** - * Disable a swimlane - * - * @access public - * @param integer $project_id Project id - * @param integer $swimlane_id Swimlane id - * @return bool - */ - public function disable($project_id, $swimlane_id) - { - $result = $this->db - ->table(self::TABLE) - ->eq('id', $swimlane_id) - ->update(array( - 'is_active' => self::INACTIVE, - 'position' => 0, - )); - - if ($result) { - // Re-order positions - $this->updatePositions($project_id); - } - - return $result; - } - - /** - * Enable a swimlane - * - * @access public - * @param integer $project_id Project id - * @param integer $swimlane_id Swimlane id - * @return bool - */ - public function enable($project_id, $swimlane_id) - { - return $this->db - ->table(self::TABLE) - ->eq('id', $swimlane_id) - ->update(array( - 'is_active' => self::ACTIVE, - 'position' => $this->getLastPosition($project_id), - )); - } - - /** - * Remove a swimlane - * - * @access public - * @param integer $project_id Project id - * @param integer $swimlane_id Swimlane id - * @return bool - */ - public function remove($project_id, $swimlane_id) - { - $this->db->startTransaction(); - - // Tasks should not be assigned anymore to this swimlane - $this->db->table(TaskModel::TABLE)->eq('swimlane_id', $swimlane_id)->update(array('swimlane_id' => 0)); - - if (! $this->db->table(self::TABLE)->eq('id', $swimlane_id)->remove()) { - $this->db->cancelTransaction(); - return false; - } - - // Re-order positions - $this->updatePositions($project_id); - - $this->db->closeTransaction(); - - return true; - } - - /** - * Update swimlane positions after disabling or removing a swimlane - * - * @access public - * @param integer $project_id Project id - * @return boolean - */ - public function updatePositions($project_id) - { - $position = 0; - $swimlanes = $this->db - ->table(self::TABLE) - ->eq('project_id', $project_id) - ->eq('is_active', 1) - ->asc('position') - ->asc('id') - ->findAllByColumn('id'); - - if (! $swimlanes) { - return false; - } - - foreach ($swimlanes as $swimlane_id) { - $this->db->table(self::TABLE) - ->eq('id', $swimlane_id) - ->update(array('position' => ++$position)); - } - - return true; - } - - /** - * Change swimlane position - * - * @access public - * @param integer $project_id - * @param integer $swimlane_id - * @param integer $position - * @return boolean - */ - public function changePosition($project_id, $swimlane_id, $position) - { - if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('project_id', $project_id)->count()) { - return false; - } - - $swimlane_ids = $this->db->table(self::TABLE) - ->eq('is_active', 1) - ->eq('project_id', $project_id) - ->neq('id', $swimlane_id) - ->asc('position') - ->findAllByColumn('id'); - - $offset = 1; - $results = array(); - - foreach ($swimlane_ids as $current_swimlane_id) { - if ($offset == $position) { - $offset++; - } - - $results[] = $this->db->table(self::TABLE)->eq('id', $current_swimlane_id)->update(array('position' => $offset)); - $offset++; - } - - $results[] = $this->db->table(self::TABLE)->eq('id', $swimlane_id)->update(array('position' => $position)); - - return !in_array(false, $results, true); - } - - /** - * Duplicate Swimlane to project - * - * @access public - * @param integer $project_from Project Template - * @param integer $project_to Project that receives the copy - * @return integer|boolean - */ - - public function duplicate($project_from, $project_to) - { - $swimlanes = $this->getAll($project_from); - - foreach ($swimlanes as $swimlane) { - unset($swimlane['id']); - $swimlane['project_id'] = $project_to; - - if (! $this->db->table(self::TABLE)->save($swimlane)) { - return false; - } - } - - $default_swimlane = $this->getDefault($project_from); - $default_swimlane['id'] = $project_to; - - $this->updateDefault($default_swimlane); - - return true; - } -} diff --git a/sources/app/Model/TagDuplicationModel.php b/sources/app/Model/TagDuplicationModel.php deleted file mode 100644 index fb0d817..0000000 --- a/sources/app/Model/TagDuplicationModel.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Tag Duplication - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TagDuplicationModel extends Base -{ - /** - * Duplicate project tags to another project - * - * @access public - * @param integer $src_project_id - * @param integer $dst_project_id - * @return bool - */ - public function duplicate($src_project_id, $dst_project_id) - { - $tags = $this->tagModel->getAllByProject($src_project_id); - $results = array(); - - foreach ($tags as $tag) { - $results[] = $this->tagModel->create($dst_project_id, $tag['name']); - } - - return ! in_array(false, $results, true); - } - - /** - * Link tags to the new tasks - * - * @access public - * @param integer $src_task_id - * @param integer $dst_task_id - * @param integer $dst_project_id - */ - public function duplicateTaskTagsToAnotherProject($src_task_id, $dst_task_id, $dst_project_id) - { - $tags = $this->taskTagModel->getTagsByTask($src_task_id); - - foreach ($tags as $tag) { - $tag_id = $this->tagModel->getIdByName($dst_project_id, $tag['name']); - - if ($tag_id) { - $this->taskTagModel->associateTag($dst_task_id, $tag_id); - } - } - } - - /** - * Duplicate tags to the new task - * - * @access public - * @param integer $src_task_id - * @param integer $dst_task_id - */ - public function duplicateTaskTags($src_task_id, $dst_task_id) - { - $tags = $this->taskTagModel->getTagsByTask($src_task_id); - - foreach ($tags as $tag) { - $this->taskTagModel->associateTag($dst_task_id, $tag['id']); - } - } - - /** - * Remove tags that are not available in destination project - * - * @access public - * @param integer $task_id - * @param integer $dst_project_id - */ - public function syncTaskTagsToAnotherProject($task_id, $dst_project_id) - { - $tag_ids = $this->taskTagModel->getTagIdsByTaskNotAvailableInProject($task_id, $dst_project_id); - - foreach ($tag_ids as $tag_id) { - $this->taskTagModel->dissociateTag($task_id, $tag_id); - } - } -} diff --git a/sources/app/Model/TagModel.php b/sources/app/Model/TagModel.php deleted file mode 100644 index e85c5a8..0000000 --- a/sources/app/Model/TagModel.php +++ /dev/null @@ -1,180 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Class TagModel - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TagModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'tags'; - - /** - * Get all tags - * - * @access public - * @return array - */ - public function getAll() - { - return $this->db->table(self::TABLE)->asc('name')->findAll(); - } - - /** - * Get all tags by project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getAllByProject($project_id) - { - return $this->db->table(self::TABLE)->eq('project_id', $project_id)->asc('name')->findAll(); - } - - /** - * Get assignable tags for a project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getAssignableList($project_id) - { - return $this->db->hashtable(self::TABLE) - ->beginOr() - ->eq('project_id', $project_id) - ->eq('project_id', 0) - ->closeOr() - ->asc('name') - ->getAll('id', 'name'); - } - - /** - * Get one tag - * - * @access public - * @param integer $tag_id - * @return array|null - */ - public function getById($tag_id) - { - return $this->db->table(self::TABLE)->eq('id', $tag_id)->findOne(); - } - - /** - * Get tag id from tag name - * - * @access public - * @param int $project_id - * @param string $tag - * @return integer - */ - public function getIdByName($project_id, $tag) - { - return $this->db - ->table(self::TABLE) - ->beginOr() - ->eq('project_id', 0) - ->eq('project_id', $project_id) - ->closeOr() - ->ilike('name', $tag) - ->asc('project_id') - ->findOneColumn('id'); - } - - /** - * Return true if the tag exists - * - * @access public - * @param integer $project_id - * @param string $tag - * @param integer $tag_id - * @return boolean - */ - public function exists($project_id, $tag, $tag_id = 0) - { - return $this->db - ->table(self::TABLE) - ->neq('id', $tag_id) - ->beginOr() - ->eq('project_id', 0) - ->eq('project_id', $project_id) - ->closeOr() - ->ilike('name', $tag) - ->asc('project_id') - ->exists(); - } - - /** - * Return tag id and create a new tag if necessary - * - * @access public - * @param int $project_id - * @param string $tag - * @return bool|int - */ - public function findOrCreateTag($project_id, $tag) - { - $tag_id = $this->getIdByName($project_id, $tag); - - if (empty($tag_id)) { - $tag_id = $this->create($project_id, $tag); - } - - return $tag_id; - } - - /** - * Add a new tag - * - * @access public - * @param int $project_id - * @param string $tag - * @return bool|int - */ - public function create($project_id, $tag) - { - return $this->db->table(self::TABLE)->persist(array( - 'project_id' => $project_id, - 'name' => $tag, - )); - } - - /** - * Update a tag - * - * @access public - * @param integer $tag_id - * @param string $tag - * @return bool - */ - public function update($tag_id, $tag) - { - return $this->db->table(self::TABLE)->eq('id', $tag_id)->update(array( - 'name' => $tag, - )); - } - - /** - * Remove a tag - * - * @access public - * @param integer $tag_id - * @return bool - */ - public function remove($tag_id) - { - return $this->db->table(self::TABLE)->eq('id', $tag_id)->remove(); - } -} diff --git a/sources/app/Model/TaskAnalyticModel.php b/sources/app/Model/TaskAnalyticModel.php deleted file mode 100644 index 3d6fe8a..0000000 --- a/sources/app/Model/TaskAnalyticModel.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Task Analytic - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskAnalyticModel extends Base -{ - /** - * Get the time between date_creation and date_completed or now if empty - * - * @access public - * @param array $task - * @return integer - */ - public function getLeadTime(array $task) - { - return ($task['date_completed'] ?: time()) - $task['date_creation']; - } - - /** - * Get the time between date_started and date_completed or now if empty - * - * @access public - * @param array $task - * @return integer - */ - public function getCycleTime(array $task) - { - if (empty($task['date_started'])) { - return 0; - } - - return ($task['date_completed'] ?: time()) - $task['date_started']; - } - - /** - * Get the average time spent in each column - * - * @access public - * @param array $task - * @return array - */ - public function getTimeSpentByColumn(array $task) - { - $result = array(); - $columns = $this->columnModel->getList($task['project_id']); - $sums = $this->transitionModel->getTimeSpentByTask($task['id']); - - foreach ($columns as $column_id => $column_title) { - $time_spent = isset($sums[$column_id]) ? $sums[$column_id] : 0; - - if ($task['column_id'] == $column_id) { - $time_spent += ($task['date_completed'] ?: time()) - $task['date_moved']; - } - - $result[] = array( - 'id' => $column_id, - 'title' => $column_title, - 'time_spent' => $time_spent, - ); - } - - return $result; - } -} diff --git a/sources/app/Model/TaskCreationModel.php b/sources/app/Model/TaskCreationModel.php deleted file mode 100644 index cd70a02..0000000 --- a/sources/app/Model/TaskCreationModel.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Event\TaskEvent; - -/** - * Task Creation - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskCreationModel extends Base -{ - /** - * Create a task - * - * @access public - * @param array $values Form values - * @return integer - */ - public function create(array $values) - { - $position = empty($values['position']) ? 0 : $values['position']; - $tags = array(); - - if (isset($values['tags'])) { - $tags = $values['tags']; - unset($values['tags']); - } - - $this->prepare($values); - $task_id = $this->db->table(TaskModel::TABLE)->persist($values); - - if ($task_id !== false) { - if ($position > 0 && $values['position'] > 1) { - $this->taskPositionModel->movePosition($values['project_id'], $task_id, $values['column_id'], $position, $values['swimlane_id'], false); - } - - if (! empty($tags)) { - $this->taskTagModel->save($values['project_id'], $task_id, $tags); - } - - $this->fireEvents($task_id, $values); - } - - return (int) $task_id; - } - - /** - * Prepare data - * - * @access public - * @param array $values Form values - */ - public function prepare(array &$values) - { - $values = $this->dateParser->convert($values, array('date_due')); - $values = $this->dateParser->convert($values, array('date_started'), true); - - $this->helper->model->removeFields($values, array('another_task')); - $this->helper->model->resetFields($values, array('creator_id', 'owner_id', 'swimlane_id', 'date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent')); - - if (empty($values['column_id'])) { - $values['column_id'] = $this->columnModel->getFirstColumnId($values['project_id']); - } - - if (empty($values['color_id'])) { - $values['color_id'] = $this->colorModel->getDefaultColor(); - } - - if (empty($values['title'])) { - $values['title'] = t('Untitled'); - } - - if ($this->userSession->isLogged()) { - $values['creator_id'] = $this->userSession->getId(); - } - - $values['swimlane_id'] = empty($values['swimlane_id']) ? 0 : $values['swimlane_id']; - $values['date_creation'] = time(); - $values['date_modification'] = $values['date_creation']; - $values['date_moved'] = $values['date_creation']; - $values['position'] = $this->taskFinderModel->countByColumnAndSwimlaneId($values['project_id'], $values['column_id'], $values['swimlane_id']) + 1; - } - - /** - * Fire events - * - * @access private - * @param integer $task_id Task id - * @param array $values Form values - */ - private function fireEvents($task_id, array $values) - { - $event = new TaskEvent(array('task_id' => $task_id) + $values); - - $this->logger->debug('Event fired: '.TaskModel::EVENT_CREATE_UPDATE); - $this->logger->debug('Event fired: '.TaskModel::EVENT_CREATE); - - $this->dispatcher->dispatch(TaskModel::EVENT_CREATE_UPDATE, $event); - $this->dispatcher->dispatch(TaskModel::EVENT_CREATE, $event); - - if (! empty($values['description'])) { - $this->userMentionModel->fireEvents($values['description'], TaskModel::EVENT_USER_MENTION, $event); - } - } -} diff --git a/sources/app/Model/TaskDuplicationModel.php b/sources/app/Model/TaskDuplicationModel.php deleted file mode 100644 index c907965..0000000 --- a/sources/app/Model/TaskDuplicationModel.php +++ /dev/null @@ -1,145 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Task Duplication - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskDuplicationModel extends Base -{ - /** - * Fields to copy when duplicating a task - * - * @access protected - * @var string[] - */ - protected $fieldsToDuplicate = array( - 'title', - 'description', - 'date_due', - 'color_id', - 'project_id', - 'column_id', - 'owner_id', - 'score', - 'priority', - 'category_id', - 'time_estimated', - 'swimlane_id', - 'recurrence_status', - 'recurrence_trigger', - 'recurrence_factor', - 'recurrence_timeframe', - 'recurrence_basedate', - ); - - /** - * Duplicate a task to the same project - * - * @access public - * @param integer $task_id Task id - * @return boolean|integer Duplicated task id - */ - public function duplicate($task_id) - { - $new_task_id = $this->save($task_id, $this->copyFields($task_id)); - - if ($new_task_id !== false) { - $this->tagDuplicationModel->duplicateTaskTags($task_id, $new_task_id); - } - - return $new_task_id; - } - - /** - * Check if the assignee and the category are available in the destination project - * - * @access public - * @param array $values - * @return array - */ - public function checkDestinationProjectValues(array &$values) - { - // Check if the assigned user is allowed for the destination project - if ($values['owner_id'] > 0 && ! $this->projectPermissionModel->isUserAllowed($values['project_id'], $values['owner_id'])) { - $values['owner_id'] = 0; - } - - // Check if the category exists for the destination project - if ($values['category_id'] > 0) { - $values['category_id'] = $this->categoryModel->getIdByName( - $values['project_id'], - $this->categoryModel->getNameById($values['category_id']) - ); - } - - // Check if the swimlane exists for the destination project - if ($values['swimlane_id'] > 0) { - $values['swimlane_id'] = $this->swimlaneModel->getIdByName( - $values['project_id'], - $this->swimlaneModel->getNameById($values['swimlane_id']) - ); - } - - // Check if the column exists for the destination project - if ($values['column_id'] > 0) { - $values['column_id'] = $this->columnModel->getColumnIdByTitle( - $values['project_id'], - $this->columnModel->getColumnTitleById($values['column_id']) - ); - - $values['column_id'] = $values['column_id'] ?: $this->columnModel->getFirstColumnId($values['project_id']); - } - - // Check if priority exists for destination project - $values['priority'] = $this->projectTaskPriorityModel->getPriorityForProject( - $values['project_id'], - empty($values['priority']) ? 0 : $values['priority'] - ); - - return $values; - } - - /** - * Duplicate fields for the new task - * - * @access protected - * @param integer $task_id Task id - * @return array - */ - protected function copyFields($task_id) - { - $task = $this->taskFinderModel->getById($task_id); - $values = array(); - - foreach ($this->fieldsToDuplicate as $field) { - $values[$field] = $task[$field]; - } - - return $values; - } - - /** - * Create the new task and duplicate subtasks - * - * @access protected - * @param integer $task_id Task id - * @param array $values Form values - * @return boolean|integer - */ - protected function save($task_id, array $values) - { - $new_task_id = $this->taskCreationModel->create($values); - - if ($new_task_id !== false) { - $this->subtaskModel->duplicate($task_id, $new_task_id); - } - - return $new_task_id; - } -} diff --git a/sources/app/Model/TaskExternalLinkModel.php b/sources/app/Model/TaskExternalLinkModel.php deleted file mode 100644 index 220b9c6..0000000 --- a/sources/app/Model/TaskExternalLinkModel.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Task External Link Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskExternalLinkModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'task_has_external_links'; - - /** - * Get all links - * - * @access public - * @param integer $task_id - * @return array - */ - public function getAll($task_id) - { - $types = $this->externalLinkManager->getTypes(); - - $links = $this->db->table(self::TABLE) - ->columns(self::TABLE.'.*', UserModel::TABLE.'.name AS creator_name', UserModel::TABLE.'.username AS creator_username') - ->eq('task_id', $task_id) - ->asc('title') - ->join(UserModel::TABLE, 'id', 'creator_id') - ->findAll(); - - foreach ($links as &$link) { - $link['dependency_label'] = $this->externalLinkManager->getDependencyLabel($link['link_type'], $link['dependency']); - $link['type'] = isset($types[$link['link_type']]) ? $types[$link['link_type']] : t('Unknown'); - } - - return $links; - } - - /** - * Get link - * - * @access public - * @param integer $link_id - * @return array - */ - public function getById($link_id) - { - return $this->db->table(self::TABLE)->eq('id', $link_id)->findOne(); - } - - /** - * Add a new link in the database - * - * @access public - * @param array $values Form values - * @return boolean|integer - */ - public function create(array $values) - { - unset($values['id']); - $values['creator_id'] = $this->userSession->getId(); - $values['date_creation'] = time(); - $values['date_modification'] = $values['date_creation']; - - return $this->db->table(self::TABLE)->persist($values); - } - - /** - * Modify external link - * - * @access public - * @param array $values Form values - * @return boolean - */ - public function update(array $values) - { - $values['date_modification'] = time(); - return $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values); - } - - /** - * Remove a link - * - * @access public - * @param integer $link_id - * @return boolean - */ - public function remove($link_id) - { - return $this->db->table(self::TABLE)->eq('id', $link_id)->remove(); - } -} diff --git a/sources/app/Model/TaskFileModel.php b/sources/app/Model/TaskFileModel.php deleted file mode 100644 index 7603019..0000000 --- a/sources/app/Model/TaskFileModel.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * Task File Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskFileModel extends FileModel -{ - /** - * Table name - * - * @var string - */ - const TABLE = 'task_has_files'; - - /** - * Events - * - * @var string - */ - const EVENT_CREATE = 'task.file.create'; - - /** - * Get the table - * - * @abstract - * @access protected - * @return string - */ - protected function getTable() - { - return self::TABLE; - } - - /** - * Define the foreign key - * - * @abstract - * @access protected - * @return string - */ - protected function getForeignKey() - { - return 'task_id'; - } - - /** - * Define the path prefix - * - * @abstract - * @access protected - * @return string - */ - protected function getPathPrefix() - { - return 'tasks'; - } - - /** - * Get event name - * - * @abstract - * @access protected - * @return string - */ - protected function getEventName() - { - return self::EVENT_CREATE; - } - - /** - * Get projectId from fileId - * - * @access public - * @param integer $file_id - * @return integer - */ - public function getProjectId($file_id) - { - return $this->db - ->table(self::TABLE) - ->eq(self::TABLE.'.id', $file_id) - ->join(TaskModel::TABLE, 'id', 'task_id') - ->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0; - } - - /** - * Handle screenshot upload - * - * @access public - * @param integer $task_id Task id - * @param string $blob Base64 encoded image - * @return bool|integer - */ - public function uploadScreenshot($task_id, $blob) - { - $original_filename = e('Screenshot taken %s', $this->helper->dt->datetime(time())).'.png'; - return $this->uploadContent($task_id, $original_filename, $blob); - } -} diff --git a/sources/app/Model/TaskFinderModel.php b/sources/app/Model/TaskFinderModel.php deleted file mode 100644 index 0e8585e..0000000 --- a/sources/app/Model/TaskFinderModel.php +++ /dev/null @@ -1,459 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use PDO; -use Kanboard\Core\Base; - -/** - * Task Finder model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskFinderModel extends Base -{ - /** - * Get query for project user overview - * - * @access public - * @param array $project_ids - * @param integer $is_active - * @return \PicoDb\Table - */ - public function getProjectUserOverviewQuery(array $project_ids, $is_active) - { - if (empty($project_ids)) { - $project_ids = array(-1); - } - - return $this->db - ->table(TaskModel::TABLE) - ->columns( - TaskModel::TABLE.'.id', - TaskModel::TABLE.'.title', - TaskModel::TABLE.'.date_due', - TaskModel::TABLE.'.date_started', - TaskModel::TABLE.'.project_id', - TaskModel::TABLE.'.color_id', - TaskModel::TABLE.'.priority', - TaskModel::TABLE.'.time_spent', - TaskModel::TABLE.'.time_estimated', - ProjectModel::TABLE.'.name AS project_name', - ColumnModel::TABLE.'.title AS column_name', - UserModel::TABLE.'.username AS assignee_username', - UserModel::TABLE.'.name AS assignee_name' - ) - ->eq(TaskModel::TABLE.'.is_active', $is_active) - ->in(ProjectModel::TABLE.'.id', $project_ids) - ->join(ProjectModel::TABLE, 'id', 'project_id') - ->join(ColumnModel::TABLE, 'id', 'column_id', TaskModel::TABLE) - ->join(UserModel::TABLE, 'id', 'owner_id', TaskModel::TABLE); - } - - /** - * Get query for assigned user tasks - * - * @access public - * @param integer $user_id User id - * @return \PicoDb\Table - */ - public function getUserQuery($user_id) - { - return $this->db - ->table(TaskModel::TABLE) - ->columns( - 'tasks.id', - 'tasks.title', - 'tasks.date_due', - 'tasks.date_creation', - 'tasks.project_id', - 'tasks.color_id', - 'tasks.priority', - 'tasks.time_spent', - 'tasks.time_estimated', - 'tasks.is_active', - 'tasks.creator_id', - 'projects.name AS project_name', - 'columns.title AS column_title' - ) - ->join(ProjectModel::TABLE, 'id', 'project_id') - ->join(ColumnModel::TABLE, 'id', 'column_id') - ->eq(TaskModel::TABLE.'.owner_id', $user_id) - ->eq(TaskModel::TABLE.'.is_active', TaskModel::STATUS_OPEN) - ->eq(ProjectModel::TABLE.'.is_active', ProjectModel::ACTIVE); - } - - /** - * Extended query - * - * @access public - * @return \PicoDb\Table - */ - public function getExtendedQuery() - { - return $this->db - ->table(TaskModel::TABLE) - ->columns( - '(SELECT COUNT(*) FROM '.CommentModel::TABLE.' WHERE task_id=tasks.id) AS nb_comments', - '(SELECT COUNT(*) FROM '.TaskFileModel::TABLE.' WHERE task_id=tasks.id) AS nb_files', - '(SELECT COUNT(*) FROM '.SubtaskModel::TABLE.' WHERE '.SubtaskModel::TABLE.'.task_id=tasks.id) AS nb_subtasks', - '(SELECT COUNT(*) FROM '.SubtaskModel::TABLE.' WHERE '.SubtaskModel::TABLE.'.task_id=tasks.id AND status=2) AS nb_completed_subtasks', - '(SELECT COUNT(*) FROM '.TaskLinkModel::TABLE.' WHERE '.TaskLinkModel::TABLE.'.task_id = tasks.id) AS nb_links', - '(SELECT COUNT(*) FROM '.TaskExternalLinkModel::TABLE.' WHERE '.TaskExternalLinkModel::TABLE.'.task_id = tasks.id) AS nb_external_links', - '(SELECT DISTINCT 1 FROM '.TaskLinkModel::TABLE.' WHERE '.TaskLinkModel::TABLE.'.task_id = tasks.id AND '.TaskLinkModel::TABLE.'.link_id = 9) AS is_milestone', - 'tasks.id', - 'tasks.reference', - 'tasks.title', - 'tasks.description', - 'tasks.date_creation', - 'tasks.date_modification', - 'tasks.date_completed', - 'tasks.date_started', - 'tasks.date_due', - 'tasks.color_id', - 'tasks.project_id', - 'tasks.column_id', - 'tasks.swimlane_id', - 'tasks.owner_id', - 'tasks.creator_id', - 'tasks.position', - 'tasks.is_active', - 'tasks.score', - 'tasks.category_id', - 'tasks.priority', - 'tasks.date_moved', - 'tasks.recurrence_status', - 'tasks.recurrence_trigger', - 'tasks.recurrence_factor', - 'tasks.recurrence_timeframe', - 'tasks.recurrence_basedate', - 'tasks.recurrence_parent', - 'tasks.recurrence_child', - 'tasks.time_estimated', - 'tasks.time_spent', - UserModel::TABLE.'.username AS assignee_username', - UserModel::TABLE.'.name AS assignee_name', - UserModel::TABLE.'.email AS assignee_email', - UserModel::TABLE.'.avatar_path AS assignee_avatar_path', - CategoryModel::TABLE.'.name AS category_name', - CategoryModel::TABLE.'.description AS category_description', - ColumnModel::TABLE.'.title AS column_name', - ColumnModel::TABLE.'.position AS column_position', - SwimlaneModel::TABLE.'.name AS swimlane_name', - ProjectModel::TABLE.'.default_swimlane', - ProjectModel::TABLE.'.name AS project_name' - ) - ->join(UserModel::TABLE, 'id', 'owner_id', TaskModel::TABLE) - ->left(UserModel::TABLE, 'uc', 'id', TaskModel::TABLE, 'creator_id') - ->join(CategoryModel::TABLE, 'id', 'category_id', TaskModel::TABLE) - ->join(ColumnModel::TABLE, 'id', 'column_id', TaskModel::TABLE) - ->join(SwimlaneModel::TABLE, 'id', 'swimlane_id', TaskModel::TABLE) - ->join(ProjectModel::TABLE, 'id', 'project_id', TaskModel::TABLE); - } - - /** - * Get all tasks for a given project and status - * - * @access public - * @param integer $project_id Project id - * @param integer $status_id Status id - * @return array - */ - public function getAll($project_id, $status_id = TaskModel::STATUS_OPEN) - { - return $this->db - ->table(TaskModel::TABLE) - ->eq(TaskModel::TABLE.'.project_id', $project_id) - ->eq(TaskModel::TABLE.'.is_active', $status_id) - ->asc(TaskModel::TABLE.'.id') - ->findAll(); - } - - /** - * Get all tasks for a given project and status - * - * @access public - * @param integer $project_id - * @param array $status - * @return array - */ - public function getAllIds($project_id, array $status = array(TaskModel::STATUS_OPEN)) - { - return $this->db - ->table(TaskModel::TABLE) - ->eq(TaskModel::TABLE.'.project_id', $project_id) - ->in(TaskModel::TABLE.'.is_active', $status) - ->asc(TaskModel::TABLE.'.id') - ->findAllByColumn(TaskModel::TABLE.'.id'); - } - - /** - * Get overdue tasks query - * - * @access public - * @return \PicoDb\Table - */ - public function getOverdueTasksQuery() - { - return $this->db->table(TaskModel::TABLE) - ->columns( - TaskModel::TABLE.'.id', - TaskModel::TABLE.'.title', - TaskModel::TABLE.'.date_due', - TaskModel::TABLE.'.project_id', - TaskModel::TABLE.'.creator_id', - TaskModel::TABLE.'.owner_id', - ProjectModel::TABLE.'.name AS project_name', - UserModel::TABLE.'.username AS assignee_username', - UserModel::TABLE.'.name AS assignee_name' - ) - ->join(ProjectModel::TABLE, 'id', 'project_id') - ->join(UserModel::TABLE, 'id', 'owner_id') - ->eq(ProjectModel::TABLE.'.is_active', 1) - ->eq(TaskModel::TABLE.'.is_active', 1) - ->neq(TaskModel::TABLE.'.date_due', 0) - ->lte(TaskModel::TABLE.'.date_due', mktime(23, 59, 59)); - } - - /** - * Get a list of overdue tasks for all projects - * - * @access public - * @return array - */ - public function getOverdueTasks() - { - return $this->getOverdueTasksQuery()->findAll(); - } - - /** - * Get a list of overdue tasks by project - * - * @access public - * @param integer $project_id - * @return array - */ - public function getOverdueTasksByProject($project_id) - { - return $this->getOverdueTasksQuery()->eq(TaskModel::TABLE.'.project_id', $project_id)->findAll(); - } - - /** - * Get a list of overdue tasks by user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getOverdueTasksByUser($user_id) - { - return $this->getOverdueTasksQuery()->eq(TaskModel::TABLE.'.owner_id', $user_id)->findAll(); - } - - /** - * Get project id for a given task - * - * @access public - * @param integer $task_id Task id - * @return integer - */ - public function getProjectId($task_id) - { - return (int) $this->db->table(TaskModel::TABLE)->eq('id', $task_id)->findOneColumn('project_id') ?: 0; - } - - /** - * Fetch a task by the id - * - * @access public - * @param integer $task_id Task id - * @return array - */ - public function getById($task_id) - { - return $this->db->table(TaskModel::TABLE)->eq('id', $task_id)->findOne(); - } - - /** - * Fetch a task by the reference (external id) - * - * @access public - * @param integer $project_id Project id - * @param string $reference Task reference - * @return array - */ - public function getByReference($project_id, $reference) - { - return $this->db->table(TaskModel::TABLE)->eq('project_id', $project_id)->eq('reference', $reference)->findOne(); - } - - /** - * Get task details (fetch more information from other tables) - * - * @access public - * @param integer $task_id Task id - * @return array - */ - public function getDetails($task_id) - { - $sql = ' - SELECT - tasks.id, - tasks.reference, - tasks.title, - tasks.description, - tasks.date_creation, - tasks.date_completed, - tasks.date_modification, - tasks.date_due, - tasks.date_started, - tasks.time_estimated, - tasks.time_spent, - tasks.color_id, - tasks.project_id, - tasks.column_id, - tasks.owner_id, - tasks.creator_id, - tasks.position, - tasks.is_active, - tasks.score, - tasks.category_id, - tasks.priority, - tasks.swimlane_id, - tasks.date_moved, - tasks.recurrence_status, - tasks.recurrence_trigger, - tasks.recurrence_factor, - tasks.recurrence_timeframe, - tasks.recurrence_basedate, - tasks.recurrence_parent, - tasks.recurrence_child, - project_has_categories.name AS category_name, - swimlanes.name AS swimlane_name, - projects.name AS project_name, - projects.default_swimlane, - columns.title AS column_title, - users.username AS assignee_username, - users.name AS assignee_name, - creators.username AS creator_username, - creators.name AS creator_name - FROM tasks - LEFT JOIN users ON users.id = tasks.owner_id - LEFT JOIN users AS creators ON creators.id = tasks.creator_id - LEFT JOIN project_has_categories ON project_has_categories.id = tasks.category_id - LEFT JOIN projects ON projects.id = tasks.project_id - LEFT JOIN columns ON columns.id = tasks.column_id - LEFT JOIN swimlanes ON swimlanes.id = tasks.swimlane_id - WHERE tasks.id = ? - '; - - $rq = $this->db->execute($sql, array($task_id)); - return $rq->fetch(PDO::FETCH_ASSOC); - } - - /** - * Get iCal query - * - * @access public - * @return \PicoDb\Table - */ - public function getICalQuery() - { - return $this->db->table(TaskModel::TABLE) - ->left(UserModel::TABLE, 'ua', 'id', TaskModel::TABLE, 'owner_id') - ->left(UserModel::TABLE, 'uc', 'id', TaskModel::TABLE, 'creator_id') - ->columns( - TaskModel::TABLE.'.*', - 'ua.email AS assignee_email', - 'ua.name AS assignee_name', - 'ua.username AS assignee_username', - 'uc.email AS creator_email', - 'uc.name AS creator_name', - 'uc.username AS creator_username' - ); - } - - /** - * Count all tasks for a given project and status - * - * @access public - * @param integer $project_id Project id - * @param array $status List of status id - * @return integer - */ - public function countByProjectId($project_id, array $status = array(TaskModel::STATUS_OPEN, TaskModel::STATUS_CLOSED)) - { - return $this->db - ->table(TaskModel::TABLE) - ->eq('project_id', $project_id) - ->in('is_active', $status) - ->count(); - } - - /** - * Count the number of tasks for a given column and status - * - * @access public - * @param integer $project_id Project id - * @param integer $column_id Column id - * @return integer - */ - public function countByColumnId($project_id, $column_id) - { - return $this->db - ->table(TaskModel::TABLE) - ->eq('project_id', $project_id) - ->eq('column_id', $column_id) - ->eq('is_active', 1) - ->count(); - } - - /** - * Count the number of tasks for a given column and swimlane - * - * @access public - * @param integer $project_id Project id - * @param integer $column_id Column id - * @param integer $swimlane_id Swimlane id - * @return integer - */ - public function countByColumnAndSwimlaneId($project_id, $column_id, $swimlane_id) - { - return $this->db - ->table(TaskModel::TABLE) - ->eq('project_id', $project_id) - ->eq('column_id', $column_id) - ->eq('swimlane_id', $swimlane_id) - ->eq('is_active', 1) - ->count(); - } - - /** - * Return true if the task exists - * - * @access public - * @param integer $task_id Task id - * @return boolean - */ - public function exists($task_id) - { - return $this->db->table(TaskModel::TABLE)->eq('id', $task_id)->exists(); - } - - /** - * Get project token - * - * @access public - * @param integer $task_id - * @return string - */ - public function getProjectToken($task_id) - { - return $this->db - ->table(TaskModel::TABLE) - ->eq(TaskModel::TABLE.'.id', $task_id) - ->join(ProjectModel::TABLE, 'id', 'project_id') - ->findOneColumn(ProjectModel::TABLE.'.token'); - } -} diff --git a/sources/app/Model/TaskLinkModel.php b/sources/app/Model/TaskLinkModel.php deleted file mode 100644 index 09978ea..0000000 --- a/sources/app/Model/TaskLinkModel.php +++ /dev/null @@ -1,281 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Event\TaskLinkEvent; - -/** - * TaskLink model - * - * @package Kanboard\Model - * @author Olivier Maridat - * @author Frederic Guillot - */ -class TaskLinkModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'task_has_links'; - - /** - * Events - * - * @var string - */ - const EVENT_CREATE_UPDATE = 'tasklink.create_update'; - - /** - * Get projectId from $task_link_id - * - * @access public - * @param integer $task_link_id - * @return integer - */ - public function getProjectId($task_link_id) - { - return $this->db - ->table(self::TABLE) - ->eq(self::TABLE.'.id', $task_link_id) - ->join(TaskModel::TABLE, 'id', 'task_id') - ->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0; - } - - /** - * Get a task link - * - * @access public - * @param integer $task_link_id Task link id - * @return array - */ - public function getById($task_link_id) - { - return $this->db->table(self::TABLE)->eq('id', $task_link_id)->findOne(); - } - - /** - * Get the opposite task link (use the unique index task_has_links_unique) - * - * @access public - * @param array $task_link - * @return array - */ - public function getOppositeTaskLink(array $task_link) - { - $opposite_link_id = $this->linkModel->getOppositeLinkId($task_link['link_id']); - - return $this->db->table(self::TABLE) - ->eq('opposite_task_id', $task_link['task_id']) - ->eq('task_id', $task_link['opposite_task_id']) - ->eq('link_id', $opposite_link_id) - ->findOne(); - } - - /** - * Get all links attached to a task - * - * @access public - * @param integer $task_id Task id - * @return array - */ - public function getAll($task_id) - { - return $this->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.id', - self::TABLE.'.opposite_task_id AS task_id', - LinkModel::TABLE.'.label', - TaskModel::TABLE.'.title', - TaskModel::TABLE.'.is_active', - TaskModel::TABLE.'.project_id', - TaskModel::TABLE.'.column_id', - TaskModel::TABLE.'.color_id', - TaskModel::TABLE.'.time_spent AS task_time_spent', - TaskModel::TABLE.'.time_estimated AS task_time_estimated', - TaskModel::TABLE.'.owner_id AS task_assignee_id', - UserModel::TABLE.'.username AS task_assignee_username', - UserModel::TABLE.'.name AS task_assignee_name', - ColumnModel::TABLE.'.title AS column_title', - ProjectModel::TABLE.'.name AS project_name' - ) - ->eq(self::TABLE.'.task_id', $task_id) - ->join(LinkModel::TABLE, 'id', 'link_id') - ->join(TaskModel::TABLE, 'id', 'opposite_task_id') - ->join(ColumnModel::TABLE, 'id', 'column_id', TaskModel::TABLE) - ->join(UserModel::TABLE, 'id', 'owner_id', TaskModel::TABLE) - ->join(ProjectModel::TABLE, 'id', 'project_id', TaskModel::TABLE) - ->asc(LinkModel::TABLE.'.id') - ->desc(ColumnModel::TABLE.'.position') - ->desc(TaskModel::TABLE.'.is_active') - ->asc(TaskModel::TABLE.'.position') - ->asc(TaskModel::TABLE.'.id') - ->findAll(); - } - - /** - * Get all links attached to a task grouped by label - * - * @access public - * @param integer $task_id Task id - * @return array - */ - public function getAllGroupedByLabel($task_id) - { - $links = $this->getAll($task_id); - $result = array(); - - foreach ($links as $link) { - if (! isset($result[$link['label']])) { - $result[$link['label']] = array(); - } - - $result[$link['label']][] = $link; - } - - return $result; - } - - /** - * Publish events - * - * @access private - * @param array $events - */ - private function fireEvents(array $events) - { - foreach ($events as $event) { - $event['project_id'] = $this->taskFinderModel->getProjectId($event['task_id']); - $this->container['dispatcher']->dispatch(self::EVENT_CREATE_UPDATE, new TaskLinkEvent($event)); - } - } - - /** - * Create a new link - * - * @access public - * @param integer $task_id Task id - * @param integer $opposite_task_id Opposite task id - * @param integer $link_id Link id - * @return integer Task link id - */ - public function create($task_id, $opposite_task_id, $link_id) - { - $events = array(); - $this->db->startTransaction(); - - // Get opposite link - $opposite_link_id = $this->linkModel->getOppositeLinkId($link_id); - - $values = array( - 'task_id' => $task_id, - 'opposite_task_id' => $opposite_task_id, - 'link_id' => $link_id, - ); - - // Create the original task link - $this->db->table(self::TABLE)->insert($values); - $task_link_id = $this->db->getLastId(); - $events[] = $values; - - // Create the opposite task link - $values = array( - 'task_id' => $opposite_task_id, - 'opposite_task_id' => $task_id, - 'link_id' => $opposite_link_id, - ); - - $this->db->table(self::TABLE)->insert($values); - $events[] = $values; - - $this->db->closeTransaction(); - - $this->fireEvents($events); - - return (int) $task_link_id; - } - - /** - * Update a task link - * - * @access public - * @param integer $task_link_id Task link id - * @param integer $task_id Task id - * @param integer $opposite_task_id Opposite task id - * @param integer $link_id Link id - * @return boolean - */ - public function update($task_link_id, $task_id, $opposite_task_id, $link_id) - { - $events = array(); - $this->db->startTransaction(); - - // Get original task link - $task_link = $this->getById($task_link_id); - - // Find opposite task link - $opposite_task_link = $this->getOppositeTaskLink($task_link); - - // Get opposite link - $opposite_link_id = $this->linkModel->getOppositeLinkId($link_id); - - // Update the original task link - $values = array( - 'task_id' => $task_id, - 'opposite_task_id' => $opposite_task_id, - 'link_id' => $link_id, - ); - - $rs1 = $this->db->table(self::TABLE)->eq('id', $task_link_id)->update($values); - $events[] = $values; - - // Update the opposite link - $values = array( - 'task_id' => $opposite_task_id, - 'opposite_task_id' => $task_id, - 'link_id' => $opposite_link_id, - ); - - $rs2 = $this->db->table(self::TABLE)->eq('id', $opposite_task_link['id'])->update($values); - $events[] = $values; - - $this->db->closeTransaction(); - - if ($rs1 && $rs2) { - $this->fireEvents($events); - return true; - } - - return false; - } - - /** - * Remove a link between two tasks - * - * @access public - * @param integer $task_link_id - * @return boolean - */ - public function remove($task_link_id) - { - $this->db->startTransaction(); - - $link = $this->getById($task_link_id); - $link_id = $this->linkModel->getOppositeLinkId($link['link_id']); - - $this->db->table(self::TABLE)->eq('id', $task_link_id)->remove(); - - $this->db - ->table(self::TABLE) - ->eq('opposite_task_id', $link['task_id']) - ->eq('task_id', $link['opposite_task_id']) - ->eq('link_id', $link_id)->remove(); - - $this->db->closeTransaction(); - - return true; - } -} diff --git a/sources/app/Model/TaskMetadataModel.php b/sources/app/Model/TaskMetadataModel.php deleted file mode 100644 index dc3f56e..0000000 --- a/sources/app/Model/TaskMetadataModel.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * Task Metadata - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskMetadataModel extends MetadataModel -{ - /** - * Get the table - * - * @abstract - * @access protected - * @return string - */ - protected function getTable() - { - return 'task_has_metadata'; - } - - /** - * Define the entity key - * - * @access protected - * @return string - */ - protected function getEntityKey() - { - return 'task_id'; - } -} diff --git a/sources/app/Model/TaskModel.php b/sources/app/Model/TaskModel.php deleted file mode 100644 index 5cddb50..0000000 --- a/sources/app/Model/TaskModel.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Task Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'tasks'; - - /** - * Task status - * - * @var integer - */ - const STATUS_OPEN = 1; - const STATUS_CLOSED = 0; - - /** - * Events - * - * @var string - */ - const EVENT_MOVE_PROJECT = 'task.move.project'; - const EVENT_MOVE_COLUMN = 'task.move.column'; - const EVENT_MOVE_POSITION = 'task.move.position'; - const EVENT_MOVE_SWIMLANE = 'task.move.swimlane'; - const EVENT_UPDATE = 'task.update'; - const EVENT_CREATE = 'task.create'; - const EVENT_CLOSE = 'task.close'; - const EVENT_OPEN = 'task.open'; - const EVENT_CREATE_UPDATE = 'task.create_update'; - const EVENT_ASSIGNEE_CHANGE = 'task.assignee_change'; - const EVENT_OVERDUE = 'task.overdue'; - const EVENT_USER_MENTION = 'task.user.mention'; - const EVENT_DAILY_CRONJOB = 'task.cronjob.daily'; - - /** - * Recurrence: status - * - * @var integer - */ - const RECURRING_STATUS_NONE = 0; - const RECURRING_STATUS_PENDING = 1; - const RECURRING_STATUS_PROCESSED = 2; - - /** - * Recurrence: trigger - * - * @var integer - */ - const RECURRING_TRIGGER_FIRST_COLUMN = 0; - const RECURRING_TRIGGER_LAST_COLUMN = 1; - const RECURRING_TRIGGER_CLOSE = 2; - - /** - * Recurrence: timeframe - * - * @var integer - */ - const RECURRING_TIMEFRAME_DAYS = 0; - const RECURRING_TIMEFRAME_MONTHS = 1; - const RECURRING_TIMEFRAME_YEARS = 2; - - /** - * Recurrence: base date used to calculate new due date - * - * @var integer - */ - const RECURRING_BASEDATE_DUEDATE = 0; - const RECURRING_BASEDATE_TRIGGERDATE = 1; - - /** - * Remove a task - * - * @access public - * @param integer $task_id Task id - * @return boolean - */ - public function remove($task_id) - { - if (!$this->taskFinderModel->exists($task_id)) { - return false; - } - - $this->taskFileModel->removeAll($task_id); - - return $this->db->table(self::TABLE)->eq('id', $task_id)->remove(); - } - - /** - * Get a the task id from a text - * - * Example: "Fix bug #1234" will return 1234 - * - * @access public - * @param string $message Text - * @return integer - */ - public function getTaskIdFromText($message) - { - if (preg_match('!#(\d+)!i', $message, $matches) && isset($matches[1])) { - return $matches[1]; - } - - return 0; - } - - /** - * Get task progress based on the column position - * - * @access public - * @param array $task - * @param array $columns - * @return integer - */ - public function getProgress(array $task, array $columns) - { - if ($task['is_active'] == self::STATUS_CLOSED) { - return 100; - } - - $position = 0; - - foreach ($columns as $column_id => $column_title) { - if ($column_id == $task['column_id']) { - break; - } - - $position++; - } - - return round(($position * 100) / count($columns), 1); - } -} diff --git a/sources/app/Model/TaskModificationModel.php b/sources/app/Model/TaskModificationModel.php deleted file mode 100644 index be5f53c..0000000 --- a/sources/app/Model/TaskModificationModel.php +++ /dev/null @@ -1,113 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Event\TaskEvent; - -/** - * Task Modification - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskModificationModel extends Base -{ - /** - * Update a task - * - * @access public - * @param array $values - * @param boolean $fire_events - * @return boolean - */ - public function update(array $values, $fire_events = true) - { - $original_task = $this->taskFinderModel->getById($values['id']); - - $this->updateTags($values, $original_task); - $this->prepare($values); - $result = $this->db->table(TaskModel::TABLE)->eq('id', $original_task['id'])->update($values); - - if ($fire_events && $result) { - $this->fireEvents($original_task, $values); - } - - return $result; - } - - /** - * Fire events - * - * @access public - * @param array $task - * @param array $new_values - */ - public function fireEvents(array $task, array $new_values) - { - $events = array(); - $event_data = array_merge($task, $new_values, array('task_id' => $task['id'])); - - // Values changed - $event_data['changes'] = array_diff_assoc($new_values, $task); - unset($event_data['changes']['date_modification']); - - if ($this->isFieldModified('owner_id', $event_data['changes'])) { - $events[] = TaskModel::EVENT_ASSIGNEE_CHANGE; - } elseif (! empty($event_data['changes'])) { - $events[] = TaskModel::EVENT_CREATE_UPDATE; - $events[] = TaskModel::EVENT_UPDATE; - } - - foreach ($events as $event) { - $this->logger->debug('Event fired: '.$event); - $this->dispatcher->dispatch($event, new TaskEvent($event_data)); - } - } - - /** - * Return true if the field is the only modified value - * - * @access public - * @param string $field - * @param array $changes - * @return boolean - */ - public function isFieldModified($field, array $changes) - { - return isset($changes[$field]) && count($changes) === 1; - } - - /** - * Prepare data before task modification - * - * @access protected - * @param array $values - */ - protected function prepare(array &$values) - { - $values = $this->dateParser->convert($values, array('date_due')); - $values = $this->dateParser->convert($values, array('date_started'), true); - - $this->helper->model->removeFields($values, array('another_task', 'id')); - $this->helper->model->resetFields($values, array('date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent')); - $this->helper->model->convertIntegerFields($values, array('priority', 'is_active', 'recurrence_status', 'recurrence_trigger', 'recurrence_factor', 'recurrence_timeframe', 'recurrence_basedate')); - - $values['date_modification'] = time(); - } - - /** - * Update tags - * - * @access protected - * @param array $values - * @param array $original_task - */ - protected function updateTags(array &$values, array $original_task) - { - if (isset($values['tags'])) { - $this->taskTagModel->save($original_task['project_id'], $values['id'], $values['tags']); - unset($values['tags']); - } - } -} diff --git a/sources/app/Model/TaskPositionModel.php b/sources/app/Model/TaskPositionModel.php deleted file mode 100644 index 9fdb8f7..0000000 --- a/sources/app/Model/TaskPositionModel.php +++ /dev/null @@ -1,239 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Event\TaskEvent; - -/** - * Task Position - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskPositionModel extends Base -{ - /** - * Move a task to another column or to another position - * - * @access public - * @param integer $project_id Project id - * @param integer $task_id Task id - * @param integer $column_id Column id - * @param integer $position Position (must be >= 1) - * @param integer $swimlane_id Swimlane id - * @param boolean $fire_events Fire events - * @return boolean - */ - public function movePosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0, $fire_events = true) - { - if ($position < 1) { - return false; - } - - $task = $this->taskFinderModel->getById($task_id); - - if ($task['is_active'] == TaskModel::STATUS_CLOSED) { - return true; - } - - $result = false; - - if ($task['swimlane_id'] != $swimlane_id) { - $result = $this->saveSwimlaneChange($project_id, $task_id, $position, $task['column_id'], $column_id, $task['swimlane_id'], $swimlane_id); - } elseif ($task['column_id'] != $column_id) { - $result = $this->saveColumnChange($project_id, $task_id, $position, $swimlane_id, $task['column_id'], $column_id); - } elseif ($task['position'] != $position) { - $result = $this->savePositionChange($project_id, $task_id, $position, $column_id, $swimlane_id); - } - - if ($result && $fire_events) { - $this->fireEvents($task, $column_id, $position, $swimlane_id); - } - - return $result; - } - - /** - * Move a task to another swimlane - * - * @access private - * @param integer $project_id - * @param integer $task_id - * @param integer $position - * @param integer $original_column_id - * @param integer $new_column_id - * @param integer $original_swimlane_id - * @param integer $new_swimlane_id - * @return boolean - */ - private function saveSwimlaneChange($project_id, $task_id, $position, $original_column_id, $new_column_id, $original_swimlane_id, $new_swimlane_id) - { - $this->db->startTransaction(); - $r1 = $this->saveTaskPositions($project_id, $task_id, 0, $original_column_id, $original_swimlane_id); - $r2 = $this->saveTaskPositions($project_id, $task_id, $position, $new_column_id, $new_swimlane_id); - $this->db->closeTransaction(); - - return $r1 && $r2; - } - - /** - * Move a task to another column - * - * @access private - * @param integer $project_id - * @param integer $task_id - * @param integer $position - * @param integer $swimlane_id - * @param integer $original_column_id - * @param integer $new_column_id - * @return boolean - */ - private function saveColumnChange($project_id, $task_id, $position, $swimlane_id, $original_column_id, $new_column_id) - { - $this->db->startTransaction(); - $r1 = $this->saveTaskPositions($project_id, $task_id, 0, $original_column_id, $swimlane_id); - $r2 = $this->saveTaskPositions($project_id, $task_id, $position, $new_column_id, $swimlane_id); - $this->db->closeTransaction(); - - return $r1 && $r2; - } - - /** - * Move a task to another position in the same column - * - * @access private - * @param integer $project_id - * @param integer $task_id - * @param integer $position - * @param integer $column_id - * @param integer $swimlane_id - * @return boolean - */ - private function savePositionChange($project_id, $task_id, $position, $column_id, $swimlane_id) - { - $this->db->startTransaction(); - $result = $this->saveTaskPositions($project_id, $task_id, $position, $column_id, $swimlane_id); - $this->db->closeTransaction(); - - return $result; - } - - /** - * Save all task positions for one column - * - * @access private - * @param integer $project_id - * @param integer $task_id - * @param integer $position - * @param integer $column_id - * @param integer $swimlane_id - * @return boolean - */ - private function saveTaskPositions($project_id, $task_id, $position, $column_id, $swimlane_id) - { - $tasks_ids = $this->db->table(TaskModel::TABLE) - ->eq('is_active', 1) - ->eq('swimlane_id', $swimlane_id) - ->eq('project_id', $project_id) - ->eq('column_id', $column_id) - ->neq('id', $task_id) - ->asc('position') - ->asc('id') - ->findAllByColumn('id'); - - $offset = 1; - - foreach ($tasks_ids as $current_task_id) { - - // Insert the new task - if ($position == $offset) { - if (! $this->saveTaskPosition($task_id, $offset, $column_id, $swimlane_id)) { - return false; - } - $offset++; - } - - // Rewrite other tasks position - if (! $this->saveTaskPosition($current_task_id, $offset, $column_id, $swimlane_id)) { - return false; - } - - $offset++; - } - - // Insert the new task at the bottom and normalize bad position - if ($position >= $offset && ! $this->saveTaskPosition($task_id, $offset, $column_id, $swimlane_id)) { - return false; - } - - $now = time(); - - return $this->db->table(TaskModel::TABLE)->eq('id', $task_id)->update(array( - 'date_moved' => $now, - 'date_modification' => $now, - )); - } - - /** - * Save new task position - * - * @access private - * @param integer $task_id - * @param integer $position - * @param integer $column_id - * @param integer $swimlane_id - * @return boolean - */ - private function saveTaskPosition($task_id, $position, $column_id, $swimlane_id) - { - $result = $this->db->table(TaskModel::TABLE)->eq('id', $task_id)->update(array( - 'position' => $position, - 'column_id' => $column_id, - 'swimlane_id' => $swimlane_id, - )); - - if (! $result) { - $this->db->cancelTransaction(); - return false; - } - - return true; - } - - /** - * Fire events - * - * @access private - * @param array $task - * @param integer $new_column_id - * @param integer $new_position - * @param integer $new_swimlane_id - */ - private function fireEvents(array $task, $new_column_id, $new_position, $new_swimlane_id) - { - $event_data = array( - 'task_id' => $task['id'], - 'project_id' => $task['project_id'], - 'position' => $new_position, - 'column_id' => $new_column_id, - 'swimlane_id' => $new_swimlane_id, - 'src_column_id' => $task['column_id'], - 'dst_column_id' => $new_column_id, - 'date_moved' => $task['date_moved'], - 'recurrence_status' => $task['recurrence_status'], - 'recurrence_trigger' => $task['recurrence_trigger'], - ); - - if ($task['swimlane_id'] != $new_swimlane_id) { - $this->logger->debug('Event fired: '.TaskModel::EVENT_MOVE_SWIMLANE); - $this->dispatcher->dispatch(TaskModel::EVENT_MOVE_SWIMLANE, new TaskEvent($event_data)); - } elseif ($task['column_id'] != $new_column_id) { - $this->logger->debug('Event fired: '.TaskModel::EVENT_MOVE_COLUMN); - $this->dispatcher->dispatch(TaskModel::EVENT_MOVE_COLUMN, new TaskEvent($event_data)); - } elseif ($task['position'] != $new_position) { - $this->logger->debug('Event fired: '.TaskModel::EVENT_MOVE_POSITION); - $this->dispatcher->dispatch(TaskModel::EVENT_MOVE_POSITION, new TaskEvent($event_data)); - } - } -} diff --git a/sources/app/Model/TaskProjectDuplicationModel.php b/sources/app/Model/TaskProjectDuplicationModel.php deleted file mode 100644 index 8ebed25..0000000 --- a/sources/app/Model/TaskProjectDuplicationModel.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * Task Project Duplication - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskProjectDuplicationModel extends TaskDuplicationModel -{ - /** - * Duplicate a task to another project - * - * @access public - * @param integer $task_id - * @param integer $project_id - * @param integer $swimlane_id - * @param integer $column_id - * @param integer $category_id - * @param integer $owner_id - * @return boolean|integer - */ - public function duplicateToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null) - { - $values = $this->prepare($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id); - $this->checkDestinationProjectValues($values); - $new_task_id = $this->save($task_id, $values); - - if ($new_task_id !== false) { - $this->tagDuplicationModel->duplicateTaskTagsToAnotherProject($task_id, $new_task_id, $project_id); - } - - return $new_task_id; - } - - /** - * Prepare values before duplication - * - * @access protected - * @param integer $task_id - * @param integer $project_id - * @param integer $swimlane_id - * @param integer $column_id - * @param integer $category_id - * @param integer $owner_id - * @return array - */ - protected function prepare($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id) - { - $values = $this->copyFields($task_id); - $values['project_id'] = $project_id; - $values['column_id'] = $column_id !== null ? $column_id : $values['column_id']; - $values['swimlane_id'] = $swimlane_id !== null ? $swimlane_id : $values['swimlane_id']; - $values['category_id'] = $category_id !== null ? $category_id : $values['category_id']; - $values['owner_id'] = $owner_id !== null ? $owner_id : $values['owner_id']; - return $values; - } -} diff --git a/sources/app/Model/TaskProjectMoveModel.php b/sources/app/Model/TaskProjectMoveModel.php deleted file mode 100644 index eda23c0..0000000 --- a/sources/app/Model/TaskProjectMoveModel.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Event\TaskEvent; - -/** - * Task Project Move - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskProjectMoveModel extends TaskDuplicationModel -{ - /** - * Move a task to another project - * - * @access public - * @param integer $task_id - * @param integer $project_id - * @param integer $swimlane_id - * @param integer $column_id - * @param integer $category_id - * @param integer $owner_id - * @return boolean - */ - public function moveToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null) - { - $task = $this->taskFinderModel->getById($task_id); - $values = $this->prepare($project_id, $swimlane_id, $column_id, $category_id, $owner_id, $task); - - $this->checkDestinationProjectValues($values); - $this->tagDuplicationModel->syncTaskTagsToAnotherProject($task_id, $project_id); - - if ($this->db->table(TaskModel::TABLE)->eq('id', $task['id'])->update($values)) { - $event = new TaskEvent(array_merge($task, $values, array('task_id' => $task['id']))); - $this->dispatcher->dispatch(TaskModel::EVENT_MOVE_PROJECT, $event); - } - - return true; - } - - /** - * Prepare new task values - * - * @access protected - * @param integer $project_id - * @param integer $swimlane_id - * @param integer $column_id - * @param integer $category_id - * @param integer $owner_id - * @param array $task - * @return array - */ - protected function prepare($project_id, $swimlane_id, $column_id, $category_id, $owner_id, array $task) - { - $values = array(); - $values['is_active'] = 1; - $values['project_id'] = $project_id; - $values['column_id'] = $column_id !== null ? $column_id : $task['column_id']; - $values['position'] = $this->taskFinderModel->countByColumnId($project_id, $values['column_id']) + 1; - $values['swimlane_id'] = $swimlane_id !== null ? $swimlane_id : $task['swimlane_id']; - $values['category_id'] = $category_id !== null ? $category_id : $task['category_id']; - $values['owner_id'] = $owner_id !== null ? $owner_id : $task['owner_id']; - $values['priority'] = $task['priority']; - return $values; - } -} diff --git a/sources/app/Model/TaskRecurrenceModel.php b/sources/app/Model/TaskRecurrenceModel.php deleted file mode 100644 index ffe43f8..0000000 --- a/sources/app/Model/TaskRecurrenceModel.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use DateInterval; -use DateTime; - -/** - * Task Recurrence - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskRecurrenceModel extends TaskDuplicationModel -{ - /** - * Return the list user selectable recurrence status - * - * @access public - * @return array - */ - public function getRecurrenceStatusList() - { - return array( - TaskModel::RECURRING_STATUS_NONE => t('No'), - TaskModel::RECURRING_STATUS_PENDING => t('Yes'), - ); - } - - /** - * Return the list recurrence triggers - * - * @access public - * @return array - */ - public function getRecurrenceTriggerList() - { - return array( - TaskModel::RECURRING_TRIGGER_FIRST_COLUMN => t('When task is moved from first column'), - TaskModel::RECURRING_TRIGGER_LAST_COLUMN => t('When task is moved to last column'), - TaskModel::RECURRING_TRIGGER_CLOSE => t('When task is closed'), - ); - } - - /** - * Return the list options to calculate recurrence due date - * - * @access public - * @return array - */ - public function getRecurrenceBasedateList() - { - return array( - TaskModel::RECURRING_BASEDATE_DUEDATE => t('Existing due date'), - TaskModel::RECURRING_BASEDATE_TRIGGERDATE => t('Action date'), - ); - } - - /** - * Return the list recurrence timeframes - * - * @access public - * @return array - */ - public function getRecurrenceTimeframeList() - { - return array( - TaskModel::RECURRING_TIMEFRAME_DAYS => t('Day(s)'), - TaskModel::RECURRING_TIMEFRAME_MONTHS => t('Month(s)'), - TaskModel::RECURRING_TIMEFRAME_YEARS => t('Year(s)'), - ); - } - - /** - * Duplicate recurring task - * - * @access public - * @param integer $task_id Task id - * @return boolean|integer Recurrence task id - */ - public function duplicateRecurringTask($task_id) - { - $values = $this->copyFields($task_id); - - if ($values['recurrence_status'] == TaskModel::RECURRING_STATUS_PENDING) { - $values['recurrence_parent'] = $task_id; - $values['column_id'] = $this->columnModel->getFirstColumnId($values['project_id']); - $this->calculateRecurringTaskDueDate($values); - - $recurring_task_id = $this->save($task_id, $values); - - if ($recurring_task_id !== false) { - $this->tagDuplicationModel->duplicateTaskTags($task_id, $recurring_task_id); - - $parent_update = $this->db - ->table(TaskModel::TABLE) - ->eq('id', $task_id) - ->update(array( - 'recurrence_status' => TaskModel::RECURRING_STATUS_PROCESSED, - 'recurrence_child' => $recurring_task_id, - )); - - if ($parent_update) { - return $recurring_task_id; - } - } - } - - return false; - } - - /** - * Calculate new due date for new recurrence task - * - * @access public - * @param array $values Task fields - */ - public function calculateRecurringTaskDueDate(array &$values) - { - if (! empty($values['date_due']) && $values['recurrence_factor'] != 0) { - if ($values['recurrence_basedate'] == TaskModel::RECURRING_BASEDATE_TRIGGERDATE) { - $values['date_due'] = time(); - } - - $factor = abs($values['recurrence_factor']); - $subtract = $values['recurrence_factor'] < 0; - - switch ($values['recurrence_timeframe']) { - case TaskModel::RECURRING_TIMEFRAME_MONTHS: - $interval = 'P' . $factor . 'M'; - break; - case TaskModel::RECURRING_TIMEFRAME_YEARS: - $interval = 'P' . $factor . 'Y'; - break; - default: - $interval = 'P' . $factor . 'D'; - } - - $date_due = new DateTime(); - $date_due->setTimestamp($values['date_due']); - - $subtract ? $date_due->sub(new DateInterval($interval)) : $date_due->add(new DateInterval($interval)); - - $values['date_due'] = $date_due->getTimestamp(); - } - } -} diff --git a/sources/app/Model/TaskStatusModel.php b/sources/app/Model/TaskStatusModel.php deleted file mode 100644 index 4d573f0..0000000 --- a/sources/app/Model/TaskStatusModel.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Event\TaskEvent; - -/** - * Task Status - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskStatusModel extends Base -{ - /** - * Return true if the task is closed - * - * @access public - * @param integer $task_id Task id - * @return boolean - */ - public function isClosed($task_id) - { - return $this->checkStatus($task_id, TaskModel::STATUS_CLOSED); - } - - /** - * Return true if the task is open - * - * @access public - * @param integer $task_id Task id - * @return boolean - */ - public function isOpen($task_id) - { - return $this->checkStatus($task_id, TaskModel::STATUS_OPEN); - } - - /** - * Mark a task closed - * - * @access public - * @param integer $task_id Task id - * @return boolean - */ - public function close($task_id) - { - $this->subtaskModel->closeAll($task_id); - return $this->changeStatus($task_id, TaskModel::STATUS_CLOSED, time(), TaskModel::EVENT_CLOSE); - } - - /** - * Mark a task open - * - * @access public - * @param integer $task_id Task id - * @return boolean - */ - public function open($task_id) - { - return $this->changeStatus($task_id, TaskModel::STATUS_OPEN, 0, TaskModel::EVENT_OPEN); - } - - /** - * Close multiple tasks - * - * @access public - * @param array $task_ids - */ - public function closeMultipleTasks(array $task_ids) - { - foreach ($task_ids as $task_id) { - $this->close($task_id); - } - } - - /** - * Close all tasks within a column/swimlane - * - * @access public - * @param integer $swimlane_id - * @param integer $column_id - */ - public function closeTasksBySwimlaneAndColumn($swimlane_id, $column_id) - { - $task_ids = $this->db - ->table(TaskModel::TABLE) - ->eq('swimlane_id', $swimlane_id) - ->eq('column_id', $column_id) - ->eq(TaskModel::TABLE.'.is_active', TaskModel::STATUS_OPEN) - ->findAllByColumn('id'); - - $this->closeMultipleTasks($task_ids); - } - - /** - * Common method to change the status of task - * - * @access private - * @param integer $task_id Task id - * @param integer $status Task status - * @param integer $date_completed Timestamp - * @param string $event Event name - * @return boolean - */ - private function changeStatus($task_id, $status, $date_completed, $event) - { - if (! $this->taskFinderModel->exists($task_id)) { - return false; - } - - $result = $this->db - ->table(TaskModel::TABLE) - ->eq('id', $task_id) - ->update(array( - 'is_active' => $status, - 'date_completed' => $date_completed, - 'date_modification' => time(), - )); - - if ($result) { - $this->logger->debug('Event fired: '.$event); - $this->dispatcher->dispatch($event, new TaskEvent(array('task_id' => $task_id) + $this->taskFinderModel->getById($task_id))); - } - - return $result; - } - - /** - * Check the status of a task - * - * @access private - * @param integer $task_id Task id - * @param integer $status Task status - * @return boolean - */ - private function checkStatus($task_id, $status) - { - return $this->db - ->table(TaskModel::TABLE) - ->eq('id', $task_id) - ->eq('is_active', $status) - ->count() === 1; - } -} diff --git a/sources/app/Model/TaskTagModel.php b/sources/app/Model/TaskTagModel.php deleted file mode 100644 index 0553cc6..0000000 --- a/sources/app/Model/TaskTagModel.php +++ /dev/null @@ -1,184 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Class TaskTagModel - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TaskTagModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'task_has_tags'; - - /** - * Get all tags not available in a project - * - * @access public - * @param integer $task_id - * @param integer $project_id - * @return array - */ - public function getTagIdsByTaskNotAvailableInProject($task_id, $project_id) - { - return $this->db->table(TagModel::TABLE) - ->eq(self::TABLE.'.task_id', $task_id) - ->notIn(TagModel::TABLE.'.project_id', array(0, $project_id)) - ->join(self::TABLE, 'tag_id', 'id') - ->findAllByColumn(TagModel::TABLE.'.id'); - } - - /** - * Get all tags associated to a task - * - * @access public - * @param integer $task_id - * @return array - */ - public function getTagsByTask($task_id) - { - return $this->db->table(TagModel::TABLE) - ->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name') - ->eq(self::TABLE.'.task_id', $task_id) - ->join(self::TABLE, 'tag_id', 'id') - ->findAll(); - } - - /** - * Get all tags associated to a list of tasks - * - * @access public - * @param integer[] $task_ids - * @return array - */ - public function getTagsByTasks($task_ids) - { - if (empty($task_ids)) { - return array(); - } - - $tags = $this->db->table(TagModel::TABLE) - ->columns(TagModel::TABLE.'.id', TagModel::TABLE.'.name', self::TABLE.'.task_id') - ->in(self::TABLE.'.task_id', $task_ids) - ->join(self::TABLE, 'tag_id', 'id') - ->findAll(); - - return array_column_index($tags, 'task_id'); - } - - /** - * Get dictionary of tags - * - * @access public - * @param integer $task_id - * @return array - */ - public function getList($task_id) - { - $tags = $this->getTagsByTask($task_id); - return array_column($tags, 'name', 'id'); - } - - /** - * Add or update a list of tags to a task - * - * @access public - * @param integer $project_id - * @param integer $task_id - * @param string[] $tags - * @return boolean - */ - public function save($project_id, $task_id, array $tags) - { - $task_tags = $this->getList($task_id); - $tags = array_filter($tags); - - return $this->associateTags($project_id, $task_id, $task_tags, $tags) && - $this->dissociateTags($task_id, $task_tags, $tags); - } - - /** - * Associate a tag to a task - * - * @access public - * @param integer $task_id - * @param integer $tag_id - * @return boolean - */ - public function associateTag($task_id, $tag_id) - { - return $this->db->table(self::TABLE)->insert(array( - 'task_id' => $task_id, - 'tag_id' => $tag_id, - )); - } - - /** - * Dissociate a tag from a task - * - * @access public - * @param integer $task_id - * @param integer $tag_id - * @return boolean - */ - public function dissociateTag($task_id, $tag_id) - { - return $this->db->table(self::TABLE) - ->eq('task_id', $task_id) - ->eq('tag_id', $tag_id) - ->remove(); - } - - /** - * Associate missing tags - * - * @access protected - * @param integer $project_id - * @param integer $task_id - * @param array $task_tags - * @param string[] $tags - * @return bool - */ - protected function associateTags($project_id, $task_id, $task_tags, $tags) - { - foreach ($tags as $tag) { - $tag_id = $this->tagModel->findOrCreateTag($project_id, $tag); - - if (! isset($task_tags[$tag_id]) && ! $this->associateTag($task_id, $tag_id)) { - return false; - } - } - - return true; - } - - /** - * Dissociate removed tags - * - * @access protected - * @param integer $task_id - * @param array $task_tags - * @param string[] $tags - * @return bool - */ - protected function dissociateTags($task_id, $task_tags, $tags) - { - foreach ($task_tags as $tag_id => $tag) { - if (! in_array($tag, $tags)) { - if (! $this->dissociateTag($task_id, $tag_id)) { - return false; - } - } - } - - return true; - } -} diff --git a/sources/app/Model/TimezoneModel.php b/sources/app/Model/TimezoneModel.php deleted file mode 100644 index 8b3e895..0000000 --- a/sources/app/Model/TimezoneModel.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Class Timezone - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TimezoneModel extends Base -{ - /** - * Get available timezones - * - * @access public - * @param boolean $prepend Prepend a default value - * @return array - */ - public function getTimezones($prepend = false) - { - $timezones = timezone_identifiers_list(); - $listing = array_combine(array_values($timezones), $timezones); - - if ($prepend) { - return array('' => t('Application default')) + $listing; - } - - return $listing; - } - - /** - * Get current timezone - * - * @access public - * @return string - */ - public function getCurrentTimezone() - { - if ($this->userSession->isLogged() && ! empty($this->sessionStorage->user['timezone'])) { - return $this->sessionStorage->user['timezone']; - } - - return $this->configModel->get('application_timezone', 'UTC'); - } - - /** - * Set timezone - * - * @access public - */ - public function setCurrentTimezone() - { - date_default_timezone_set($this->getCurrentTimezone()); - } -} diff --git a/sources/app/Model/TransitionModel.php b/sources/app/Model/TransitionModel.php deleted file mode 100644 index a4a5847..0000000 --- a/sources/app/Model/TransitionModel.php +++ /dev/null @@ -1,130 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * Transition - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class TransitionModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'transitions'; - - /** - * Save transition event - * - * @access public - * @param integer $user_id - * @param array $task_event - * @return bool - */ - public function save($user_id, array $task_event) - { - $time = time(); - - return $this->db->table(self::TABLE)->insert(array( - 'user_id' => $user_id, - 'project_id' => $task_event['project_id'], - 'task_id' => $task_event['task_id'], - 'src_column_id' => $task_event['src_column_id'], - 'dst_column_id' => $task_event['dst_column_id'], - 'date' => $time, - 'time_spent' => $time - $task_event['date_moved'] - )); - } - - /** - * Get time spent by task for each column - * - * @access public - * @param integer $task_id - * @return array - */ - public function getTimeSpentByTask($task_id) - { - return $this->db - ->hashtable(self::TABLE) - ->groupBy('src_column_id') - ->eq('task_id', $task_id) - ->getAll('src_column_id', 'SUM(time_spent) AS time_spent'); - } - - /** - * Get all transitions by task - * - * @access public - * @param integer $task_id - * @return array - */ - public function getAllByTask($task_id) - { - return $this->db->table(self::TABLE) - ->columns( - 'src.title as src_column', - 'dst.title as dst_column', - UserModel::TABLE.'.name', - UserModel::TABLE.'.username', - self::TABLE.'.user_id', - self::TABLE.'.date', - self::TABLE.'.time_spent' - ) - ->eq('task_id', $task_id) - ->desc('date') - ->join(UserModel::TABLE, 'id', 'user_id') - ->join(ColumnModel::TABLE.' as src', 'id', 'src_column_id', self::TABLE, 'src') - ->join(ColumnModel::TABLE.' as dst', 'id', 'dst_column_id', self::TABLE, 'dst') - ->findAll(); - } - - /** - * Get all transitions by project - * - * @access public - * @param integer $project_id - * @param mixed $from Start date (timestamp or user formatted date) - * @param mixed $to End date (timestamp or user formatted date) - * @return array - */ - public function getAllByProjectAndDate($project_id, $from, $to) - { - if (! is_numeric($from)) { - $from = $this->dateParser->removeTimeFromTimestamp($this->dateParser->getTimestamp($from)); - } - - if (! is_numeric($to)) { - $to = $this->dateParser->removeTimeFromTimestamp(strtotime('+1 day', $this->dateParser->getTimestamp($to))); - } - - return $this->db->table(self::TABLE) - ->columns( - TaskModel::TABLE.'.id', - TaskModel::TABLE.'.title', - 'src.title as src_column', - 'dst.title as dst_column', - UserModel::TABLE.'.name', - UserModel::TABLE.'.username', - self::TABLE.'.user_id', - self::TABLE.'.date', - self::TABLE.'.time_spent' - ) - ->gte('date', $from) - ->lte('date', $to) - ->eq(self::TABLE.'.project_id', $project_id) - ->desc('date') - ->desc(self::TABLE.'.id') - ->join(TaskModel::TABLE, 'id', 'task_id') - ->join(UserModel::TABLE, 'id', 'user_id') - ->join(ColumnModel::TABLE.' as src', 'id', 'src_column_id', self::TABLE, 'src') - ->join(ColumnModel::TABLE.' as dst', 'id', 'dst_column_id', self::TABLE, 'dst') - ->findAll(); - } -} diff --git a/sources/app/Model/UserLockingModel.php b/sources/app/Model/UserLockingModel.php deleted file mode 100644 index 1d4d994..0000000 --- a/sources/app/Model/UserLockingModel.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * User Locking Model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class UserLockingModel extends Base -{ - /** - * Get the number of failed login for the user - * - * @access public - * @param string $username - * @return integer - */ - public function getFailedLogin($username) - { - return (int) $this->db->table(UserModel::TABLE) - ->eq('username', $username) - ->findOneColumn('nb_failed_login'); - } - - /** - * Reset to 0 the counter of failed login - * - * @access public - * @param string $username - * @return boolean - */ - public function resetFailedLogin($username) - { - return $this->db->table(UserModel::TABLE) - ->eq('username', $username) - ->update(array( - 'nb_failed_login' => 0, - 'lock_expiration_date' => 0, - )); - } - - /** - * Increment failed login counter - * - * @access public - * @param string $username - * @return boolean - */ - public function incrementFailedLogin($username) - { - return $this->db->table(UserModel::TABLE) - ->eq('username', $username) - ->increment('nb_failed_login', 1); - } - - /** - * Check if the account is locked - * - * @access public - * @param string $username - * @return boolean - */ - public function isLocked($username) - { - return $this->db->table(UserModel::TABLE) - ->eq('username', $username) - ->neq('lock_expiration_date', 0) - ->gte('lock_expiration_date', time()) - ->exists(); - } - - /** - * Lock the account for the specified duration - * - * @access public - * @param string $username Username - * @param integer $duration Duration in minutes - * @return boolean - */ - public function lock($username, $duration = 15) - { - return $this->db->table(UserModel::TABLE) - ->eq('username', $username) - ->update(array( - 'lock_expiration_date' => time() + $duration * 60 - )); - } - - /** - * Return true if the captcha must be shown - * - * @access public - * @param string $username - * @param integer $tries - * @return boolean - */ - public function hasCaptcha($username, $tries = BRUTEFORCE_CAPTCHA) - { - return $this->getFailedLogin($username) >= $tries; - } -} diff --git a/sources/app/Model/UserMentionModel.php b/sources/app/Model/UserMentionModel.php deleted file mode 100644 index cdb9949..0000000 --- a/sources/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/sources/app/Model/UserMetadataModel.php b/sources/app/Model/UserMetadataModel.php deleted file mode 100644 index e931d3b..0000000 --- a/sources/app/Model/UserMetadataModel.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * User Metadata - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class UserMetadataModel extends MetadataModel -{ - /** - * Get the table - * - * @abstract - * @access protected - * @return string - */ - protected function getTable() - { - return 'user_has_metadata'; - } - - /** - * Define the entity key - * - * @access protected - * @return string - */ - protected function getEntityKey() - { - return 'user_id'; - } -} diff --git a/sources/app/Model/UserModel.php b/sources/app/Model/UserModel.php deleted file mode 100644 index f7a051c..0000000 --- a/sources/app/Model/UserModel.php +++ /dev/null @@ -1,390 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use PicoDb\Database; -use Kanboard\Core\Base; -use Kanboard\Core\Security\Token; -use Kanboard\Core\Security\Role; - -/** - * User model - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class UserModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'users'; - - /** - * Id used for everybody (filtering) - * - * @var integer - */ - const EVERYBODY_ID = -1; - - /** - * Return true if the user exists - * - * @access public - * @param integer $user_id User id - * @return boolean - */ - public function exists($user_id) - { - return $this->db->table(self::TABLE)->eq('id', $user_id)->exists(); - } - - /** - * Return true if the user is active - * - * @access public - * @param integer $user_id User id - * @return boolean - */ - public function isActive($user_id) - { - return $this->db->table(self::TABLE)->eq('id', $user_id)->eq('is_active', 1)->exists(); - } - - /** - * Get query to fetch all users - * - * @access public - * @return \PicoDb\Table - */ - public function getQuery() - { - return $this->db->table(self::TABLE); - } - - /** - * Return the full name - * - * @param array $user User properties - * @return string - */ - public function getFullname(array $user) - { - return $user['name'] ?: $user['username']; - } - - /** - * Return true is the given user id is administrator - * - * @access public - * @param integer $user_id User id - * @return boolean - */ - public function isAdmin($user_id) - { - return $this->userSession->isAdmin() || // Avoid SQL query if connected - $this->db - ->table(UserModel::TABLE) - ->eq('id', $user_id) - ->eq('role', Role::APP_ADMIN) - ->exists(); - } - - /** - * Get a specific user by id - * - * @access public - * @param integer $user_id User id - * @return array - */ - public function getById($user_id) - { - return $this->db->table(self::TABLE)->eq('id', $user_id)->findOne(); - } - - /** - * Get a specific user by the Google id - * - * @access public - * @param string $column - * @param string $id - * @return array|boolean - */ - public function getByExternalId($column, $id) - { - if (empty($id)) { - return false; - } - - return $this->db->table(self::TABLE)->eq($column, $id)->findOne(); - } - - /** - * Get a specific user by the username - * - * @access public - * @param string $username Username - * @return array - */ - public function getByUsername($username) - { - return $this->db->table(self::TABLE)->eq('username', $username)->findOne(); - } - - /** - * Get user_id by username - * - * @access public - * @param string $username Username - * @return integer - */ - public function getIdByUsername($username) - { - return $this->db->table(self::TABLE)->eq('username', $username)->findOneColumn('id'); - } - - /** - * Get a specific user by the email address - * - * @access public - * @param string $email Email - * @return array|boolean - */ - public function getByEmail($email) - { - if (empty($email)) { - return false; - } - - return $this->db->table(self::TABLE)->eq('email', $email)->findOne(); - } - - /** - * Fetch user by using the token - * - * @access public - * @param string $token Token - * @return array|boolean - */ - public function getByToken($token) - { - if (empty($token)) { - return false; - } - - return $this->db->table(self::TABLE)->eq('token', $token)->findOne(); - } - - /** - * Get all users - * - * @access public - * @return array - */ - public function getAll() - { - return $this->getQuery()->asc('username')->findAll(); - } - - /** - * Get the number of users - * - * @access public - * @return integer - */ - public function count() - { - return $this->db->table(self::TABLE)->count(); - } - - /** - * List all users (key-value pairs with id/username) - * - * @access public - * @param boolean $prepend Prepend "All users" - * @return array - */ - public function getActiveUsersList($prepend = false) - { - $users = $this->db->table(self::TABLE)->eq('is_active', 1)->columns('id', 'username', 'name')->findAll(); - $listing = $this->prepareList($users); - - if ($prepend) { - return array(UserModel::EVERYBODY_ID => t('Everybody')) + $listing; - } - - return $listing; - } - - /** - * Common method to prepare a user list - * - * @access public - * @param array $users Users list (from database) - * @return array Formated list - */ - public function prepareList(array $users) - { - $result = array(); - - foreach ($users as $user) { - $result[$user['id']] = $this->getFullname($user); - } - - asort($result); - - return $result; - } - - /** - * Prepare values before an update or a create - * - * @access public - * @param array $values Form values - */ - public function prepare(array &$values) - { - if (isset($values['password'])) { - if (! empty($values['password'])) { - $values['password'] = \password_hash($values['password'], PASSWORD_BCRYPT); - } else { - unset($values['password']); - } - } - - $this->helper->model->removeFields($values, array('confirmation', 'current_password')); - $this->helper->model->resetFields($values, array('is_ldap_user', 'disable_login_form')); - $this->helper->model->convertNullFields($values, array('gitlab_id')); - $this->helper->model->convertIntegerFields($values, array('gitlab_id')); - } - - /** - * Add a new user in the database - * - * @access public - * @param array $values Form values - * @return boolean|integer - */ - public function create(array $values) - { - $this->prepare($values); - return $this->db->table(self::TABLE)->persist($values); - } - - /** - * Modify a new user - * - * @access public - * @param array $values Form values - * @return boolean - */ - public function update(array $values) - { - $this->prepare($values); - $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values); - $this->userSession->refresh($values['id']); - return $result; - } - - /** - * Disable a specific user - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function disable($user_id) - { - return $this->db->table(self::TABLE)->eq('id', $user_id)->update(array('is_active' => 0)); - } - - /** - * Enable a specific user - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function enable($user_id) - { - return $this->db->table(self::TABLE)->eq('id', $user_id)->update(array('is_active' => 1)); - } - - /** - * Remove a specific user - * - * @access public - * @param integer $user_id User id - * @return boolean - */ - public function remove($user_id) - { - $this->avatarFileModel->remove($user_id); - - return $this->db->transaction(function (Database $db) use ($user_id) { - - // All assigned tasks are now unassigned (no foreign key) - if (! $db->table(TaskModel::TABLE)->eq('owner_id', $user_id)->update(array('owner_id' => 0))) { - return false; - } - - // All assigned subtasks are now unassigned (no foreign key) - if (! $db->table(SubtaskModel::TABLE)->eq('user_id', $user_id)->update(array('user_id' => 0))) { - return false; - } - - // All comments are not assigned anymore (no foreign key) - if (! $db->table(CommentModel::TABLE)->eq('user_id', $user_id)->update(array('user_id' => 0))) { - return false; - } - - // All private projects are removed - $project_ids = $db->table(ProjectModel::TABLE) - ->eq('is_private', 1) - ->eq(ProjectUserRoleModel::TABLE.'.user_id', $user_id) - ->join(ProjectUserRoleModel::TABLE, 'project_id', 'id') - ->findAllByColumn(ProjectModel::TABLE.'.id'); - - if (! empty($project_ids)) { - $db->table(ProjectModel::TABLE)->in('id', $project_ids)->remove(); - } - - // Finally remove the user - if (! $db->table(UserModel::TABLE)->eq('id', $user_id)->remove()) { - return false; - } - }); - } - - /** - * Enable public access for a user - * - * @access public - * @param integer $user_id User id - * @return bool - */ - public function enablePublicAccess($user_id) - { - return $this->db - ->table(self::TABLE) - ->eq('id', $user_id) - ->save(array('token' => Token::getToken())); - } - - /** - * Disable public access for a user - * - * @access public - * @param integer $user_id User id - * @return bool - */ - public function disablePublicAccess($user_id) - { - return $this->db - ->table(self::TABLE) - ->eq('id', $user_id) - ->save(array('token' => '')); - } -} diff --git a/sources/app/Model/UserNotificationFilterModel.php b/sources/app/Model/UserNotificationFilterModel.php deleted file mode 100644 index 112ba29..0000000 --- a/sources/app/Model/UserNotificationFilterModel.php +++ /dev/null @@ -1,206 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * User Notification Filter - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class UserNotificationFilterModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const PROJECT_TABLE = 'user_has_notifications'; - - /** - * User filters - * - * @var integer - */ - const FILTER_NONE = 1; - const FILTER_ASSIGNEE = 2; - const FILTER_CREATOR = 3; - const FILTER_BOTH = 4; - - /** - * Get the list of filters - * - * @access public - * @return array - */ - public function getFilters() - { - return array( - self::FILTER_NONE => t('All tasks'), - self::FILTER_ASSIGNEE => t('Only for tasks assigned to me'), - self::FILTER_CREATOR => t('Only for tasks created by me'), - self::FILTER_BOTH => t('Only for tasks created by me and assigned to me'), - ); - } - - /** - * Get user selected filter - * - * @access public - * @param integer $user_id - * @return integer - */ - public function getSelectedFilter($user_id) - { - return $this->db->table(UserModel::TABLE)->eq('id', $user_id)->findOneColumn('notifications_filter'); - } - - /** - * Save selected filter for a user - * - * @access public - * @param integer $user_id - * @param string $filter - * @return boolean - */ - public function saveFilter($user_id, $filter) - { - return $this->db->table(UserModel::TABLE)->eq('id', $user_id)->update(array( - 'notifications_filter' => $filter, - )); - } - - /** - * Get user selected projects - * - * @access public - * @param integer $user_id - * @return array - */ - public function getSelectedProjects($user_id) - { - return $this->db->table(self::PROJECT_TABLE)->eq('user_id', $user_id)->findAllByColumn('project_id'); - } - - /** - * Save selected projects for a user - * - * @access public - * @param integer $user_id - * @param integer[] $project_ids - * @return boolean - */ - public function saveSelectedProjects($user_id, array $project_ids) - { - $results = array(); - $this->db->table(self::PROJECT_TABLE)->eq('user_id', $user_id)->remove(); - - foreach ($project_ids as $project_id) { - $results[] = $this->db->table(self::PROJECT_TABLE)->insert(array( - 'user_id' => $user_id, - 'project_id' => $project_id, - )); - } - - return !in_array(false, $results, true); - } - - /** - * Return true if the user should receive notification - * - * @access public - * @param array $user - * @param array $event_data - * @return boolean - */ - public function shouldReceiveNotification(array $user, array $event_data) - { - $filters = array( - 'filterNone', - 'filterAssignee', - 'filterCreator', - 'filterBoth', - ); - - foreach ($filters as $filter) { - if ($this->$filter($user, $event_data)) { - return $this->filterProject($user, $event_data); - } - } - - return false; - } - - /** - * Return true if the user will receive all notifications - * - * @access public - * @param array $user - * @return boolean - */ - public function filterNone(array $user) - { - return $user['notifications_filter'] == self::FILTER_NONE; - } - - /** - * Return true if the user is the assignee and selected the filter "assignee" - * - * @access public - * @param array $user - * @param array $event_data - * @return boolean - */ - public function filterAssignee(array $user, array $event_data) - { - return $user['notifications_filter'] == self::FILTER_ASSIGNEE && $event_data['task']['owner_id'] == $user['id']; - } - - /** - * Return true if the user is the creator and enabled the filter "creator" - * - * @access public - * @param array $user - * @param array $event_data - * @return boolean - */ - public function filterCreator(array $user, array $event_data) - { - return $user['notifications_filter'] == self::FILTER_CREATOR && $event_data['task']['creator_id'] == $user['id']; - } - - /** - * Return true if the user is the assignee or the creator and selected the filter "both" - * - * @access public - * @param array $user - * @param array $event_data - * @return boolean - */ - public function filterBoth(array $user, array $event_data) - { - return $user['notifications_filter'] == self::FILTER_BOTH && - ($event_data['task']['creator_id'] == $user['id'] || $event_data['task']['owner_id'] == $user['id']); - } - - /** - * Return true if the user want to receive notification for the selected project - * - * @access public - * @param array $user - * @param array $event_data - * @return boolean - */ - public function filterProject(array $user, array $event_data) - { - $projects = $this->getSelectedProjects($user['id']); - - if (! empty($projects)) { - return in_array($event_data['task']['project_id'], $projects); - } - - return true; - } -} diff --git a/sources/app/Model/UserNotificationModel.php b/sources/app/Model/UserNotificationModel.php deleted file mode 100644 index d77526f..0000000 --- a/sources/app/Model/UserNotificationModel.php +++ /dev/null @@ -1,204 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; -use Kanboard\Core\Translator; - -/** - * User Notification - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class UserNotificationModel extends Base -{ - /** - * Send notifications to people - * - * @access public - * @param string $event_name - * @param array $event_data - */ - public function sendNotifications($event_name, array $event_data) - { - $users = $this->getUsersWithNotificationEnabled($event_data['task']['project_id'], $this->userSession->getId()); - - foreach ($users as $user) { - if ($this->userNotificationFilterModel->shouldReceiveNotification($user, $event_data)) { - $this->sendUserNotification($user, $event_name, $event_data); - } - } - } - - /** - * Send notification to someone - * - * @access public - * @param array $user User - * @param string $event_name - * @param array $event_data - */ - public function sendUserNotification(array $user, $event_name, array $event_data) - { - Translator::unload(); - - // Use the user language otherwise use the application language (do not use the session language) - if (! empty($user['language'])) { - Translator::load($user['language']); - } else { - Translator::load($this->configModel->get('application_language', 'en_US')); - } - - foreach ($this->userNotificationTypeModel->getSelectedTypes($user['id']) as $type) { - $this->userNotificationTypeModel->getType($type)->notifyUser($user, $event_name, $event_data); - } - - // Restore locales - $this->languageModel->loadCurrentLanguage(); - } - - /** - * Get a list of people with notifications enabled - * - * @access public - * @param integer $project_id Project id - * @param integer $exclude_user_id User id to exclude - * @return array - */ - public function getUsersWithNotificationEnabled($project_id, $exclude_user_id = 0) - { - if ($this->projectPermissionModel->isEverybodyAllowed($project_id)) { - return $this->getEverybodyWithNotificationEnabled($exclude_user_id); - } - - $users = array(); - $members = $this->getProjectUserMembersWithNotificationEnabled($project_id, $exclude_user_id); - $groups = $this->getProjectGroupMembersWithNotificationEnabled($project_id, $exclude_user_id); - - foreach (array_merge($members, $groups) as $user) { - if (! isset($users[$user['id']])) { - $users[$user['id']] = $user; - } - } - - return array_values($users); - } - - /** - * Enable notification for someone - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function enableNotification($user_id) - { - return $this->db->table(UserModel::TABLE)->eq('id', $user_id)->update(array('notifications_enabled' => 1)); - } - - /** - * Disable notification for someone - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function disableNotification($user_id) - { - return $this->db->table(UserModel::TABLE)->eq('id', $user_id)->update(array('notifications_enabled' => 0)); - } - - /** - * Save settings for the given user - * - * @access public - * @param integer $user_id User id - * @param array $values Form values - */ - public function saveSettings($user_id, array $values) - { - $types = empty($values['notification_types']) ? array() : array_keys($values['notification_types']); - - if (! empty($types)) { - $this->enableNotification($user_id); - } else { - $this->disableNotification($user_id); - } - - $filter = empty($values['notifications_filter']) ? UserNotificationFilterModel::FILTER_BOTH : $values['notifications_filter']; - $project_ids = empty($values['notification_projects']) ? array() : array_keys($values['notification_projects']); - - $this->userNotificationFilterModel->saveFilter($user_id, $filter); - $this->userNotificationFilterModel->saveSelectedProjects($user_id, $project_ids); - $this->userNotificationTypeModel->saveSelectedTypes($user_id, $types); - } - - /** - * Read user settings to display the form - * - * @access public - * @param integer $user_id User id - * @return array - */ - public function readSettings($user_id) - { - $values = $this->db->table(UserModel::TABLE)->eq('id', $user_id)->columns('notifications_enabled', 'notifications_filter')->findOne(); - $values['notification_types'] = $this->userNotificationTypeModel->getSelectedTypes($user_id); - $values['notification_projects'] = $this->userNotificationFilterModel->getSelectedProjects($user_id); - return $values; - } - - /** - * Get a list of group members with notification enabled - * - * @access private - * @param integer $project_id Project id - * @param integer $exclude_user_id User id to exclude - * @return array - */ - private function getProjectUserMembersWithNotificationEnabled($project_id, $exclude_user_id) - { - return $this->db - ->table(ProjectUserRoleModel::TABLE) - ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name', UserModel::TABLE.'.email', UserModel::TABLE.'.language', UserModel::TABLE.'.notifications_filter') - ->join(UserModel::TABLE, 'id', 'user_id') - ->eq(ProjectUserRoleModel::TABLE.'.project_id', $project_id) - ->eq(UserModel::TABLE.'.notifications_enabled', '1') - ->eq(UserModel::TABLE.'.is_active', 1) - ->neq(UserModel::TABLE.'.id', $exclude_user_id) - ->findAll(); - } - - private function getProjectGroupMembersWithNotificationEnabled($project_id, $exclude_user_id) - { - return $this->db - ->table(ProjectGroupRoleModel::TABLE) - ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name', UserModel::TABLE.'.email', UserModel::TABLE.'.language', UserModel::TABLE.'.notifications_filter') - ->join(GroupMemberModel::TABLE, 'group_id', 'group_id', ProjectGroupRoleModel::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id', GroupMemberModel::TABLE) - ->eq(ProjectGroupRoleModel::TABLE.'.project_id', $project_id) - ->eq(UserModel::TABLE.'.notifications_enabled', '1') - ->neq(UserModel::TABLE.'.id', $exclude_user_id) - ->eq(UserModel::TABLE.'.is_active', 1) - ->findAll(); - } - - /** - * Get a list of project members with notification enabled - * - * @access private - * @param integer $exclude_user_id User id to exclude - * @return array - */ - private function getEverybodyWithNotificationEnabled($exclude_user_id) - { - return $this->db - ->table(UserModel::TABLE) - ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name', UserModel::TABLE.'.email', UserModel::TABLE.'.language', UserModel::TABLE.'.notifications_filter') - ->eq('notifications_enabled', '1') - ->neq(UserModel::TABLE.'.id', $exclude_user_id) - ->eq(UserModel::TABLE.'.is_active', 1) - ->findAll(); - } -} diff --git a/sources/app/Model/UserNotificationTypeModel.php b/sources/app/Model/UserNotificationTypeModel.php deleted file mode 100644 index 0f37722..0000000 --- a/sources/app/Model/UserNotificationTypeModel.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php - -namespace Kanboard\Model; - -/** - * User Notification Type - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class UserNotificationTypeModel extends NotificationTypeModel -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'user_has_notification_types'; - - /** - * Get selected notification types for a given user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getSelectedTypes($user_id) - { - $types = $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('notification_type')->findAllByColumn('notification_type'); - return $this->filterTypes($types); - } - - /** - * Save notification types for a given user - * - * @access public - * @param integer $user_id - * @param string[] $types - * @return boolean - */ - public function saveSelectedTypes($user_id, array $types) - { - $results = array(); - $this->db->table(self::TABLE)->eq('user_id', $user_id)->remove(); - - foreach ($types as $type) { - $results[] = $this->db->table(self::TABLE)->insert(array('user_id' => $user_id, 'notification_type' => $type)); - } - - return ! in_array(false, $results, true); - } -} diff --git a/sources/app/Model/UserUnreadNotificationModel.php b/sources/app/Model/UserUnreadNotificationModel.php deleted file mode 100644 index 6c930ee..0000000 --- a/sources/app/Model/UserUnreadNotificationModel.php +++ /dev/null @@ -1,117 +0,0 @@ -<?php - -namespace Kanboard\Model; - -use Kanboard\Core\Base; - -/** - * User Unread Notification - * - * @package Kanboard\Model - * @author Frederic Guillot - */ -class UserUnreadNotificationModel extends Base -{ - /** - * SQL table name - * - * @var string - */ - const TABLE = 'user_has_unread_notifications'; - - /** - * Add unread notification to someone - * - * @access public - * @param integer $user_id - * @param string $event_name - * @param array $event_data - */ - public function create($user_id, $event_name, array $event_data) - { - $this->db->table(self::TABLE)->insert(array( - 'user_id' => $user_id, - 'date_creation' => time(), - 'event_name' => $event_name, - 'event_data' => json_encode($event_data), - )); - } - - /** - * Get one notification - * - * @param integer $notification_id - * @return array|null - */ - public function getById($notification_id) - { - $notification = $this->db->table(self::TABLE)->eq('id', $notification_id)->findOne(); - - if (! empty($notification)) { - $this->unserialize($notification); - } - - return $notification; - } - - /** - * Get all notifications for a user - * - * @access public - * @param integer $user_id - * @return array - */ - public function getAll($user_id) - { - $events = $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('date_creation')->findAll(); - - foreach ($events as &$event) { - $this->unserialize($event); - } - - return $events; - } - - /** - * Mark a notification as read - * - * @access public - * @param integer $user_id - * @param integer $notification_id - * @return boolean - */ - public function markAsRead($user_id, $notification_id) - { - return $this->db->table(self::TABLE)->eq('id', $notification_id)->eq('user_id', $user_id)->remove(); - } - - /** - * Mark all notifications as read for a user - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function markAllAsRead($user_id) - { - return $this->db->table(self::TABLE)->eq('user_id', $user_id)->remove(); - } - - /** - * Return true if the user as unread notifications - * - * @access public - * @param integer $user_id - * @return boolean - */ - public function hasNotifications($user_id) - { - return $this->db->table(self::TABLE)->eq('user_id', $user_id)->exists(); - } - - private function unserialize(&$event) - { - $event['event_data'] = json_decode($event['event_data'], true); - $event['title'] = $this->notificationModel->getTitleWithoutAuthor($event['event_name'], $event['event_data']); - } -} diff --git a/sources/app/Notification/ActivityStreamNotification.php b/sources/app/Notification/ActivityStreamNotification.php deleted file mode 100644 index 9f23c88..0000000 --- a/sources/app/Notification/ActivityStreamNotification.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -namespace Kanboard\Notification; - -use Kanboard\Core\Base; -use Kanboard\Core\Notification\NotificationInterface; - -/** - * Activity Stream Notification - * - * @package Kanboard\Notification - * @author Frederic Guillot - */ -class ActivityStreamNotification extends Base implements NotificationInterface -{ - /** - * Send notification to a user - * - * @access public - * @param array $user - * @param string $event_name - * @param array $event_data - */ - public function notifyUser(array $user, $event_name, array $event_data) - { - } - - /** - * Send notification to a project - * - * @access public - * @param array $project - * @param string $event_name - * @param array $event_data - */ - public function notifyProject(array $project, $event_name, array $event_data) - { - if ($this->userSession->isLogged()) { - $this->projectActivityModel->createEvent( - $project['id'], - $event_data['task']['id'], - $this->userSession->getId(), - $event_name, - $event_data - ); - } - } -} diff --git a/sources/app/Notification/MailNotification.php b/sources/app/Notification/MailNotification.php deleted file mode 100644 index 2d27179..0000000 --- a/sources/app/Notification/MailNotification.php +++ /dev/null @@ -1,151 +0,0 @@ -<?php - -namespace Kanboard\Notification; - -use Kanboard\Core\Base; -use Kanboard\Core\Notification\NotificationInterface; -use Kanboard\Model\TaskModel; -use Kanboard\Model\TaskFileModel; -use Kanboard\Model\CommentModel; -use Kanboard\Model\SubtaskModel; - -/** - * Email Notification - * - * @package Kanboard\Notification - * @author Frederic Guillot - */ -class MailNotification extends Base implements NotificationInterface -{ - /** - * Notification type - * - * @var string - */ - const TYPE = 'email'; - - /** - * Send notification to a user - * - * @access public - * @param array $user - * @param string $event_name - * @param array $event_data - */ - public function notifyUser(array $user, $event_name, array $event_data) - { - if (! empty($user['email'])) { - $this->emailClient->send( - $user['email'], - $user['name'] ?: $user['username'], - $this->getMailSubject($event_name, $event_data), - $this->getMailContent($event_name, $event_data) - ); - } - } - - /** - * Send notification to a project - * - * @access public - * @param array $project - * @param string $event_name - * @param array $event_data - */ - public function notifyProject(array $project, $event_name, array $event_data) - { - } - - /** - * Get the mail content for a given template name - * - * @access public - * @param string $event_name Event name - * @param array $event_data Event data - * @return string - */ - public function getMailContent($event_name, array $event_data) - { - return $this->template->render( - 'notification/'.str_replace('.', '_', $event_name), - $event_data + array('application_url' => $this->configModel->get('application_url')) - ); - } - - /** - * Get the mail subject for a given template name - * - * @access public - * @param string $event_name Event name - * @param array $event_data Event data - * @return string - */ - public function getMailSubject($event_name, array $event_data) - { - switch ($event_name) { - case TaskFileModel::EVENT_CREATE: - $subject = $this->getStandardMailSubject(e('New attachment'), $event_data); - break; - case CommentModel::EVENT_CREATE: - $subject = $this->getStandardMailSubject(e('New comment'), $event_data); - break; - case CommentModel::EVENT_UPDATE: - $subject = $this->getStandardMailSubject(e('Comment updated'), $event_data); - break; - case SubtaskModel::EVENT_CREATE: - $subject = $this->getStandardMailSubject(e('New subtask'), $event_data); - break; - case SubtaskModel::EVENT_UPDATE: - $subject = $this->getStandardMailSubject(e('Subtask updated'), $event_data); - break; - case TaskModel::EVENT_CREATE: - $subject = $this->getStandardMailSubject(e('New task'), $event_data); - break; - case TaskModel::EVENT_UPDATE: - $subject = $this->getStandardMailSubject(e('Task updated'), $event_data); - break; - case TaskModel::EVENT_CLOSE: - $subject = $this->getStandardMailSubject(e('Task closed'), $event_data); - break; - case TaskModel::EVENT_OPEN: - $subject = $this->getStandardMailSubject(e('Task opened'), $event_data); - break; - case TaskModel::EVENT_MOVE_COLUMN: - $subject = $this->getStandardMailSubject(e('Column change'), $event_data); - break; - case TaskModel::EVENT_MOVE_POSITION: - $subject = $this->getStandardMailSubject(e('Position change'), $event_data); - break; - case TaskModel::EVENT_MOVE_SWIMLANE: - $subject = $this->getStandardMailSubject(e('Swimlane change'), $event_data); - break; - case TaskModel::EVENT_ASSIGNEE_CHANGE: - $subject = $this->getStandardMailSubject(e('Assignee change'), $event_data); - break; - case TaskModel::EVENT_USER_MENTION: - case CommentModel::EVENT_USER_MENTION: - $subject = $this->getStandardMailSubject(e('Mentioned'), $event_data); - break; - case TaskModel::EVENT_OVERDUE: - $subject = e('[%s] Overdue tasks', $event_data['project_name']); - break; - default: - $subject = e('Notification'); - } - - return $subject; - } - - /** - * Get the mail subject for a given label - * - * @access private - * @param string $label Label - * @param array $data Template data - * @return string - */ - private function getStandardMailSubject($label, array $data) - { - return sprintf('[%s][%s] %s (#%d)', $data['task']['project_name'], $label, $data['task']['title'], $data['task']['id']); - } -} diff --git a/sources/app/Notification/WebNotification.php b/sources/app/Notification/WebNotification.php deleted file mode 100644 index d881882..0000000 --- a/sources/app/Notification/WebNotification.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php - -namespace Kanboard\Notification; - -use Kanboard\Core\Base; -use Kanboard\Core\Notification\NotificationInterface; - -/** - * Web Notification - * - * @package Kanboard\Notification - * @author Frederic Guillot - */ -class WebNotification extends Base implements NotificationInterface -{ - /** - * Notification type - * - * @var string - */ - const TYPE = 'web'; - - /** - * Send notification to a user - * - * @access public - * @param array $user - * @param string $event_name - * @param array $event_data - */ - public function notifyUser(array $user, $event_name, array $event_data) - { - $this->userUnreadNotificationModel->create($user['id'], $event_name, $event_data); - } - - /** - * Send notification to a project - * - * @access public - * @param array $project - * @param string $event_name - * @param array $event_data - */ - public function notifyProject(array $project, $event_name, array $event_data) - { - } -} diff --git a/sources/app/Notification/WebhookNotification.php b/sources/app/Notification/WebhookNotification.php deleted file mode 100644 index 1604553..0000000 --- a/sources/app/Notification/WebhookNotification.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php - -namespace Kanboard\Notification; - -use Kanboard\Core\Base; -use Kanboard\Core\Notification\NotificationInterface; - -/** - * Webhook Notification - * - * @package Kanboard\Notification - * @author Frederic Guillot - */ -class WebhookNotification extends Base implements NotificationInterface -{ - /** - * Send notification to a user - * - * @access public - * @param array $user - * @param string $event_name - * @param array $event_data - */ - public function notifyUser(array $user, $event_name, array $event_data) - { - } - - /** - * Send notification to a project - * - * @access public - * @param array $project - * @param string $event_name - * @param array $event_data - */ - public function notifyProject(array $project, $event_name, array $event_data) - { - $url = $this->configModel->get('webhook_url'); - $token = $this->configModel->get('webhook_token'); - - if (! empty($url)) { - if (strpos($url, '?') !== false) { - $url .= '&token='.$token; - } else { - $url .= '?token='.$token; - } - - $payload = array( - 'event_name' => $event_name, - 'event_data' => $event_data, - ); - - $this->httpClient->postJson($url, $payload); - } - } -} diff --git a/sources/app/Schema/Mysql.php b/sources/app/Schema/Mysql.php deleted file mode 100644 index 82ccb8c..0000000 --- a/sources/app/Schema/Mysql.php +++ /dev/null @@ -1,1350 +0,0 @@ -<?php - -namespace Schema; - -use PDO; -use Kanboard\Core\Security\Token; -use Kanboard\Core\Security\Role; - -const VERSION = 111; - -function version_111(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE tags ( - id INT NOT NULL AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, - project_id INT NOT NULL, - UNIQUE(project_id, name), - PRIMARY KEY(id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE task_has_tags ( - task_id INT NOT NULL, - tag_id INT NOT NULL, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(tag_id) REFERENCES tags(id) ON DELETE CASCADE, - UNIQUE(tag_id, task_id) - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_110(PDO $pdo) -{ - $pdo->exec("ALTER TABLE user_has_notifications DROP FOREIGN KEY `user_has_notifications_ibfk_1`"); - $pdo->exec("ALTER TABLE user_has_notifications DROP FOREIGN KEY `user_has_notifications_ibfk_2`"); - $pdo->exec("DROP INDEX `project_id` ON user_has_notifications"); - $pdo->exec("ALTER TABLE user_has_notifications DROP KEY `user_id`"); - $pdo->exec("CREATE UNIQUE INDEX `user_has_notifications_unique_idx` ON `user_has_notifications` (`user_id`, `project_id`)"); - $pdo->exec("ALTER TABLE user_has_notifications ADD CONSTRAINT user_has_notifications_ibfk_1 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE"); - $pdo->exec("ALTER TABLE user_has_notifications ADD CONSTRAINT user_has_notifications_ibfk_2 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE"); -} - -function version_109(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN avatar_path VARCHAR(255)"); -} - -function version_108(PDO $pdo) -{ - $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE settings ADD COLUMN changed_by INT DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE settings ADD COLUMN changed_on INT DEFAULT 0 NOT NULL"); -} - -function version_107(PDO $pdo) -{ - $pdo->exec("UPDATE project_activities SET event_name='task.file.create' WHERE event_name='file.create'"); -} - -function version_106(PDO $pdo) -{ - $pdo->exec('RENAME TABLE files TO task_has_files'); - - $pdo->exec(" - CREATE TABLE project_has_files ( - `id` INT NOT NULL AUTO_INCREMENT, - `project_id` INT NOT NULL, - `name` VARCHAR(255) NOT NULL, - `path` VARCHAR(255) NOT NULL, - `is_image` TINYINT(1) DEFAULT 0, - `size` INT DEFAULT 0 NOT NULL, - `user_id` INT DEFAULT 0 NOT NULL, - `date` INT DEFAULT 0 NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - PRIMARY KEY(id) - ) ENGINE=InnoDB CHARSET=utf8" - ); -} - -function version_105(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_active TINYINT(1) DEFAULT 1"); -} - -function version_104(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_external_links ( - id INT NOT NULL AUTO_INCREMENT, - link_type VARCHAR(100) NOT NULL, - dependency VARCHAR(100) NOT NULL, - title VARCHAR(255) NOT NULL, - url VARCHAR(255) NOT NULL, - date_creation INT NOT NULL, - date_modification INT NOT NULL, - task_id INT NOT NULL, - creator_id INT DEFAULT 0, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - PRIMARY KEY(id) - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_103(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_default INT DEFAULT 0"); - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_start INT DEFAULT 0"); - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_end INT DEFAULT 3"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN priority INT DEFAULT 0"); -} - -function version_102(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN owner_id INT DEFAULT 0"); -} - -function version_101(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE password_reset ( - token VARCHAR(80) PRIMARY KEY, - user_id INT NOT NULL, - date_expiration INT NOT NULL, - date_creation INT NOT NULL, - ip VARCHAR(45) NOT NULL, - user_agent VARCHAR(255) NOT NULL, - is_active TINYINT(1) NOT NULL, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec("INSERT INTO settings VALUES ('password_reset', '1')"); -} - -function version_100(PDO $pdo) -{ - $pdo->exec('ALTER TABLE `actions` MODIFY `action_name` VARCHAR(255)'); -} - -function version_99(PDO $pdo) -{ - $rq = $pdo->prepare('SELECT * FROM actions'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE actions SET action_name=? WHERE id=?'); - - foreach ($rows as $row) { - if ($row['action_name'] === 'TaskAssignCurrentUser' && $row['event_name'] === 'task.move.column') { - $row['action_name'] = '\Kanboard\Action\TaskAssignCurrentUserColumn'; - } elseif ($row['action_name'] === 'TaskClose' && $row['event_name'] === 'task.move.column') { - $row['action_name'] = '\Kanboard\Action\TaskCloseColumn'; - } elseif ($row['action_name'] === 'TaskLogMoveAnotherColumn') { - $row['action_name'] = '\Kanboard\Action\CommentCreationMoveTaskColumn'; - } elseif ($row['action_name']{0} !== '\\') { - $row['action_name'] = '\Kanboard\Action\\'.$row['action_name']; - } - - $rq->execute(array($row['action_name'], $row['id'])); - } -} - -function version_98(PDO $pdo) -{ - $pdo->exec('ALTER TABLE `users` MODIFY `language` VARCHAR(5)'); -} - -function version_97(PDO $pdo) -{ - $pdo->exec("ALTER TABLE `users` ADD COLUMN `role` VARCHAR(25) NOT NULL DEFAULT '".Role::APP_USER."'"); - - $rq = $pdo->prepare('SELECT * FROM `users`'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE `users` SET `role`=? WHERE `id`=?'); - - foreach ($rows as $row) { - $role = Role::APP_USER; - - if ($row['is_admin'] == 1) { - $role = Role::APP_ADMIN; - } else if ($row['is_project_admin']) { - $role = Role::APP_MANAGER; - } - - $rq->execute(array($role, $row['id'])); - } - - $pdo->exec('ALTER TABLE `users` DROP COLUMN `is_admin`'); - $pdo->exec('ALTER TABLE `users` DROP COLUMN `is_project_admin`'); -} - -function version_96(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_groups ( - `group_id` INT NOT NULL, - `project_id` INT NOT NULL, - `role` VARCHAR(25) NOT NULL, - FOREIGN KEY(group_id) REFERENCES groups(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(group_id, project_id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec("ALTER TABLE `project_has_users` ADD COLUMN `role` VARCHAR(25) NOT NULL DEFAULT '".Role::PROJECT_VIEWER."'"); - - $rq = $pdo->prepare('SELECT * FROM project_has_users'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE `project_has_users` SET `role`=? WHERE `id`=?'); - - foreach ($rows as $row) { - $rq->execute(array( - $row['is_owner'] == 1 ? Role::PROJECT_MANAGER : Role::PROJECT_MEMBER, - $row['id'], - )); - } - - $pdo->exec('ALTER TABLE `project_has_users` DROP COLUMN `is_owner`'); - $pdo->exec('ALTER TABLE `project_has_users` DROP COLUMN `id`'); -} - -function version_95(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE groups ( - id INT NOT NULL AUTO_INCREMENT, - external_id VARCHAR(255) DEFAULT '', - name VARCHAR(100) NOT NULL UNIQUE, - PRIMARY KEY(id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE group_has_users ( - group_id INT NOT NULL, - user_id INT NOT NULL, - FOREIGN KEY(group_id) REFERENCES groups(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(group_id, user_id) - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_94(PDO $pdo) -{ - $pdo->exec('ALTER TABLE `projects` DROP INDEX `name`'); - $pdo->exec('ALTER TABLE `projects` DROP INDEX `name_2`'); -} - -function version_93(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE user_has_metadata ( - user_id INT NOT NULL, - name VARCHAR(50) NOT NULL, - value VARCHAR(255) DEFAULT '', - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(user_id, name) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE project_has_metadata ( - project_id INT NOT NULL, - name VARCHAR(50) NOT NULL, - value VARCHAR(255) DEFAULT '', - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, name) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE task_has_metadata ( - task_id INT NOT NULL, - name VARCHAR(50) NOT NULL, - value VARCHAR(255) DEFAULT '', - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - UNIQUE(task_id, name) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec("DROP TABLE project_integrations"); - - $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_server'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_domain'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_username'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_password'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_nickname'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_jabber_room'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat_api_url'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat_room_id'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_hipchat_room_token'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_slack_webhook'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_slack_webhook_url'"); - $pdo->exec("DELETE FROM settings WHERE `option`='integration_slack_webhook_channel'"); -} - -function version_92(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_notification_types ( - id INT NOT NULL AUTO_INCREMENT, - project_id INT NOT NULL, - notification_type VARCHAR(50) NOT NULL, - PRIMARY KEY(id), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, notification_type) - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_91(PDO $pdo) -{ - $pdo->exec("ALTER TABLE custom_filters ADD COLUMN `append` TINYINT(1) DEFAULT 0"); -} - -function version_90(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks MODIFY date_due BIGINT"); - $pdo->exec("ALTER TABLE tasks MODIFY date_creation BIGINT"); - $pdo->exec("ALTER TABLE tasks MODIFY date_completed BIGINT"); - $pdo->exec("ALTER TABLE tasks MODIFY date_started BIGINT"); - $pdo->exec("ALTER TABLE tasks MODIFY date_moved BIGINT"); - $pdo->exec("ALTER TABLE comments MODIFY date_creation BIGINT"); - $pdo->exec("ALTER TABLE last_logins MODIFY date_creation BIGINT"); - $pdo->exec("ALTER TABLE project_activities MODIFY date_creation BIGINT"); - $pdo->exec("ALTER TABLE projects MODIFY last_modified BIGINT"); - $pdo->exec("ALTER TABLE remember_me MODIFY date_creation BIGINT"); - $pdo->exec('ALTER TABLE files MODIFY `date` BIGINT'); - $pdo->exec('ALTER TABLE transitions MODIFY `date` BIGINT'); - $pdo->exec('ALTER TABLE subtask_time_tracking MODIFY `start` BIGINT'); - $pdo->exec('ALTER TABLE subtask_time_tracking MODIFY `end` BIGINT'); - $pdo->exec('ALTER TABLE users MODIFY `lock_expiration_date` BIGINT'); -} - -function version_89(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE user_has_unread_notifications ( - id INT NOT NULL AUTO_INCREMENT, - user_id INT NOT NULL, - date_creation BIGINT NOT NULL, - event_name VARCHAR(50) NOT NULL, - event_data TEXT NOT NULL, - PRIMARY KEY(id), - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE user_has_notification_types ( - id INT NOT NULL AUTO_INCREMENT, - user_id INT NOT NULL, - notification_type VARCHAR(50), - PRIMARY KEY(id), - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec('CREATE UNIQUE INDEX user_has_notification_types_user_idx ON user_has_notification_types(user_id, notification_type)'); - - // Migrate people who have notification enabled before - $rq = $pdo->prepare('SELECT id FROM users WHERE notifications_enabled=1'); - $rq->execute(); - $user_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0); - - foreach ($user_ids as $user_id) { - $rq = $pdo->prepare('INSERT INTO user_has_notification_types (user_id, notification_type) VALUES (?, ?)'); - $rq->execute(array($user_id, 'email')); - } -} - -function version_88(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE custom_filters ( - id INT NOT NULL AUTO_INCREMENT, - filter VARCHAR(100) NOT NULL, - project_id INT NOT NULL, - user_id INT NOT NULL, - name VARCHAR(100) NOT NULL, - is_shared TINYINT(1) DEFAULT 0, - PRIMARY KEY(id), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_87(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE plugin_schema_versions ( - plugin VARCHAR(80) NOT NULL, - version INT NOT NULL DEFAULT 0, - PRIMARY KEY(plugin) - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_86(PDO $pdo) -{ - $pdo->exec("ALTER TABLE swimlanes ADD COLUMN description TEXT"); -} - -function version_85(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN gitlab_id INT"); -} - -function version_84(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN start_date VARCHAR(10) DEFAULT ''"); - $pdo->exec("ALTER TABLE projects ADD COLUMN end_date VARCHAR(10) DEFAULT ''"); -} - -function version_83(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_project_admin INT DEFAULT 0"); -} - -function version_82(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN nb_failed_login INT DEFAULT 0"); - $pdo->exec("ALTER TABLE users ADD COLUMN lock_expiration_date INT DEFAULT 0"); -} - -function version_81(PDO $pdo) -{ - $pdo->exec("INSERT INTO settings VALUES ('subtask_time_tracking', '1')"); - $pdo->exec("INSERT INTO settings VALUES ('cfd_include_closed_tasks', '1')"); -} - -function version_80(PDO $pdo) -{ - $pdo->exec("INSERT INTO settings VALUES ('default_color', 'yellow')"); -} - -function version_79(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_daily_stats ( - id INT NOT NULL AUTO_INCREMENT, - day CHAR(10) NOT NULL, - project_id INT NOT NULL, - avg_lead_time INT NOT NULL DEFAULT 0, - avg_cycle_time INT NOT NULL DEFAULT 0, - PRIMARY KEY(id), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec('CREATE UNIQUE INDEX project_daily_stats_idx ON project_daily_stats(day, project_id)'); - - $pdo->exec('RENAME TABLE project_daily_summaries TO project_daily_column_stats'); -} - -function version_78(PDO $pdo) -{ - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN slack_webhook_channel VARCHAR(255) DEFAULT ''"); - $pdo->exec("INSERT INTO settings VALUES ('integration_slack_webhook_channel', '')"); -} - -function version_77(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users DROP COLUMN `default_project_id`'); -} - -function version_76(PDO $pdo) -{ - $pdo->exec("DELETE FROM `settings` WHERE `option`='subtask_time_tracking'"); -} - -function version_75(PDO $pdo) -{ - $pdo->exec('ALTER TABLE comments DROP FOREIGN KEY comments_ibfk_2'); - $pdo->exec('ALTER TABLE comments MODIFY task_id INT NOT NULL'); - $pdo->exec('ALTER TABLE comments CHANGE COLUMN `user_id` `user_id` INT DEFAULT 0'); - $pdo->exec('ALTER TABLE comments CHANGE COLUMN `date` `date_creation` INT NOT NULL'); -} - -function version_74(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_has_categories MODIFY project_id INT NOT NULL'); - $pdo->exec('ALTER TABLE project_has_categories MODIFY name VARCHAR(255) NOT NULL'); - - $pdo->exec('ALTER TABLE actions MODIFY project_id INT NOT NULL'); - $pdo->exec('ALTER TABLE actions MODIFY event_name VARCHAR(50) NOT NULL'); - $pdo->exec('ALTER TABLE actions MODIFY action_name VARCHAR(50) NOT NULL'); - - $pdo->exec('ALTER TABLE action_has_params MODIFY action_id INT NOT NULL'); - $pdo->exec('ALTER TABLE action_has_params MODIFY name VARCHAR(50) NOT NULL'); - $pdo->exec('ALTER TABLE action_has_params MODIFY value VARCHAR(50) NOT NULL'); - - $pdo->exec('ALTER TABLE files MODIFY name VARCHAR(255) NOT NULL'); - $pdo->exec('ALTER TABLE files MODIFY task_id INT NOT NULL'); - - $pdo->exec('ALTER TABLE subtasks MODIFY title VARCHAR(255) NOT NULL'); - - $pdo->exec('ALTER TABLE tasks MODIFY project_id INT NOT NULL'); - $pdo->exec('ALTER TABLE tasks MODIFY column_id INT NOT NULL'); - - $pdo->exec('ALTER TABLE columns MODIFY title VARCHAR(255) NOT NULL'); - $pdo->exec('ALTER TABLE columns MODIFY project_id INT NOT NULL'); - - $pdo->exec('ALTER TABLE project_has_users MODIFY project_id INT NOT NULL'); - $pdo->exec('ALTER TABLE project_has_users MODIFY user_id INT NOT NULL'); - - $pdo->exec('ALTER TABLE projects MODIFY name VARCHAR(255) NOT NULL UNIQUE'); - - $pdo->exec('ALTER TABLE users MODIFY username VARCHAR(50) NOT NULL'); - - $pdo->exec('ALTER TABLE user_has_notifications MODIFY project_id INT NOT NULL'); - $pdo->exec('ALTER TABLE user_has_notifications MODIFY user_id INT NOT NULL'); -} - -function version_73(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN notifications_filter INT DEFAULT 4"); -} - -function version_72(PDO $pdo) -{ - $pdo->exec('ALTER TABLE files MODIFY name VARCHAR(255)'); -} - -function version_71(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO `settings` VALUES (?, ?)'); - $rq->execute(array('webhook_url', '')); - - $pdo->exec("DELETE FROM `settings` WHERE `option`='webhook_url_task_creation'"); - $pdo->exec("DELETE FROM `settings` WHERE `option`='webhook_url_task_modification'"); -} - -function version_70(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN token VARCHAR(255) DEFAULT ''"); -} - -function version_69(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('calendar_user_subtasks_time_tracking', 0)); - $rq->execute(array('calendar_user_tasks', 'date_started')); - $rq->execute(array('calendar_project_tasks', 'date_started')); - - $pdo->exec("DELETE FROM `settings` WHERE `option`='subtask_forecast'"); -} - -function version_68(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_jabber', '0')); - $rq->execute(array('integration_jabber_server', '')); - $rq->execute(array('integration_jabber_domain', '')); - $rq->execute(array('integration_jabber_username', '')); - $rq->execute(array('integration_jabber_password', '')); - $rq->execute(array('integration_jabber_nickname', 'kanboard')); - $rq->execute(array('integration_jabber_room', '')); - - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber INTEGER DEFAULT '0'"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_server VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_domain VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_username VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_password VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_nickname VARCHAR(255) DEFAULT 'kanboard'"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_room VARCHAR(255) DEFAULT ''"); -} - -function version_67(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_status INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_trigger INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_factor INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_timeframe INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_basedate INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_parent INTEGER'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_child INTEGER'); -} - -function version_66(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN identifier VARCHAR(50) DEFAULT ''"); -} - -function version_65(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_integrations ( - `id` INT NOT NULL AUTO_INCREMENT, - `project_id` INT NOT NULL UNIQUE, - `hipchat` TINYINT(1) DEFAULT 0, - `hipchat_api_url` VARCHAR(255) DEFAULT 'https://api.hipchat.com', - `hipchat_room_id` VARCHAR(255), - `hipchat_room_token` VARCHAR(255), - `slack` TINYINT(1) DEFAULT 0, - `slack_webhook_url` VARCHAR(255), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - PRIMARY KEY(id) - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_64(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_daily_summaries ADD COLUMN score INT NOT NULL DEFAULT 0'); -} - -function version_63(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_has_categories ADD COLUMN description TEXT'); -} - -function version_62(PDO $pdo) -{ - $pdo->exec('ALTER TABLE files ADD COLUMN `date` INT NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE files ADD COLUMN `user_id` INT NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE files ADD COLUMN `size` INT NOT NULL DEFAULT 0'); -} - -function version_61(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN twofactor_activated TINYINT(1) DEFAULT 0'); - $pdo->exec('ALTER TABLE users ADD COLUMN twofactor_secret CHAR(16)'); -} - -function version_60(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_gravatar', '0')); -} - -function version_59(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_hipchat', '0')); - $rq->execute(array('integration_hipchat_api_url', 'https://api.hipchat.com')); - $rq->execute(array('integration_hipchat_room_id', '')); - $rq->execute(array('integration_hipchat_room_token', '')); -} - -function version_58(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_slack_webhook', '0')); - $rq->execute(array('integration_slack_webhook_url', '')); -} - -function version_57(PDO $pdo) -{ - $pdo->exec('CREATE TABLE currencies (`currency` CHAR(3) NOT NULL UNIQUE, `rate` FLOAT DEFAULT 0) ENGINE=InnoDB CHARSET=utf8'); - - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_currency', 'USD')); -} - -function version_56(PDO $pdo) -{ - $pdo->exec('CREATE TABLE transitions ( - `id` INT NOT NULL AUTO_INCREMENT, - `user_id` INT NOT NULL, - `project_id` INT NOT NULL, - `task_id` INT NOT NULL, - `src_column_id` INT NOT NULL, - `dst_column_id` INT NOT NULL, - `date` INT NOT NULL, - `time_spent` INT DEFAULT 0, - FOREIGN KEY(src_column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(dst_column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - PRIMARY KEY(id) - ) ENGINE=InnoDB CHARSET=utf8'); - - $pdo->exec("CREATE INDEX transitions_task_index ON transitions(task_id)"); - $pdo->exec("CREATE INDEX transitions_project_index ON transitions(project_id)"); - $pdo->exec("CREATE INDEX transitions_user_index ON transitions(user_id)"); -} - -function version_55(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('subtask_forecast', '0')); -} - -function version_54(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_stylesheet', '')); -} - -function version_53(PDO $pdo) -{ - $pdo->exec("ALTER TABLE subtask_time_tracking ADD COLUMN time_spent FLOAT DEFAULT 0"); -} - -function version_49(PDO $pdo) -{ - $pdo->exec('ALTER TABLE subtasks ADD COLUMN position INTEGER DEFAULT 1'); - - $task_id = 0; - $position = 1; - $urq = $pdo->prepare('UPDATE subtasks SET position=? WHERE id=?'); - - $rq = $pdo->prepare('SELECT * FROM subtasks ORDER BY task_id, id ASC'); - $rq->execute(); - - foreach ($rq->fetchAll(PDO::FETCH_ASSOC) as $subtask) { - if ($task_id != $subtask['task_id']) { - $position = 1; - $task_id = $subtask['task_id']; - } - - $urq->execute(array($position, $subtask['id'])); - $position++; - } -} - -function version_48(PDO $pdo) -{ - $pdo->exec('RENAME TABLE task_has_files TO files'); - $pdo->exec('RENAME TABLE task_has_subtasks TO subtasks'); -} - -function version_47(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects ADD COLUMN description TEXT'); -} - -function version_46(PDO $pdo) -{ - $pdo->exec("CREATE TABLE links ( - id INT NOT NULL AUTO_INCREMENT, - label VARCHAR(255) NOT NULL, - opposite_id INT DEFAULT 0, - PRIMARY KEY(id), - UNIQUE(label) - ) ENGINE=InnoDB CHARSET=utf8"); - - $pdo->exec("CREATE TABLE task_has_links ( - id INT NOT NULL AUTO_INCREMENT, - link_id INT NOT NULL, - task_id INT NOT NULL, - opposite_task_id INT NOT NULL, - FOREIGN KEY(link_id) REFERENCES links(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(opposite_task_id) REFERENCES tasks(id) ON DELETE CASCADE, - PRIMARY KEY(id) - ) ENGINE=InnoDB CHARSET=utf8"); - - $pdo->exec("CREATE INDEX task_has_links_task_index ON task_has_links(task_id)"); - $pdo->exec("CREATE UNIQUE INDEX task_has_links_unique ON task_has_links(link_id, task_id, opposite_task_id)"); - - $rq = $pdo->prepare('INSERT INTO links (label, opposite_id) VALUES (?, ?)'); - $rq->execute(array('relates to', 0)); - $rq->execute(array('blocks', 3)); - $rq->execute(array('is blocked by', 2)); - $rq->execute(array('duplicates', 5)); - $rq->execute(array('is duplicated by', 4)); - $rq->execute(array('is a child of', 7)); - $rq->execute(array('is a parent of', 6)); - $rq->execute(array('targets milestone', 9)); - $rq->execute(array('is a milestone of', 8)); - $rq->execute(array('fixes', 11)); - $rq->execute(array('is fixed by', 10)); -} - -function version_45(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ADD COLUMN date_moved INT DEFAULT 0'); - - /* Update tasks.date_moved from project_activities table if tasks.date_moved = null or 0. - * We take max project_activities.date_creation where event_name in task.create','task.move.column - * since creation date is always less than task moves - */ - $pdo->exec("UPDATE tasks - SET date_moved = ( - SELECT md - FROM ( - SELECT task_id, max(date_creation) md - FROM project_activities - WHERE event_name IN ('task.create', 'task.move.column') - GROUP BY task_id - ) src - WHERE id = src.task_id - ) - WHERE (date_moved IS NULL OR date_moved = 0) AND id IN ( - SELECT task_id - FROM ( - SELECT task_id, max(date_creation) md - FROM project_activities - WHERE event_name IN ('task.create', 'task.move.column') - GROUP BY task_id - ) src - )"); - - // If there is no activities for some tasks use the date_creation - $pdo->exec("UPDATE tasks SET date_moved = date_creation WHERE date_moved IS NULL OR date_moved = 0"); -} - -function version_44(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN disable_login_form TINYINT(1) DEFAULT 0'); -} - -function version_43(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('subtask_restriction', '0')); - $rq->execute(array('subtask_time_tracking', '0')); - - $pdo->exec(" - CREATE TABLE subtask_time_tracking ( - id INT NOT NULL AUTO_INCREMENT, - user_id INT NOT NULL, - subtask_id INT NOT NULL, - start INT DEFAULT 0, - end INT DEFAULT 0, - PRIMARY KEY(id), - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(subtask_id) REFERENCES task_has_subtasks(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_42(PDO $pdo) -{ - $pdo->exec('ALTER TABLE columns ADD COLUMN description TEXT'); -} - -function version_41(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN timezone VARCHAR(50)'); - $pdo->exec('ALTER TABLE users ADD COLUMN language CHAR(5)'); -} - -function version_40(PDO $pdo) -{ - // Avoid some full table scans - $pdo->exec('CREATE INDEX users_admin_idx ON users(is_admin)'); - $pdo->exec('CREATE INDEX columns_project_idx ON columns(project_id)'); - $pdo->exec('CREATE INDEX tasks_project_idx ON tasks(project_id)'); - $pdo->exec('CREATE INDEX swimlanes_project_idx ON swimlanes(project_id)'); - $pdo->exec('CREATE INDEX categories_project_idx ON project_has_categories(project_id)'); - $pdo->exec('CREATE INDEX subtasks_task_idx ON task_has_subtasks(task_id)'); - $pdo->exec('CREATE INDEX files_task_idx ON task_has_files(task_id)'); - $pdo->exec('CREATE INDEX comments_task_idx ON comments(task_id)'); - - // Set the ownership for all private projects - $rq = $pdo->prepare('SELECT id FROM projects WHERE is_private=1'); - $rq->execute(); - $project_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0); - - $rq = $pdo->prepare('UPDATE project_has_users SET is_owner=1 WHERE project_id=?'); - - foreach ($project_ids as $project_id) { - $rq->execute(array($project_id)); - } -} - -function version_39(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('project_categories', '')); -} - -function version_38(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE swimlanes ( - id INT NOT NULL AUTO_INCREMENT, - name VARCHAR(200) NOT NULL, - position INT DEFAULT 1, - is_active INT DEFAULT 1, - project_id INT, - PRIMARY KEY(id), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE (name, project_id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec('ALTER TABLE tasks ADD COLUMN swimlane_id INT DEFAULT 0'); - $pdo->exec("ALTER TABLE projects ADD COLUMN default_swimlane VARCHAR(200) DEFAULT 'Default swimlane'"); - $pdo->exec("ALTER TABLE projects ADD COLUMN show_default_swimlane INT DEFAULT 1"); -} - -function version_37(PDO $pdo) -{ - $pdo->exec("ALTER TABLE project_has_users ADD COLUMN is_owner TINYINT(1) DEFAULT '0'"); -} - -function version_36(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks MODIFY title VARCHAR(255) NOT NULL'); -} - -function version_35(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_daily_summaries ( - id INT NOT NULL AUTO_INCREMENT, - day CHAR(10) NOT NULL, - project_id INT NOT NULL, - column_id INT NOT NULL, - total INT NOT NULL DEFAULT 0, - PRIMARY KEY(id), - FOREIGN KEY(column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec('CREATE UNIQUE INDEX project_daily_column_stats_idx ON project_daily_summaries(day, project_id, column_id)'); -} - -function version_34(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN is_everybody_allowed TINYINT(1) DEFAULT '0'"); -} - -function version_33(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_activities ( - id INT NOT NULL AUTO_INCREMENT, - date_creation INT NOT NULL, - event_name VARCHAR(50) NOT NULL, - creator_id INT, - project_id INT, - task_id INT, - data TEXT, - PRIMARY KEY(id), - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec('DROP TABLE task_has_events'); - $pdo->exec('DROP TABLE comment_has_events'); - $pdo->exec('DROP TABLE subtask_has_events'); -} - -function version_32(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN date_started INTEGER"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN time_spent FLOAT DEFAULT 0"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN time_estimated FLOAT DEFAULT 0"); - - $pdo->exec("ALTER TABLE task_has_subtasks MODIFY time_estimated FLOAT"); - $pdo->exec("ALTER TABLE task_has_subtasks MODIFY time_spent FLOAT"); -} - -function version_31(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN is_private TINYINT(1) DEFAULT '0'"); -} - -function version_30(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_date_format', 'm/d/Y')); -} - -function version_29(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE settings ( - `option` VARCHAR(100) PRIMARY KEY, - `value` VARCHAR(255) DEFAULT '' - ) - "); - - // Migrate old config parameters - $rq = $pdo->prepare('SELECT * FROM config'); - $rq->execute(); - $parameters = $rq->fetch(PDO::FETCH_ASSOC); - - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('board_highlight_period', defined('RECENT_TASK_PERIOD') ? RECENT_TASK_PERIOD : 48*60*60)); - $rq->execute(array('board_public_refresh_interval', defined('BOARD_PUBLIC_CHECK_INTERVAL') ? BOARD_PUBLIC_CHECK_INTERVAL : 60)); - $rq->execute(array('board_private_refresh_interval', defined('BOARD_CHECK_INTERVAL') ? BOARD_CHECK_INTERVAL : 10)); - $rq->execute(array('board_columns', $parameters['default_columns'])); - $rq->execute(array('webhook_url_task_creation', $parameters['webhooks_url_task_creation'])); - $rq->execute(array('webhook_url_task_modification', $parameters['webhooks_url_task_modification'])); - $rq->execute(array('webhook_token', $parameters['webhooks_token'])); - $rq->execute(array('api_token', $parameters['api_token'])); - $rq->execute(array('application_language', $parameters['language'])); - $rq->execute(array('application_timezone', $parameters['timezone'])); - $rq->execute(array('application_url', defined('KANBOARD_URL') ? KANBOARD_URL : '')); - - $pdo->exec('DROP TABLE config'); -} - -function version_28(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN reference VARCHAR(50) DEFAULT ''"); - $pdo->exec("ALTER TABLE comments ADD COLUMN reference VARCHAR(50) DEFAULT ''"); - - $pdo->exec('CREATE INDEX tasks_reference_idx ON tasks(reference)'); - $pdo->exec('CREATE INDEX comments_reference_idx ON comments(reference)'); -} - -function version_27(PDO $pdo) -{ - $pdo->exec('CREATE UNIQUE INDEX users_username_idx ON users(username)'); -} - -function version_26(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN default_columns VARCHAR(255) DEFAULT ''"); -} - -function version_25(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_events ( - id INT NOT NULL AUTO_INCREMENT, - date_creation INT NOT NULL, - event_name TEXT NOT NULL, - creator_id INT, - project_id INT, - task_id INT, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - PRIMARY KEY (id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE subtask_has_events ( - id INT NOT NULL AUTO_INCREMENT, - date_creation INT NOT NULL, - event_name TEXT NOT NULL, - creator_id INT, - project_id INT, - subtask_id INT, - task_id INT, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(subtask_id) REFERENCES task_has_subtasks(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - PRIMARY KEY (id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE comment_has_events ( - id INT NOT NULL AUTO_INCREMENT, - date_creation INT NOT NULL, - event_name TEXT NOT NULL, - creator_id INT, - project_id INT, - comment_id INT, - task_id INT, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(comment_id) REFERENCES comments(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - PRIMARY KEY (id) - ) ENGINE=InnoDB CHARSET=utf8 - "); -} - -function version_24(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN is_public TINYINT(1) DEFAULT '0'"); -} - -function version_23(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN notifications_enabled TINYINT(1) DEFAULT '0'"); - - $pdo->exec(" - CREATE TABLE user_has_notifications ( - user_id INT, - project_id INT, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, user_id) - ); - "); -} - -function version_22(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_modification VARCHAR(255)"); - $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_creation VARCHAR(255)"); -} - -function version_21(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN creator_id INTEGER DEFAULT '0'"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN date_modification INTEGER DEFAULT '0'"); -} - -function version_20(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN github_id VARCHAR(30)"); -} - -function version_19(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN api_token VARCHAR(255) DEFAULT ''"); - $pdo->exec("UPDATE config SET api_token='".Token::getToken()."'"); -} - -function version_18(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_subtasks ( - id INT NOT NULL AUTO_INCREMENT, - title VARCHAR(255), - status INT DEFAULT 0, - time_estimated INT DEFAULT 0, - time_spent INT DEFAULT 0, - task_id INT NOT NULL, - user_id INT, - PRIMARY KEY (id), - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8" - ); -} - -function version_17(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_files ( - id INT NOT NULL AUTO_INCREMENT, - name VARCHAR(50), - path VARCHAR(255), - is_image TINYINT(1) DEFAULT 0, - task_id INT, - PRIMARY KEY (id), - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8" - ); -} - -function version_16(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_categories ( - id INT NOT NULL AUTO_INCREMENT, - name VARCHAR(255), - project_id INT, - PRIMARY KEY (id), - UNIQUE KEY `idx_project_category` (project_id, name), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8" - ); - - $pdo->exec("ALTER TABLE tasks ADD COLUMN category_id INT DEFAULT 0"); -} - -function version_15(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN last_modified INT DEFAULT 0"); -} - -function version_14(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN name VARCHAR(255)"); - $pdo->exec("ALTER TABLE users ADD COLUMN email VARCHAR(255)"); - $pdo->exec("ALTER TABLE users ADD COLUMN google_id VARCHAR(30)"); -} - -function version_13(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_ldap_user TINYINT(1) DEFAULT 0"); -} - -function version_12(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE remember_me ( - id INT NOT NULL AUTO_INCREMENT, - user_id INT, - ip VARCHAR(45), - user_agent VARCHAR(255), - token VARCHAR(255), - sequence VARCHAR(255), - expiration INT, - date_creation INT, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - PRIMARY KEY (id) - ) ENGINE=InnoDB CHARSET=utf8" - ); - - $pdo->exec(" - CREATE TABLE last_logins ( - id INT NOT NULL AUTO_INCREMENT, - auth_type VARCHAR(25), - user_id INT, - ip VARCHAR(45), - user_agent VARCHAR(255), - date_creation INT, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - PRIMARY KEY (id), - INDEX (user_id) - ) ENGINE=InnoDB CHARSET=utf8" - ); -} - -function version_1(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE config ( - language CHAR(5) DEFAULT 'en_US', - webhooks_token VARCHAR(255) DEFAULT '', - timezone VARCHAR(50) DEFAULT 'UTC' - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE users ( - id INT NOT NULL AUTO_INCREMENT, - username VARCHAR(50), - password VARCHAR(255), - is_admin TINYINT DEFAULT 0, - default_project_id INT DEFAULT 0, - PRIMARY KEY (id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE projects ( - id INT NOT NULL AUTO_INCREMENT, - name VARCHAR(50) UNIQUE, - is_active TINYINT DEFAULT 1, - token VARCHAR(255), - PRIMARY KEY (id) - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE project_has_users ( - id INT NOT NULL AUTO_INCREMENT, - project_id INT, - user_id INT, - PRIMARY KEY (id), - UNIQUE KEY `idx_project_user` (project_id, user_id), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE columns ( - id INT NOT NULL AUTO_INCREMENT, - title VARCHAR(255), - position INT NOT NULL, - project_id INT NOT NULL, - task_limit INT DEFAULT '0', - UNIQUE KEY `idx_title_project` (title, project_id), - PRIMARY KEY (id), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE tasks ( - id INT NOT NULL AUTO_INCREMENT, - title VARCHAR(255), - description TEXT, - date_creation INT, - date_completed INT, - date_due INT, - color_id VARCHAR(50), - project_id INT, - column_id INT, - owner_id INT DEFAULT '0', - position INT, - score INT, - is_active TINYINT DEFAULT 1, - PRIMARY KEY (id), - INDEX `idx_task_active` (is_active), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(column_id) REFERENCES columns(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE comments ( - id INT NOT NULL AUTO_INCREMENT, - task_id INT, - user_id INT, - `date` INT, - comment TEXT, - PRIMARY KEY (id), - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE actions ( - id INT NOT NULL AUTO_INCREMENT, - project_id INT, - event_name VARCHAR(50), - action_name VARCHAR(50), - PRIMARY KEY (id), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - CREATE TABLE action_has_params ( - id INT NOT NULL AUTO_INCREMENT, - action_id INT, - name VARCHAR(50), - value VARCHAR(50), - PRIMARY KEY (id), - FOREIGN KEY(action_id) REFERENCES actions(id) ON DELETE CASCADE - ) ENGINE=InnoDB CHARSET=utf8 - "); - - $pdo->exec(" - INSERT INTO users - (username, password, is_admin) - VALUES ('admin', '".\password_hash('admin', PASSWORD_BCRYPT)."', '1') - "); - - $pdo->exec(" - INSERT INTO config - (webhooks_token) - VALUES ('".Token::getToken()."') - "); -} diff --git a/sources/app/Schema/Postgres.php b/sources/app/Schema/Postgres.php deleted file mode 100644 index 229cbd2..0000000 --- a/sources/app/Schema/Postgres.php +++ /dev/null @@ -1,1237 +0,0 @@ -<?php - -namespace Schema; - -use PDO; -use Kanboard\Core\Security\Token; -use Kanboard\Core\Security\Role; - -const VERSION = 90; - -function version_90(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE tags ( - id SERIAL PRIMARY KEY, - name VARCHAR(255) NOT NULL, - project_id INTEGER NOT NULL, - UNIQUE(project_id, name) - ) - "); - - $pdo->exec(" - CREATE TABLE task_has_tags ( - task_id INTEGER NOT NULL, - tag_id INTEGER NOT NULL, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(tag_id) REFERENCES tags(id) ON DELETE CASCADE, - UNIQUE(tag_id, task_id) - ) - "); -} - -function version_89(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN avatar_path VARCHAR(255)"); -} - -function version_88(PDO $pdo) -{ - $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE settings ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE settings ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); -} - -function version_87(PDO $pdo) -{ - $pdo->exec("UPDATE project_activities SET event_name='task.file.create' WHERE event_name='file.create'"); -} - -function version_86(PDO $pdo) -{ - $pdo->exec('ALTER TABLE files RENAME TO task_has_files'); - - $pdo->exec(" - CREATE TABLE project_has_files ( - id SERIAL PRIMARY KEY, - project_id INTEGER NOT NULL, - name VARCHAR(255) NOT NULL, - path VARCHAR(255) NOT NULL, - is_image BOOLEAN DEFAULT '0', - size INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - date INTEGER DEFAULT 0 NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - )" - ); -} - -function version_85(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_active BOOLEAN DEFAULT '1'"); -} - -function version_84(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_external_links ( - id SERIAL PRIMARY KEY, - link_type VARCHAR(100) NOT NULL, - dependency VARCHAR(100) NOT NULL, - title VARCHAR(255) NOT NULL, - url VARCHAR(255) NOT NULL, - date_creation INT NOT NULL, - date_modification INT NOT NULL, - task_id INT NOT NULL, - creator_id INT DEFAULT 0, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ) - "); -} - -function version_83(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_default INTEGER DEFAULT 0"); - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_start INTEGER DEFAULT 0"); - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_end INTEGER DEFAULT 3"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN priority INTEGER DEFAULT 0"); -} - -function version_82(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN owner_id INTEGER DEFAULT 0"); -} - -function version_81(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE password_reset ( - token VARCHAR(80) PRIMARY KEY, - user_id INTEGER NOT NULL, - date_expiration INTEGER NOT NULL, - date_creation INTEGER NOT NULL, - ip VARCHAR(45) NOT NULL, - user_agent VARCHAR(255) NOT NULL, - is_active BOOLEAN NOT NULL, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) - "); - - $pdo->exec("INSERT INTO settings VALUES ('password_reset', '1')"); -} - -function version_80(PDO $pdo) -{ - $pdo->exec('ALTER TABLE "actions" ALTER COLUMN "action_name" TYPE VARCHAR(255)'); -} - -function version_79(PDO $pdo) -{ - $rq = $pdo->prepare('SELECT * FROM actions'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE actions SET action_name=? WHERE id=?'); - - foreach ($rows as $row) { - if ($row['action_name'] === 'TaskAssignCurrentUser' && $row['event_name'] === 'task.move.column') { - $row['action_name'] = '\Kanboard\Action\TaskAssignCurrentUserColumn'; - } elseif ($row['action_name'] === 'TaskClose' && $row['event_name'] === 'task.move.column') { - $row['action_name'] = '\Kanboard\Action\TaskCloseColumn'; - } elseif ($row['action_name'] === 'TaskLogMoveAnotherColumn') { - $row['action_name'] = '\Kanboard\Action\CommentCreationMoveTaskColumn'; - } elseif ($row['action_name']{0} !== '\\') { - $row['action_name'] = '\Kanboard\Action\\'.$row['action_name']; - } - - $rq->execute(array($row['action_name'], $row['id'])); - } -} - -function version_78(PDO $pdo) -{ - $pdo->exec('ALTER TABLE "users" ALTER COLUMN "language" TYPE VARCHAR(5)'); -} - -function version_77(PDO $pdo) -{ - $pdo->exec('ALTER TABLE "users" ADD COLUMN "role" VARCHAR(25) NOT NULL DEFAULT \''.Role::APP_USER.'\''); - - $rq = $pdo->prepare('SELECT * FROM "users"'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE "users" SET "role"=? WHERE "id"=?'); - - foreach ($rows as $row) { - $role = Role::APP_USER; - - if ($row['is_admin'] == 1) { - $role = Role::APP_ADMIN; - } else if ($row['is_project_admin']) { - $role = Role::APP_MANAGER; - } - - $rq->execute(array($role, $row['id'])); - } - - $pdo->exec('ALTER TABLE users DROP COLUMN "is_admin"'); - $pdo->exec('ALTER TABLE users DROP COLUMN "is_project_admin"'); -} - -function version_76(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_groups ( - group_id INTEGER NOT NULL, - project_id INTEGER NOT NULL, - role VARCHAR(25) NOT NULL, - FOREIGN KEY(group_id) REFERENCES groups(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(group_id, project_id) - ) - "); - - $pdo->exec("ALTER TABLE project_has_users ADD COLUMN role VARCHAR(25) NOT NULL DEFAULT '".Role::PROJECT_VIEWER."'"); - - $rq = $pdo->prepare('SELECT * FROM project_has_users'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE project_has_users SET "role"=? WHERE "id"=?'); - - foreach ($rows as $row) { - $rq->execute(array( - $row['is_owner'] == 1 ? Role::PROJECT_MANAGER : Role::PROJECT_MEMBER, - $row['id'], - )); - } - - $pdo->exec('ALTER TABLE project_has_users DROP COLUMN "is_owner"'); - $pdo->exec('ALTER TABLE project_has_users DROP COLUMN "id"'); -} - -function version_75(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE groups ( - id SERIAL PRIMARY KEY, - external_id VARCHAR(255) DEFAULT '', - name VARCHAR(100) NOT NULL UNIQUE - ) - "); - - $pdo->exec(" - CREATE TABLE group_has_users ( - group_id INTEGER NOT NULL, - user_id INTEGER NOT NULL, - FOREIGN KEY(group_id) REFERENCES groups(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(group_id, user_id) - ) - "); -} - -function version_74(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects DROP CONSTRAINT IF EXISTS projects_name_key'); -} - -function version_73(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE user_has_metadata ( - user_id INTEGER NOT NULL, - name VARCHAR(50) NOT NULL, - value VARCHAR(255) DEFAULT '', - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(user_id, name) - ) - "); - - $pdo->exec(" - CREATE TABLE project_has_metadata ( - project_id INTEGER NOT NULL, - name VARCHAR(50) NOT NULL, - value VARCHAR(255) DEFAULT '', - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, name) - ) - "); - - $pdo->exec(" - CREATE TABLE task_has_metadata ( - task_id INTEGER NOT NULL, - name VARCHAR(50) NOT NULL, - value VARCHAR(255) DEFAULT '', - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - UNIQUE(task_id, name) - ) - "); - - $pdo->exec("DROP TABLE project_integrations"); - - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_server'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_domain'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_username'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_password'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_nickname'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_room'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_api_url'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_id'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_token'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_url'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_channel'"); -} - -function version_72(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_notification_types ( - id SERIAL PRIMARY KEY, - project_id INTEGER NOT NULL, - notification_type VARCHAR(50) NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, notification_type) - ) - "); -} - -function version_71(PDO $pdo) -{ - $pdo->exec("ALTER TABLE custom_filters ADD COLUMN \"append\" BOOLEAN DEFAULT '0'"); -} - -function version_70(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ALTER COLUMN date_due TYPE BIGINT"); - $pdo->exec("ALTER TABLE tasks ALTER COLUMN date_creation TYPE BIGINT"); - $pdo->exec("ALTER TABLE tasks ALTER COLUMN date_completed TYPE BIGINT"); - $pdo->exec("ALTER TABLE tasks ALTER COLUMN date_started TYPE BIGINT"); - $pdo->exec("ALTER TABLE tasks ALTER COLUMN date_moved TYPE BIGINT"); - $pdo->exec("ALTER TABLE comments ALTER COLUMN date_creation TYPE BIGINT"); - $pdo->exec("ALTER TABLE last_logins ALTER COLUMN date_creation TYPE BIGINT"); - $pdo->exec("ALTER TABLE project_activities ALTER COLUMN date_creation TYPE BIGINT"); - $pdo->exec("ALTER TABLE projects ALTER COLUMN last_modified TYPE BIGINT"); - $pdo->exec("ALTER TABLE remember_me ALTER COLUMN date_creation TYPE BIGINT"); - $pdo->exec('ALTER TABLE files ALTER COLUMN "date" TYPE BIGINT'); - $pdo->exec('ALTER TABLE transitions ALTER COLUMN "date" TYPE BIGINT'); - $pdo->exec('ALTER TABLE subtask_time_tracking ALTER COLUMN "start" TYPE BIGINT'); - $pdo->exec('ALTER TABLE subtask_time_tracking ALTER COLUMN "end" TYPE BIGINT'); - $pdo->exec('ALTER TABLE users ALTER COLUMN "lock_expiration_date" TYPE BIGINT'); -} - -function version_69(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE user_has_unread_notifications ( - id SERIAL PRIMARY KEY, - user_id INTEGER NOT NULL, - date_creation BIGINT NOT NULL, - event_name VARCHAR(50) NOT NULL, - event_data TEXT NOT NULL, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) - "); - - $pdo->exec(" - CREATE TABLE user_has_notification_types ( - id SERIAL PRIMARY KEY, - user_id INTEGER NOT NULL, - notification_type VARCHAR(50), - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('CREATE UNIQUE INDEX user_has_notification_types_user_idx ON user_has_notification_types(user_id, notification_type)'); - - // Migrate people who have notification enabled before - $rq = $pdo->prepare("SELECT id FROM users WHERE notifications_enabled='1'"); - $rq->execute(); - $user_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0); - - foreach ($user_ids as $user_id) { - $rq = $pdo->prepare('INSERT INTO user_has_notification_types (user_id, notification_type) VALUES (?, ?)'); - $rq->execute(array($user_id, 'email')); - } -} - -function version_68(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE custom_filters ( - id SERIAL PRIMARY KEY, - filter VARCHAR(100) NOT NULL, - project_id INTEGER NOT NULL, - user_id INTEGER NOT NULL, - name VARCHAR(100) NOT NULL, - is_shared BOOLEAN DEFAULT '0' - ) - "); -} - -function version_67(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE plugin_schema_versions ( - plugin VARCHAR(80) NOT NULL PRIMARY KEY, - version INTEGER NOT NULL DEFAULT 0 - ) - "); -} - -function version_66(PDO $pdo) -{ - $pdo->exec("ALTER TABLE swimlanes ADD COLUMN description TEXT"); -} - -function version_65(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN gitlab_id INTEGER"); -} - -function version_64(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN start_date VARCHAR(10) DEFAULT ''"); - $pdo->exec("ALTER TABLE projects ADD COLUMN end_date VARCHAR(10) DEFAULT ''"); -} - -function version_63(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_project_admin BOOLEAN DEFAULT '0'"); -} - -function version_62(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN nb_failed_login INTEGER DEFAULT 0"); - $pdo->exec("ALTER TABLE users ADD COLUMN lock_expiration_date INTEGER DEFAULT 0"); -} - -function version_61(PDO $pdo) -{ - $pdo->exec("INSERT INTO settings VALUES ('subtask_time_tracking', '1')"); - $pdo->exec("INSERT INTO settings VALUES ('cfd_include_closed_tasks', '1')"); -} - -function version_60(PDO $pdo) -{ - $pdo->exec("INSERT INTO settings VALUES ('default_color', 'yellow')"); -} - -function version_59(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_daily_stats ( - id SERIAL PRIMARY KEY, - day CHAR(10) NOT NULL, - project_id INTEGER NOT NULL, - avg_lead_time INTEGER NOT NULL DEFAULT 0, - avg_cycle_time INTEGER NOT NULL DEFAULT 0, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('CREATE UNIQUE INDEX project_daily_stats_idx ON project_daily_stats(day, project_id)'); - - $pdo->exec('ALTER TABLE project_daily_summaries RENAME TO project_daily_column_stats'); -} - -function version_58(PDO $pdo) -{ - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN slack_webhook_channel VARCHAR(255) DEFAULT ''"); - $pdo->exec("INSERT INTO settings VALUES ('integration_slack_webhook_channel', '')"); -} - -function version_57(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users DROP COLUMN "default_project_id"'); -} - -function version_56(PDO $pdo) -{ - $pdo->exec('DELETE FROM "settings" WHERE "option"=\'subtask_time_tracking\''); -} - -function version_55(PDO $pdo) -{ - $pdo->exec('ALTER TABLE comments DROP CONSTRAINT IF EXISTS comments_user_id_fkey'); - $pdo->exec("ALTER TABLE comments ALTER COLUMN task_id SET NOT NULL"); - $pdo->exec("ALTER TABLE comments ALTER COLUMN user_id SET DEFAULT 0"); - $pdo->exec('ALTER TABLE comments RENAME COLUMN "date" TO "date_creation"'); - $pdo->exec("ALTER TABLE comments ALTER COLUMN date_creation SET NOT NULL"); -} - -function version_54(PDO $pdo) -{ - $pdo->exec("ALTER TABLE project_has_categories ALTER COLUMN project_id SET NOT NULL"); - $pdo->exec("ALTER TABLE project_has_categories ALTER COLUMN name SET NOT NULL"); - - $pdo->exec("ALTER TABLE actions ALTER COLUMN project_id SET NOT NULL"); - $pdo->exec("ALTER TABLE actions ALTER COLUMN event_name SET NOT NULL"); - $pdo->exec("ALTER TABLE actions ALTER COLUMN action_name SET NOT NULL"); - - $pdo->exec("ALTER TABLE action_has_params ALTER COLUMN action_id SET NOT NULL"); - $pdo->exec("ALTER TABLE action_has_params ALTER COLUMN name SET NOT NULL"); - $pdo->exec("ALTER TABLE action_has_params ALTER COLUMN value SET NOT NULL"); - - $pdo->exec("ALTER TABLE files ALTER COLUMN name SET NOT NULL"); - $pdo->exec("ALTER TABLE files ALTER COLUMN task_id SET NOT NULL"); - - $pdo->exec("ALTER TABLE subtasks ALTER COLUMN title SET NOT NULL"); - - $pdo->exec("ALTER TABLE tasks ALTER COLUMN title SET NOT NULL"); - $pdo->exec("ALTER TABLE tasks ALTER COLUMN project_id SET NOT NULL"); - $pdo->exec("ALTER TABLE tasks ALTER COLUMN column_id SET NOT NULL"); - - $pdo->exec("ALTER TABLE columns ALTER COLUMN title SET NOT NULL"); - $pdo->exec("ALTER TABLE columns ALTER COLUMN project_id SET NOT NULL"); - - $pdo->exec("ALTER TABLE project_has_users ALTER COLUMN project_id SET NOT NULL"); - $pdo->exec("ALTER TABLE project_has_users ALTER COLUMN user_id SET NOT NULL"); - - $pdo->exec("ALTER TABLE projects ALTER COLUMN name SET NOT NULL"); - - $pdo->exec("ALTER TABLE users ALTER COLUMN username SET NOT NULL"); - - $pdo->exec("ALTER TABLE user_has_notifications ALTER COLUMN user_id SET NOT NULL"); - $pdo->exec("ALTER TABLE user_has_notifications ALTER COLUMN user_id SET NOT NULL"); -} - -function version_53(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN notifications_filter INTEGER DEFAULT 4"); -} - -function version_52(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('webhook_url', '')); - - $pdo->exec("DELETE FROM settings WHERE option='webhook_url_task_creation'"); - $pdo->exec("DELETE FROM settings WHERE option='webhook_url_task_modification'"); -} - -function version_51(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN token VARCHAR(255) DEFAULT ''"); -} - -function version_50(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('calendar_user_subtasks_time_tracking', 0)); - $rq->execute(array('calendar_user_tasks', 'date_started')); - $rq->execute(array('calendar_project_tasks', 'date_started')); - - $pdo->exec("DELETE FROM settings WHERE option='subtask_forecast'"); -} - -function version_49(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_jabber', '0')); - $rq->execute(array('integration_jabber_server', '')); - $rq->execute(array('integration_jabber_domain', '')); - $rq->execute(array('integration_jabber_username', '')); - $rq->execute(array('integration_jabber_password', '')); - $rq->execute(array('integration_jabber_nickname', 'kanboard')); - $rq->execute(array('integration_jabber_room', '')); - - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber INTEGER DEFAULT '0'"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_server VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_domain VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_username VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_password VARCHAR(255) DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_nickname VARCHAR(255) DEFAULT 'kanboard'"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_room VARCHAR(255) DEFAULT ''"); -} - -function version_48(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_status INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_trigger INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_factor INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_timeframe INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_basedate INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_parent INTEGER'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_child INTEGER'); -} - -function version_47(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN identifier VARCHAR(50) DEFAULT ''"); -} - -function version_46(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_integrations ( - id SERIAL PRIMARY KEY, - project_id INTEGER NOT NULL UNIQUE, - hipchat BOOLEAN DEFAULT '0', - hipchat_api_url VARCHAR(255) DEFAULT 'https://api.hipchat.com', - hipchat_room_id VARCHAR(255), - hipchat_room_token VARCHAR(255), - slack BOOLEAN DEFAULT '0', - slack_webhook_url VARCHAR(255), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) - "); -} - -function version_45(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_daily_summaries ADD COLUMN score INTEGER NOT NULL DEFAULT 0'); -} - -function version_44(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_has_categories ADD COLUMN description TEXT'); -} - -function version_43(PDO $pdo) -{ - $pdo->exec('ALTER TABLE files ADD COLUMN "date" INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE files ADD COLUMN "user_id" INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE files ADD COLUMN "size" INTEGER NOT NULL DEFAULT 0'); -} - -function version_42(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN twofactor_activated BOOLEAN DEFAULT \'0\''); - $pdo->exec('ALTER TABLE users ADD COLUMN twofactor_secret CHAR(16)'); -} - -function version_41(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_gravatar', '0')); -} - -function version_40(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_hipchat', '0')); - $rq->execute(array('integration_hipchat_api_url', 'https://api.hipchat.com')); - $rq->execute(array('integration_hipchat_room_id', '')); - $rq->execute(array('integration_hipchat_room_token', '')); -} - -function version_39(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_slack_webhook', '0')); - $rq->execute(array('integration_slack_webhook_url', '')); -} - -function version_38(PDO $pdo) -{ - $pdo->exec('CREATE TABLE currencies ("currency" CHAR(3) NOT NULL UNIQUE, "rate" REAL DEFAULT 0)'); - - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_currency', 'USD')); -} - -function version_37(PDO $pdo) -{ - $pdo->exec('CREATE TABLE transitions ( - "id" SERIAL PRIMARY KEY, - "user_id" INTEGER NOT NULL, - "project_id" INTEGER NOT NULL, - "task_id" INTEGER NOT NULL, - "src_column_id" INTEGER NOT NULL, - "dst_column_id" INTEGER NOT NULL, - "date" INTEGER NOT NULL, - "time_spent" INTEGER DEFAULT 0, - FOREIGN KEY(src_column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(dst_column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - )'); - - $pdo->exec("CREATE INDEX transitions_task_index ON transitions(task_id)"); - $pdo->exec("CREATE INDEX transitions_project_index ON transitions(project_id)"); - $pdo->exec("CREATE INDEX transitions_user_index ON transitions(user_id)"); -} - -function version_36(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('subtask_forecast', '0')); -} - -function version_35(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_stylesheet', '')); -} - -function version_34(PDO $pdo) -{ - $pdo->exec("ALTER TABLE subtask_time_tracking ADD COLUMN time_spent REAL DEFAULT 0"); -} - -function version_30(PDO $pdo) -{ - $pdo->exec('ALTER TABLE subtasks ADD COLUMN position INTEGER DEFAULT 1'); - - $task_id = 0; - $position = 1; - $urq = $pdo->prepare('UPDATE subtasks SET position=? WHERE id=?'); - - $rq = $pdo->prepare('SELECT * FROM subtasks ORDER BY task_id, id ASC'); - $rq->execute(); - - foreach ($rq->fetchAll(PDO::FETCH_ASSOC) as $subtask) { - if ($task_id != $subtask['task_id']) { - $position = 1; - $task_id = $subtask['task_id']; - } - - $urq->execute(array($position, $subtask['id'])); - $position++; - } -} - -function version_29(PDO $pdo) -{ - $pdo->exec('ALTER TABLE task_has_files RENAME TO files'); - $pdo->exec('ALTER TABLE task_has_subtasks RENAME TO subtasks'); -} - -function version_28(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects ADD COLUMN description TEXT'); -} - -function version_27(PDO $pdo) -{ - $pdo->exec('CREATE TABLE links ( - "id" SERIAL PRIMARY KEY, - "label" VARCHAR(255) NOT NULL, - "opposite_id" INTEGER DEFAULT 0, - UNIQUE("label") - )'); - - $pdo->exec("CREATE TABLE task_has_links ( - id SERIAL PRIMARY KEY, - link_id INTEGER NOT NULL, - task_id INTEGER NOT NULL, - opposite_task_id INTEGER NOT NULL, - FOREIGN KEY(link_id) REFERENCES links(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(opposite_task_id) REFERENCES tasks(id) ON DELETE CASCADE - )"); - - $pdo->exec("CREATE INDEX task_has_links_task_index ON task_has_links(task_id)"); - $pdo->exec("CREATE UNIQUE INDEX task_has_links_unique ON task_has_links(link_id, task_id, opposite_task_id)"); - - $rq = $pdo->prepare('INSERT INTO links (label, opposite_id) VALUES (?, ?)'); - $rq->execute(array('relates to', 0)); - $rq->execute(array('blocks', 3)); - $rq->execute(array('is blocked by', 2)); - $rq->execute(array('duplicates', 5)); - $rq->execute(array('is duplicated by', 4)); - $rq->execute(array('is a child of', 7)); - $rq->execute(array('is a parent of', 6)); - $rq->execute(array('targets milestone', 9)); - $rq->execute(array('is a milestone of', 8)); - $rq->execute(array('fixes', 11)); - $rq->execute(array('is fixed by', 10)); -} - -function version_26(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ADD COLUMN date_moved INT DEFAULT 0'); - - /* Update tasks.date_moved from project_activities table if tasks.date_moved = null or 0. - * We take max project_activities.date_creation where event_name in task.create','task.move.column - * since creation date is always less than task moves - */ - $pdo->exec("UPDATE tasks - SET date_moved = ( - SELECT md - FROM ( - SELECT task_id, max(date_creation) md - FROM project_activities - WHERE event_name IN ('task.create', 'task.move.column') - GROUP BY task_id - ) src - WHERE id = src.task_id - ) - WHERE (date_moved IS NULL OR date_moved = 0) AND id IN ( - SELECT task_id - FROM ( - SELECT task_id, max(date_creation) md - FROM project_activities - WHERE event_name IN ('task.create', 'task.move.column') - GROUP BY task_id - ) src - )"); - - // If there is no activities for some tasks use the date_creation - $pdo->exec("UPDATE tasks SET date_moved = date_creation WHERE date_moved IS NULL OR date_moved = 0"); -} - -function version_25(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN disable_login_form BOOLEAN DEFAULT '0'"); -} - -function version_24(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('subtask_restriction', '0')); - $rq->execute(array('subtask_time_tracking', '0')); - - $pdo->exec(' - CREATE TABLE subtask_time_tracking ( - id SERIAL PRIMARY KEY, - "user_id" INTEGER NOT NULL, - "subtask_id" INTEGER NOT NULL, - "start" INTEGER DEFAULT 0, - "end" INTEGER DEFAULT 0, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(subtask_id) REFERENCES task_has_subtasks(id) ON DELETE CASCADE - ) - '); -} - -function version_23(PDO $pdo) -{ - $pdo->exec('ALTER TABLE columns ADD COLUMN description TEXT'); -} - -function version_22(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN timezone VARCHAR(50)'); - $pdo->exec('ALTER TABLE users ADD COLUMN language CHAR(5)'); -} - -function version_21(PDO $pdo) -{ - // Avoid some full table scans - $pdo->exec('CREATE INDEX users_admin_idx ON users(is_admin)'); - $pdo->exec('CREATE INDEX columns_project_idx ON columns(project_id)'); - $pdo->exec('CREATE INDEX tasks_project_idx ON tasks(project_id)'); - $pdo->exec('CREATE INDEX swimlanes_project_idx ON swimlanes(project_id)'); - $pdo->exec('CREATE INDEX categories_project_idx ON project_has_categories(project_id)'); - $pdo->exec('CREATE INDEX subtasks_task_idx ON task_has_subtasks(task_id)'); - $pdo->exec('CREATE INDEX files_task_idx ON task_has_files(task_id)'); - $pdo->exec('CREATE INDEX comments_task_idx ON comments(task_id)'); - - // Set the ownership for all private projects - $rq = $pdo->prepare("SELECT id FROM projects WHERE is_private='1'"); - $rq->execute(); - $project_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0); - - $rq = $pdo->prepare("UPDATE project_has_users SET is_owner='1' WHERE project_id=?"); - - foreach ($project_ids as $project_id) { - $rq->execute(array($project_id)); - } -} - -function version_20(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('project_categories', '')); -} - -function version_19(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE swimlanes ( - id SERIAL PRIMARY KEY, - name VARCHAR(200) NOT NULL, - position INTEGER DEFAULT 1, - is_active BOOLEAN DEFAULT '1', - project_id INTEGER, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE (name, project_id) - ) - "); - - $pdo->exec('ALTER TABLE tasks ADD COLUMN swimlane_id INTEGER DEFAULT 0'); - $pdo->exec("ALTER TABLE projects ADD COLUMN default_swimlane VARCHAR(200) DEFAULT 'Default swimlane'"); - $pdo->exec("ALTER TABLE projects ADD COLUMN show_default_swimlane BOOLEAN DEFAULT '1'"); -} - -function version_18(PDO $pdo) -{ - $pdo->exec("ALTER TABLE project_has_users ADD COLUMN is_owner BOOLEAN DEFAULT '0'"); -} - -function version_17(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ALTER COLUMN title SET NOT NULL'); -} - -function version_16(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_daily_summaries ( - id SERIAL PRIMARY KEY, - day CHAR(10) NOT NULL, - project_id INTEGER NOT NULL, - column_id INTEGER NOT NULL, - total INTEGER NOT NULL DEFAULT 0, - FOREIGN KEY(column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('CREATE UNIQUE INDEX project_daily_column_stats_idx ON project_daily_summaries(day, project_id, column_id)'); -} - -function version_15(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN is_everybody_allowed BOOLEAN DEFAULT '0'"); -} - -function version_14(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_activities ( - id SERIAL PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name VARCHAR(50) NOT NULL, - creator_id INTEGER, - project_id INTEGER, - task_id INTEGER, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('DROP TABLE task_has_events'); - $pdo->exec('DROP TABLE comment_has_events'); - $pdo->exec('DROP TABLE subtask_has_events'); -} - -function version_13(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN date_started INTEGER"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN time_spent FLOAT DEFAULT 0"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN time_estimated FLOAT DEFAULT 0"); - - $pdo->exec("ALTER TABLE task_has_subtasks ALTER COLUMN time_estimated TYPE FLOAT"); - $pdo->exec("ALTER TABLE task_has_subtasks ALTER COLUMN time_spent TYPE FLOAT"); -} - -function version_12(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN is_private BOOLEAN DEFAULT '0'"); -} - -function version_11(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_date_format', 'm/d/Y')); -} - -function version_10(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE settings ( - option VARCHAR(100) PRIMARY KEY, - value VARCHAR(255) DEFAULT '' - ) - "); - - // Migrate old config parameters - $rq = $pdo->prepare('SELECT * FROM config'); - $rq->execute(); - $parameters = $rq->fetch(PDO::FETCH_ASSOC); - - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('board_highlight_period', defined('RECENT_TASK_PERIOD') ? RECENT_TASK_PERIOD : 48*60*60)); - $rq->execute(array('board_public_refresh_interval', defined('BOARD_PUBLIC_CHECK_INTERVAL') ? BOARD_PUBLIC_CHECK_INTERVAL : 60)); - $rq->execute(array('board_private_refresh_interval', defined('BOARD_CHECK_INTERVAL') ? BOARD_CHECK_INTERVAL : 10)); - $rq->execute(array('board_columns', $parameters['default_columns'])); - $rq->execute(array('webhook_url_task_creation', $parameters['webhooks_url_task_creation'])); - $rq->execute(array('webhook_url_task_modification', $parameters['webhooks_url_task_modification'])); - $rq->execute(array('webhook_token', $parameters['webhooks_token'])); - $rq->execute(array('api_token', $parameters['api_token'])); - $rq->execute(array('application_language', $parameters['language'])); - $rq->execute(array('application_timezone', $parameters['timezone'])); - $rq->execute(array('application_url', defined('KANBOARD_URL') ? KANBOARD_URL : '')); - - $pdo->exec('DROP TABLE config'); -} - -function version_9(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN reference VARCHAR(50) DEFAULT ''"); - $pdo->exec("ALTER TABLE comments ADD COLUMN reference VARCHAR(50) DEFAULT ''"); - - $pdo->exec('CREATE INDEX tasks_reference_idx ON tasks(reference)'); - $pdo->exec('CREATE INDEX comments_reference_idx ON comments(reference)'); -} - -function version_8(PDO $pdo) -{ - $pdo->exec('CREATE UNIQUE INDEX users_username_idx ON users(username)'); -} - -function version_7(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN default_columns VARCHAR(255) DEFAULT ''"); -} - -function version_6(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_events ( - id SERIAL PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name VARCHAR(50) NOT NULL, - creator_id INTEGER, - project_id INTEGER, - task_id INTEGER, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - "); - - $pdo->exec(" - CREATE TABLE subtask_has_events ( - id SERIAL PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name VARCHAR(50) NOT NULL, - creator_id INTEGER, - project_id INTEGER, - subtask_id INTEGER, - task_id INTEGER, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(subtask_id) REFERENCES task_has_subtasks(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - "); - - $pdo->exec(" - CREATE TABLE comment_has_events ( - id SERIAL PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name VARCHAR(50) NOT NULL, - creator_id INTEGER, - project_id INTEGER, - comment_id INTEGER, - task_id INTEGER, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(comment_id) REFERENCES comments(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - "); -} - -function version_5(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN is_public BOOLEAN DEFAULT '0'"); -} - -function version_4(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN notifications_enabled BOOLEAN DEFAULT '0'"); - - $pdo->exec(" - CREATE TABLE user_has_notifications ( - user_id INTEGER, - project_id INTEGER, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, user_id) - ); - "); -} - -function version_3(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_modification VARCHAR(255)"); - $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_creation VARCHAR(255)"); -} - -function version_2(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN creator_id INTEGER DEFAULT 0"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN date_modification INTEGER DEFAULT 0"); -} - -function version_1(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE config ( - language CHAR(5) DEFAULT 'en_US', - webhooks_token VARCHAR(255) DEFAULT '', - timezone VARCHAR(50) DEFAULT 'UTC', - api_token VARCHAR(255) DEFAULT '' - ); - - CREATE TABLE users ( - id SERIAL PRIMARY KEY, - username VARCHAR(50), - password VARCHAR(255), - is_admin BOOLEAN DEFAULT '0', - default_project_id INTEGER DEFAULT 0, - is_ldap_user BOOLEAN DEFAULT '0', - name VARCHAR(255), - email VARCHAR(255), - google_id VARCHAR(255), - github_id VARCHAR(30) - ); - - CREATE TABLE remember_me ( - id SERIAL PRIMARY KEY, - user_id INTEGER, - ip VARCHAR(45), - user_agent VARCHAR(255), - token VARCHAR(255), - sequence VARCHAR(255), - expiration INTEGER, - date_creation INTEGER, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ); - - CREATE TABLE last_logins ( - id SERIAL PRIMARY KEY, - auth_type VARCHAR(25), - user_id INTEGER, - ip VARCHAR(45), - user_agent VARCHAR(255), - date_creation INTEGER, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ); - - CREATE TABLE projects ( - id SERIAL PRIMARY KEY, - name VARCHAR(255) UNIQUE, - is_active BOOLEAN DEFAULT '1', - token VARCHAR(255), - last_modified INTEGER DEFAULT 0 - ); - - CREATE TABLE project_has_users ( - id SERIAL PRIMARY KEY, - project_id INTEGER, - user_id INTEGER, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(project_id, user_id) - ); - - CREATE TABLE project_has_categories ( - id SERIAL PRIMARY KEY, - name VARCHAR(255), - project_id INTEGER, - UNIQUE (project_id, name), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ); - - CREATE TABLE columns ( - id SERIAL PRIMARY KEY, - title VARCHAR(255), - position INTEGER, - project_id INTEGER, - task_limit INTEGER DEFAULT 0, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE (title, project_id) - ); - - CREATE TABLE tasks ( - id SERIAL PRIMARY KEY, - title VARCHAR(255), - description TEXT, - date_creation INTEGER, - color_id VARCHAR(255), - project_id INTEGER, - column_id INTEGER, - owner_id INTEGER DEFAULT 0, - position INTEGER, - is_active BOOLEAN DEFAULT '1', - date_completed INTEGER, - score INTEGER, - date_due INTEGER, - category_id INTEGER DEFAULT 0, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(column_id) REFERENCES columns(id) ON DELETE CASCADE - ); - - CREATE TABLE task_has_subtasks ( - id SERIAL PRIMARY KEY, - title VARCHAR(255), - status SMALLINT DEFAULT 0, - time_estimated INTEGER DEFAULT 0, - time_spent INTEGER DEFAULT 0, - task_id INTEGER NOT NULL, - user_id INTEGER, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - - CREATE TABLE task_has_files ( - id SERIAL PRIMARY KEY, - name VARCHAR(255), - path VARCHAR(255), - is_image BOOLEAN DEFAULT '0', - task_id INTEGER, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - - CREATE TABLE comments ( - id SERIAL PRIMARY KEY, - task_id INTEGER, - user_id INTEGER, - date INTEGER, - comment TEXT, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ); - - CREATE TABLE actions ( - id SERIAL PRIMARY KEY, - project_id INTEGER, - event_name VARCHAR(50), - action_name VARCHAR(50), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ); - - CREATE TABLE action_has_params ( - id SERIAL PRIMARY KEY, - action_id INTEGER, - name VARCHAR(50), - value VARCHAR(50), - FOREIGN KEY(action_id) REFERENCES actions(id) ON DELETE CASCADE - ); - "); - - $pdo->exec(" - INSERT INTO users - (username, password, is_admin) - VALUES ('admin', '".\password_hash('admin', PASSWORD_BCRYPT)."', '1') - "); - - $pdo->exec(" - INSERT INTO config - (webhooks_token, api_token) - VALUES ('".Token::getToken()."', '".Token::getToken()."') - "); -} diff --git a/sources/app/Schema/Sql/mysql.sql b/sources/app/Schema/Sql/mysql.sql deleted file mode 100644 index 9583989..0000000 --- a/sources/app/Schema/Sql/mysql.sql +++ /dev/null @@ -1,702 +0,0 @@ - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS `action_has_params`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `action_has_params` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `action_id` int(11) NOT NULL, - `name` varchar(50) NOT NULL, - `value` varchar(50) NOT NULL, - PRIMARY KEY (`id`), - KEY `action_id` (`action_id`), - CONSTRAINT `action_has_params_ibfk_1` FOREIGN KEY (`action_id`) REFERENCES `actions` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `actions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `actions` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `project_id` int(11) NOT NULL, - `event_name` varchar(50) NOT NULL, - `action_name` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `project_id` (`project_id`), - 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 `columns`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `columns` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `title` varchar(255) NOT NULL, - `position` int(11) NOT NULL, - `project_id` int(11) NOT NULL, - `task_limit` int(11) DEFAULT '0', - `description` text, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_title_project` (`title`,`project_id`), - KEY `columns_project_idx` (`project_id`), - CONSTRAINT `columns_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 `comments`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `comments` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `task_id` int(11) NOT NULL, - `user_id` int(11) DEFAULT '0', - `date_creation` bigint(20) DEFAULT NULL, - `comment` text, - `reference` varchar(50) DEFAULT '', - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`), - KEY `comments_reference_idx` (`reference`), - KEY `comments_task_idx` (`task_id`), - CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `currencies`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `currencies` ( - `currency` char(3) NOT NULL, - `rate` float DEFAULT '0', - UNIQUE KEY `currency` (`currency`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `custom_filters`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `custom_filters` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `filter` varchar(100) NOT NULL, - `project_id` int(11) NOT NULL, - `user_id` int(11) NOT NULL, - `name` varchar(100) NOT NULL, - `is_shared` tinyint(1) DEFAULT '0', - `append` tinyint(1) DEFAULT '0', - PRIMARY KEY (`id`), - KEY `project_id` (`project_id`), - KEY `user_id` (`user_id`), - CONSTRAINT `custom_filters_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE, - CONSTRAINT `custom_filters_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 `group_has_users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `group_has_users` ( - `group_id` int(11) NOT NULL, - `user_id` int(11) NOT NULL, - UNIQUE KEY `group_id` (`group_id`,`user_id`), - KEY `user_id` (`user_id`), - CONSTRAINT `group_has_users_ibfk_1` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`) ON DELETE CASCADE, - CONSTRAINT `group_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 `groups`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `groups` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `external_id` varchar(255) DEFAULT '', - `name` varchar(100) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) 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 */; -CREATE TABLE `last_logins` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `auth_type` varchar(25) DEFAULT NULL, - `user_id` int(11) DEFAULT NULL, - `ip` varchar(45) DEFAULT NULL, - `user_agent` varchar(255) DEFAULT NULL, - `date_creation` bigint(20) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`), - CONSTRAINT `last_logins_ibfk_1` 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 `links`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `links` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `label` varchar(255) NOT NULL, - `opposite_id` int(11) DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `label` (`label`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `password_reset`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `password_reset` ( - `token` varchar(80) NOT NULL, - `user_id` int(11) NOT NULL, - `date_expiration` int(11) NOT NULL, - `date_creation` int(11) NOT NULL, - `ip` varchar(45) NOT NULL, - `user_agent` varchar(255) NOT NULL, - `is_active` tinyint(1) NOT NULL, - PRIMARY KEY (`token`), - KEY `user_id` (`user_id`), - CONSTRAINT `password_reset_ibfk_1` 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 `plugin_schema_versions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `plugin_schema_versions` ( - `plugin` varchar(80) NOT NULL, - `version` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`plugin`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `project_activities`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_activities` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `date_creation` bigint(20) DEFAULT NULL, - `event_name` varchar(50) NOT NULL, - `creator_id` int(11) DEFAULT NULL, - `project_id` int(11) DEFAULT NULL, - `task_id` int(11) DEFAULT NULL, - `data` text, - PRIMARY KEY (`id`), - KEY `creator_id` (`creator_id`), - KEY `project_id` (`project_id`), - KEY `task_id` (`task_id`), - CONSTRAINT `project_activities_ibfk_1` FOREIGN KEY (`creator_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, - CONSTRAINT `project_activities_ibfk_2` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE, - CONSTRAINT `project_activities_ibfk_3` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `project_daily_column_stats`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_daily_column_stats` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `day` char(10) NOT NULL, - `project_id` int(11) NOT NULL, - `column_id` int(11) NOT NULL, - `total` int(11) NOT NULL DEFAULT '0', - `score` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `project_daily_column_stats_idx` (`day`,`project_id`,`column_id`), - KEY `column_id` (`column_id`), - KEY `project_id` (`project_id`), - CONSTRAINT `project_daily_column_stats_ibfk_1` FOREIGN KEY (`column_id`) REFERENCES `columns` (`id`) ON DELETE CASCADE, - CONSTRAINT `project_daily_column_stats_ibfk_2` 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_daily_stats`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_daily_stats` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `day` char(10) NOT NULL, - `project_id` int(11) NOT NULL, - `avg_lead_time` int(11) NOT NULL DEFAULT '0', - `avg_cycle_time` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `project_daily_stats_idx` (`day`,`project_id`), - KEY `project_id` (`project_id`), - CONSTRAINT `project_daily_stats_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_categories`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_has_categories` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `project_id` int(11) NOT NULL, - `description` text, - PRIMARY KEY (`id`), - UNIQUE KEY `idx_project_category` (`project_id`,`name`), - KEY `categories_project_idx` (`project_id`), - CONSTRAINT `project_has_categories_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_files`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_has_files` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `project_id` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `path` varchar(255) NOT NULL, - `is_image` tinyint(1) DEFAULT '0', - `size` int(11) NOT NULL DEFAULT '0', - `user_id` int(11) NOT NULL DEFAULT '0', - `date` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `project_id` (`project_id`), - CONSTRAINT `project_has_files_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_groups`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_has_groups` ( - `group_id` int(11) NOT NULL, - `project_id` int(11) NOT NULL, - `role` varchar(25) 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, - CONSTRAINT `project_has_groups_ibfk_2` 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_metadata`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_has_metadata` ( - `project_id` int(11) NOT NULL, - `name` varchar(50) NOT NULL, - `value` varchar(255) DEFAULT '', - `changed_by` int(11) NOT NULL DEFAULT '0', - `changed_on` int(11) NOT NULL DEFAULT '0', - UNIQUE KEY `project_id` (`project_id`,`name`), - CONSTRAINT `project_has_metadata_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_notification_types`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `project_has_notification_types` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `project_id` int(11) NOT NULL, - `notification_type` varchar(50) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `project_id` (`project_id`,`notification_type`), - 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_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', - 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 `projects`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `projects` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `is_active` tinyint(4) DEFAULT '1', - `token` varchar(255) DEFAULT NULL, - `last_modified` bigint(20) DEFAULT NULL, - `is_public` tinyint(1) DEFAULT '0', - `is_private` tinyint(1) DEFAULT '0', - `is_everybody_allowed` tinyint(1) DEFAULT '0', - `default_swimlane` varchar(200) DEFAULT 'Default swimlane', - `show_default_swimlane` int(11) DEFAULT '1', - `description` text, - `identifier` varchar(50) DEFAULT '', - `start_date` varchar(10) DEFAULT '', - `end_date` varchar(10) DEFAULT '', - `owner_id` int(11) DEFAULT '0', - `priority_default` int(11) DEFAULT '0', - `priority_start` int(11) DEFAULT '0', - `priority_end` int(11) DEFAULT '3', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `remember_me`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `remember_me` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) DEFAULT NULL, - `ip` varchar(45) DEFAULT NULL, - `user_agent` varchar(255) DEFAULT NULL, - `token` varchar(255) DEFAULT NULL, - `sequence` varchar(255) DEFAULT NULL, - `expiration` int(11) DEFAULT NULL, - `date_creation` bigint(20) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`), - CONSTRAINT `remember_me_ibfk_1` 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 `schema_version`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `schema_version` ( - `version` int(11) DEFAULT '0' -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `settings`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `settings` ( - `option` varchar(100) NOT NULL, - `value` varchar(255) DEFAULT '', - `changed_by` int(11) NOT NULL DEFAULT '0', - `changed_on` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`option`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `subtask_time_tracking`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `subtask_time_tracking` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) NOT NULL, - `subtask_id` int(11) NOT NULL, - `start` bigint(20) DEFAULT NULL, - `end` bigint(20) DEFAULT NULL, - `time_spent` float DEFAULT '0', - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`), - KEY `subtask_id` (`subtask_id`), - CONSTRAINT `subtask_time_tracking_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, - CONSTRAINT `subtask_time_tracking_ibfk_2` FOREIGN KEY (`subtask_id`) REFERENCES `subtasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `subtasks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `subtasks` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `title` varchar(255) NOT NULL, - `status` int(11) DEFAULT '0', - `time_estimated` float DEFAULT NULL, - `time_spent` float DEFAULT NULL, - `task_id` int(11) NOT NULL, - `user_id` int(11) DEFAULT NULL, - `position` int(11) DEFAULT '1', - PRIMARY KEY (`id`), - KEY `subtasks_task_idx` (`task_id`), - CONSTRAINT `subtasks_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `swimlanes`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `swimlanes` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(200) NOT NULL, - `position` int(11) DEFAULT '1', - `is_active` int(11) DEFAULT '1', - `project_id` int(11) DEFAULT NULL, - `description` text, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`,`project_id`), - KEY `swimlanes_project_idx` (`project_id`), - CONSTRAINT `swimlanes_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 `tags`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tags` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `project_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `project_id` (`project_id`,`name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `task_has_external_links`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `task_has_external_links` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `link_type` varchar(100) NOT NULL, - `dependency` varchar(100) NOT NULL, - `title` varchar(255) NOT NULL, - `url` varchar(255) NOT NULL, - `date_creation` int(11) NOT NULL, - `date_modification` int(11) NOT NULL, - `task_id` int(11) NOT NULL, - `creator_id` int(11) DEFAULT '0', - PRIMARY KEY (`id`), - KEY `task_id` (`task_id`), - CONSTRAINT `task_has_external_links_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `task_has_files`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `task_has_files` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `path` varchar(255) DEFAULT NULL, - `is_image` tinyint(1) DEFAULT '0', - `task_id` int(11) NOT NULL, - `date` bigint(20) DEFAULT NULL, - `user_id` int(11) NOT NULL DEFAULT '0', - `size` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `files_task_idx` (`task_id`), - CONSTRAINT `task_has_files_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `task_has_links`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `task_has_links` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `link_id` int(11) NOT NULL, - `task_id` int(11) NOT NULL, - `opposite_task_id` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `task_has_links_unique` (`link_id`,`task_id`,`opposite_task_id`), - KEY `opposite_task_id` (`opposite_task_id`), - KEY `task_has_links_task_index` (`task_id`), - CONSTRAINT `task_has_links_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `links` (`id`) ON DELETE CASCADE, - CONSTRAINT `task_has_links_ibfk_2` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE, - CONSTRAINT `task_has_links_ibfk_3` FOREIGN KEY (`opposite_task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `task_has_metadata`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `task_has_metadata` ( - `task_id` int(11) NOT NULL, - `name` varchar(50) NOT NULL, - `value` varchar(255) DEFAULT '', - `changed_by` int(11) NOT NULL DEFAULT '0', - `changed_on` int(11) NOT NULL DEFAULT '0', - UNIQUE KEY `task_id` (`task_id`,`name`), - CONSTRAINT `task_has_metadata_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `task_has_tags`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `task_has_tags` ( - `task_id` int(11) NOT NULL, - `tag_id` int(11) NOT NULL, - UNIQUE KEY `tag_id` (`tag_id`,`task_id`), - KEY `task_id` (`task_id`), - CONSTRAINT `task_has_tags_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE, - CONSTRAINT `task_has_tags_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `tasks`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `tasks` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `title` varchar(255) NOT NULL, - `description` text, - `date_creation` bigint(20) DEFAULT NULL, - `date_completed` bigint(20) DEFAULT NULL, - `date_due` bigint(20) DEFAULT NULL, - `color_id` varchar(50) DEFAULT NULL, - `project_id` int(11) NOT NULL, - `column_id` int(11) NOT NULL, - `owner_id` int(11) DEFAULT '0', - `position` int(11) DEFAULT NULL, - `score` int(11) DEFAULT NULL, - `is_active` tinyint(4) DEFAULT '1', - `category_id` int(11) DEFAULT '0', - `creator_id` int(11) DEFAULT '0', - `date_modification` int(11) DEFAULT '0', - `reference` varchar(50) DEFAULT '', - `date_started` bigint(20) DEFAULT NULL, - `time_spent` float DEFAULT '0', - `time_estimated` float DEFAULT '0', - `swimlane_id` int(11) DEFAULT '0', - `date_moved` bigint(20) DEFAULT NULL, - `recurrence_status` int(11) NOT NULL DEFAULT '0', - `recurrence_trigger` int(11) NOT NULL DEFAULT '0', - `recurrence_factor` int(11) NOT NULL DEFAULT '0', - `recurrence_timeframe` int(11) NOT NULL DEFAULT '0', - `recurrence_basedate` int(11) NOT NULL DEFAULT '0', - `recurrence_parent` int(11) DEFAULT NULL, - `recurrence_child` int(11) DEFAULT NULL, - `priority` int(11) DEFAULT '0', - PRIMARY KEY (`id`), - KEY `idx_task_active` (`is_active`), - KEY `column_id` (`column_id`), - KEY `tasks_reference_idx` (`reference`), - KEY `tasks_project_idx` (`project_id`), - CONSTRAINT `tasks_ibfk_1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE, - CONSTRAINT `tasks_ibfk_2` 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 `transitions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `transitions` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) NOT NULL, - `project_id` int(11) NOT NULL, - `task_id` int(11) NOT NULL, - `src_column_id` int(11) NOT NULL, - `dst_column_id` int(11) NOT NULL, - `date` bigint(20) DEFAULT NULL, - `time_spent` int(11) DEFAULT '0', - PRIMARY KEY (`id`), - KEY `src_column_id` (`src_column_id`), - KEY `dst_column_id` (`dst_column_id`), - KEY `transitions_task_index` (`task_id`), - KEY `transitions_project_index` (`project_id`), - KEY `transitions_user_index` (`user_id`), - CONSTRAINT `transitions_ibfk_1` FOREIGN KEY (`src_column_id`) REFERENCES `columns` (`id`) ON DELETE CASCADE, - CONSTRAINT `transitions_ibfk_2` FOREIGN KEY (`dst_column_id`) REFERENCES `columns` (`id`) ON DELETE CASCADE, - CONSTRAINT `transitions_ibfk_3` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, - CONSTRAINT `transitions_ibfk_4` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE CASCADE, - CONSTRAINT `transitions_ibfk_5` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -DROP TABLE IF EXISTS `user_has_metadata`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_has_metadata` ( - `user_id` int(11) NOT NULL, - `name` varchar(50) NOT NULL, - `value` varchar(255) DEFAULT '', - `changed_by` int(11) NOT NULL DEFAULT '0', - `changed_on` int(11) NOT NULL DEFAULT '0', - UNIQUE KEY `user_id` (`user_id`,`name`), - CONSTRAINT `user_has_metadata_ibfk_1` 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 `user_has_notification_types`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_has_notification_types` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) NOT NULL, - `notification_type` varchar(50) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `user_has_notification_types_user_idx` (`user_id`,`notification_type`), - CONSTRAINT `user_has_notification_types_ibfk_1` 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 `user_has_notifications`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_has_notifications` ( - `user_id` int(11) NOT NULL, - `project_id` int(11) NOT NULL, - UNIQUE KEY `user_has_notifications_unique_idx` (`user_id`,`project_id`), - KEY `user_has_notifications_ibfk_2` (`project_id`), - CONSTRAINT `user_has_notifications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, - CONSTRAINT `user_has_notifications_ibfk_2` 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 `user_has_unread_notifications`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `user_has_unread_notifications` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) NOT NULL, - `date_creation` bigint(20) NOT NULL, - `event_name` varchar(50) NOT NULL, - `event_data` text NOT NULL, - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`), - CONSTRAINT `user_has_unread_notifications_ibfk_1` 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 `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `users` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `username` varchar(50) NOT NULL, - `password` varchar(255) DEFAULT NULL, - `is_ldap_user` tinyint(1) DEFAULT '0', - `name` varchar(255) DEFAULT NULL, - `email` varchar(255) DEFAULT NULL, - `google_id` varchar(30) DEFAULT NULL, - `github_id` varchar(30) DEFAULT NULL, - `notifications_enabled` tinyint(1) DEFAULT '0', - `timezone` varchar(50) DEFAULT NULL, - `language` varchar(5) DEFAULT NULL, - `disable_login_form` tinyint(1) DEFAULT '0', - `twofactor_activated` tinyint(1) DEFAULT '0', - `twofactor_secret` char(16) DEFAULT NULL, - `token` varchar(255) DEFAULT '', - `notifications_filter` int(11) DEFAULT '4', - `nb_failed_login` int(11) DEFAULT '0', - `lock_expiration_date` bigint(20) DEFAULT NULL, - `gitlab_id` int(11) DEFAULT NULL, - `role` varchar(25) NOT NULL DEFAULT 'app-user', - `is_active` tinyint(1) DEFAULT '1', - `avatar_path` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `users_username_idx` (`username`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - -LOCK TABLES `settings` WRITE; -/*!40000 ALTER TABLE `settings` DISABLE KEYS */; -INSERT INTO `settings` VALUES ('api_token','19ffd9709d03ce50675c3a43d1c49c1ac207f4bc45f06c5b2701fbdf8929',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','1d62395a742260738a406789366a84138ced50a1be62e8862c5cf8d0a561',0,0),('webhook_url','',0,0); -/*!40000 ALTER TABLE `settings` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - -LOCK TABLES `links` WRITE; -/*!40000 ALTER TABLE `links` DISABLE KEYS */; -INSERT INTO `links` VALUES (1,'relates to',0),(2,'blocks',3),(3,'is blocked by',2),(4,'duplicates',5),(5,'is duplicated by',4),(6,'is a child of',7),(7,'is a parent of',6),(8,'targets milestone',9),(9,'is a milestone of',8),(10,'fixes',11),(11,'is fixed by',10); -/*!40000 ALTER TABLE `links` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$Kv6fus67I/ZG/3LYJ7bRLeis8bk8455Lwtu12ElgnGm3lhRs/z7Ni', 'app-admin');INSERT INTO schema_version VALUES ('111'); diff --git a/sources/app/Schema/Sql/postgres.sql b/sources/app/Schema/Sql/postgres.sql deleted file mode 100644 index 9423905..0000000 --- a/sources/app/Schema/Sql/postgres.sql +++ /dev/null @@ -1,2315 +0,0 @@ --- --- PostgreSQL database dump --- - --- Dumped from database version 9.5.2 --- Dumped by pg_dump version 9.5.2 - -SET statement_timeout = 0; -SET lock_timeout = 0; -SET client_encoding = 'UTF8'; -SET standard_conforming_strings = on; -SET check_function_bodies = false; -SET client_min_messages = warning; -SET row_security = off; - --- --- Name: SCHEMA "public"; Type: COMMENT; Schema: -; Owner: - --- - -COMMENT ON SCHEMA "public" IS 'standard public schema'; - - -SET search_path = "public", pg_catalog; - -SET default_tablespace = ''; - -SET default_with_oids = false; - --- --- Name: action_has_params; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "action_has_params" ( - "id" integer NOT NULL, - "action_id" integer NOT NULL, - "name" character varying(50) NOT NULL, - "value" character varying(50) NOT NULL -); - - --- --- Name: action_has_params_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "action_has_params_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: action_has_params_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "action_has_params_id_seq" OWNED BY "action_has_params"."id"; - - --- --- Name: actions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "actions" ( - "id" integer NOT NULL, - "project_id" integer NOT NULL, - "event_name" character varying(50) NOT NULL, - "action_name" character varying(255) NOT NULL -); - - --- --- Name: actions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "actions_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: actions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "actions_id_seq" OWNED BY "actions"."id"; - - --- --- Name: columns; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "columns" ( - "id" integer NOT NULL, - "title" character varying(255) NOT NULL, - "position" integer, - "project_id" integer NOT NULL, - "task_limit" integer DEFAULT 0, - "description" "text" -); - - --- --- Name: columns_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "columns_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: columns_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "columns_id_seq" OWNED BY "columns"."id"; - - --- --- Name: comments; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "comments" ( - "id" integer NOT NULL, - "task_id" integer NOT NULL, - "user_id" integer DEFAULT 0, - "date_creation" bigint NOT NULL, - "comment" "text", - "reference" character varying(50) DEFAULT ''::character varying -); - - --- --- Name: comments_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "comments_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: comments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "comments_id_seq" OWNED BY "comments"."id"; - - --- --- Name: currencies; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "currencies" ( - "currency" character(3) NOT NULL, - "rate" real DEFAULT 0 -); - - --- --- Name: custom_filters; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "custom_filters" ( - "id" integer NOT NULL, - "filter" character varying(100) NOT NULL, - "project_id" integer NOT NULL, - "user_id" integer NOT NULL, - "name" character varying(100) NOT NULL, - "is_shared" boolean DEFAULT false, - "append" boolean DEFAULT false -); - - --- --- Name: custom_filters_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "custom_filters_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: custom_filters_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "custom_filters_id_seq" OWNED BY "custom_filters"."id"; - - --- --- Name: group_has_users; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "group_has_users" ( - "group_id" integer NOT NULL, - "user_id" integer NOT NULL -); - - --- --- Name: groups; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "groups" ( - "id" integer NOT NULL, - "external_id" character varying(255) DEFAULT ''::character varying, - "name" character varying(100) NOT NULL -); - - --- --- Name: groups_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "groups_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: groups_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "groups_id_seq" OWNED BY "groups"."id"; - - --- --- Name: last_logins; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "last_logins" ( - "id" integer NOT NULL, - "auth_type" character varying(25), - "user_id" integer, - "ip" character varying(45), - "user_agent" character varying(255), - "date_creation" bigint -); - - --- --- Name: last_logins_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "last_logins_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: last_logins_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "last_logins_id_seq" OWNED BY "last_logins"."id"; - - --- --- Name: links; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "links" ( - "id" integer NOT NULL, - "label" character varying(255) NOT NULL, - "opposite_id" integer DEFAULT 0 -); - - --- --- Name: links_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "links_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: links_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "links_id_seq" OWNED BY "links"."id"; - - --- --- Name: password_reset; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "password_reset" ( - "token" character varying(80) NOT NULL, - "user_id" integer NOT NULL, - "date_expiration" integer NOT NULL, - "date_creation" integer NOT NULL, - "ip" character varying(45) NOT NULL, - "user_agent" character varying(255) NOT NULL, - "is_active" boolean NOT NULL -); - - --- --- Name: plugin_schema_versions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "plugin_schema_versions" ( - "plugin" character varying(80) NOT NULL, - "version" integer DEFAULT 0 NOT NULL -); - - --- --- Name: project_activities; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_activities" ( - "id" integer NOT NULL, - "date_creation" bigint NOT NULL, - "event_name" character varying(50) NOT NULL, - "creator_id" integer, - "project_id" integer, - "task_id" integer, - "data" "text" -); - - --- --- Name: project_activities_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "project_activities_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: project_activities_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "project_activities_id_seq" OWNED BY "project_activities"."id"; - - --- --- Name: project_daily_column_stats; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_daily_column_stats" ( - "id" integer NOT NULL, - "day" character(10) NOT NULL, - "project_id" integer NOT NULL, - "column_id" integer NOT NULL, - "total" integer DEFAULT 0 NOT NULL, - "score" integer DEFAULT 0 NOT NULL -); - - --- --- Name: project_daily_stats; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_daily_stats" ( - "id" integer NOT NULL, - "day" character(10) NOT NULL, - "project_id" integer NOT NULL, - "avg_lead_time" integer DEFAULT 0 NOT NULL, - "avg_cycle_time" integer DEFAULT 0 NOT NULL -); - - --- --- Name: project_daily_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "project_daily_stats_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: project_daily_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "project_daily_stats_id_seq" OWNED BY "project_daily_stats"."id"; - - --- --- Name: project_daily_summaries_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "project_daily_summaries_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: project_daily_summaries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "project_daily_summaries_id_seq" OWNED BY "project_daily_column_stats"."id"; - - --- --- Name: project_has_categories; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_has_categories" ( - "id" integer NOT NULL, - "name" character varying(255) NOT NULL, - "project_id" integer NOT NULL, - "description" "text" -); - - --- --- Name: project_has_categories_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "project_has_categories_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: project_has_categories_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "project_has_categories_id_seq" OWNED BY "project_has_categories"."id"; - - --- --- Name: project_has_files; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_has_files" ( - "id" integer NOT NULL, - "project_id" integer NOT NULL, - "name" character varying(255) NOT NULL, - "path" character varying(255) NOT NULL, - "is_image" boolean DEFAULT false, - "size" integer DEFAULT 0 NOT NULL, - "user_id" integer DEFAULT 0 NOT NULL, - "date" integer DEFAULT 0 NOT NULL -); - - --- --- Name: project_has_files_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "project_has_files_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: project_has_files_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "project_has_files_id_seq" OWNED BY "project_has_files"."id"; - - --- --- Name: project_has_groups; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_has_groups" ( - "group_id" integer NOT NULL, - "project_id" integer NOT NULL, - "role" character varying(25) NOT NULL -); - - --- --- Name: project_has_metadata; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_has_metadata" ( - "project_id" integer NOT NULL, - "name" character varying(50) NOT NULL, - "value" character varying(255) DEFAULT ''::character varying, - "changed_by" integer DEFAULT 0 NOT NULL, - "changed_on" integer DEFAULT 0 NOT NULL -); - - --- --- Name: project_has_notification_types; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "project_has_notification_types" ( - "id" integer NOT NULL, - "project_id" integer NOT NULL, - "notification_type" character varying(50) NOT NULL -); - - --- --- Name: project_has_notification_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "project_has_notification_types_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: project_has_notification_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "project_has_notification_types_id_seq" OWNED BY "project_has_notification_types"."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 -); - - --- --- Name: projects; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "projects" ( - "id" integer NOT NULL, - "name" character varying(255) NOT NULL, - "is_active" boolean DEFAULT true, - "token" character varying(255), - "last_modified" bigint DEFAULT 0, - "is_public" boolean DEFAULT false, - "is_private" boolean DEFAULT false, - "is_everybody_allowed" boolean DEFAULT false, - "default_swimlane" character varying(200) DEFAULT 'Default swimlane'::character varying, - "show_default_swimlane" boolean DEFAULT true, - "description" "text", - "identifier" character varying(50) DEFAULT ''::character varying, - "start_date" character varying(10) DEFAULT ''::character varying, - "end_date" character varying(10) DEFAULT ''::character varying, - "owner_id" integer DEFAULT 0, - "priority_default" integer DEFAULT 0, - "priority_start" integer DEFAULT 0, - "priority_end" integer DEFAULT 3 -); - - --- --- Name: projects_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "projects_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: projects_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "projects_id_seq" OWNED BY "projects"."id"; - - --- --- Name: remember_me; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "remember_me" ( - "id" integer NOT NULL, - "user_id" integer, - "ip" character varying(45), - "user_agent" character varying(255), - "token" character varying(255), - "sequence" character varying(255), - "expiration" integer, - "date_creation" bigint -); - - --- --- Name: remember_me_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "remember_me_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: remember_me_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "remember_me_id_seq" OWNED BY "remember_me"."id"; - - --- --- Name: schema_version; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "schema_version" ( - "version" integer DEFAULT 0 -); - - --- --- Name: settings; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "settings" ( - "option" character varying(100) NOT NULL, - "value" character varying(255) DEFAULT ''::character varying, - "changed_by" integer DEFAULT 0 NOT NULL, - "changed_on" integer DEFAULT 0 NOT NULL -); - - --- --- Name: subtask_time_tracking; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "subtask_time_tracking" ( - "id" integer NOT NULL, - "user_id" integer NOT NULL, - "subtask_id" integer NOT NULL, - "start" bigint DEFAULT 0, - "end" bigint DEFAULT 0, - "time_spent" real DEFAULT 0 -); - - --- --- Name: subtask_time_tracking_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "subtask_time_tracking_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: subtask_time_tracking_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "subtask_time_tracking_id_seq" OWNED BY "subtask_time_tracking"."id"; - - --- --- Name: subtasks; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "subtasks" ( - "id" integer NOT NULL, - "title" character varying(255) NOT NULL, - "status" smallint DEFAULT 0, - "time_estimated" double precision DEFAULT 0, - "time_spent" double precision DEFAULT 0, - "task_id" integer NOT NULL, - "user_id" integer, - "position" integer DEFAULT 1 -); - - --- --- Name: swimlanes; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "swimlanes" ( - "id" integer NOT NULL, - "name" character varying(200) NOT NULL, - "position" integer DEFAULT 1, - "is_active" boolean DEFAULT true, - "project_id" integer, - "description" "text" -); - - --- --- Name: swimlanes_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "swimlanes_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: swimlanes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "swimlanes_id_seq" OWNED BY "swimlanes"."id"; - - --- --- Name: tags; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "tags" ( - "id" integer NOT NULL, - "name" character varying(255) NOT NULL, - "project_id" integer NOT NULL -); - - --- --- Name: tags_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "tags_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: tags_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "tags_id_seq" OWNED BY "tags"."id"; - - --- --- Name: task_has_external_links; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "task_has_external_links" ( - "id" integer NOT NULL, - "link_type" character varying(100) NOT NULL, - "dependency" character varying(100) NOT NULL, - "title" character varying(255) NOT NULL, - "url" character varying(255) NOT NULL, - "date_creation" integer NOT NULL, - "date_modification" integer NOT NULL, - "task_id" integer NOT NULL, - "creator_id" integer DEFAULT 0 -); - - --- --- Name: task_has_external_links_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "task_has_external_links_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: task_has_external_links_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "task_has_external_links_id_seq" OWNED BY "task_has_external_links"."id"; - - --- --- Name: task_has_files; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "task_has_files" ( - "id" integer NOT NULL, - "name" character varying(255) NOT NULL, - "path" character varying(255), - "is_image" boolean DEFAULT false, - "task_id" integer NOT NULL, - "date" bigint DEFAULT 0 NOT NULL, - "user_id" integer DEFAULT 0 NOT NULL, - "size" integer DEFAULT 0 NOT NULL -); - - --- --- Name: task_has_files_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "task_has_files_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: task_has_files_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "task_has_files_id_seq" OWNED BY "task_has_files"."id"; - - --- --- Name: task_has_links; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "task_has_links" ( - "id" integer NOT NULL, - "link_id" integer NOT NULL, - "task_id" integer NOT NULL, - "opposite_task_id" integer NOT NULL -); - - --- --- Name: task_has_links_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "task_has_links_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: task_has_links_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "task_has_links_id_seq" OWNED BY "task_has_links"."id"; - - --- --- Name: task_has_metadata; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "task_has_metadata" ( - "task_id" integer NOT NULL, - "name" character varying(50) NOT NULL, - "value" character varying(255) DEFAULT ''::character varying, - "changed_by" integer DEFAULT 0 NOT NULL, - "changed_on" integer DEFAULT 0 NOT NULL -); - - --- --- Name: task_has_subtasks_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "task_has_subtasks_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: task_has_subtasks_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "task_has_subtasks_id_seq" OWNED BY "subtasks"."id"; - - --- --- Name: task_has_tags; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "task_has_tags" ( - "task_id" integer NOT NULL, - "tag_id" integer NOT NULL -); - - --- --- Name: tasks; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "tasks" ( - "id" integer NOT NULL, - "title" character varying(255) NOT NULL, - "description" "text", - "date_creation" bigint, - "color_id" character varying(255), - "project_id" integer NOT NULL, - "column_id" integer NOT NULL, - "owner_id" integer DEFAULT 0, - "position" integer, - "is_active" boolean DEFAULT true, - "date_completed" bigint, - "score" integer, - "date_due" bigint, - "category_id" integer DEFAULT 0, - "creator_id" integer DEFAULT 0, - "date_modification" integer DEFAULT 0, - "reference" character varying(50) DEFAULT ''::character varying, - "date_started" bigint, - "time_spent" double precision DEFAULT 0, - "time_estimated" double precision DEFAULT 0, - "swimlane_id" integer DEFAULT 0, - "date_moved" bigint DEFAULT 0, - "recurrence_status" integer DEFAULT 0 NOT NULL, - "recurrence_trigger" integer DEFAULT 0 NOT NULL, - "recurrence_factor" integer DEFAULT 0 NOT NULL, - "recurrence_timeframe" integer DEFAULT 0 NOT NULL, - "recurrence_basedate" integer DEFAULT 0 NOT NULL, - "recurrence_parent" integer, - "recurrence_child" integer, - "priority" integer DEFAULT 0 -); - - --- --- Name: tasks_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "tasks_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: tasks_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "tasks_id_seq" OWNED BY "tasks"."id"; - - --- --- Name: transitions; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "transitions" ( - "id" integer NOT NULL, - "user_id" integer NOT NULL, - "project_id" integer NOT NULL, - "task_id" integer NOT NULL, - "src_column_id" integer NOT NULL, - "dst_column_id" integer NOT NULL, - "date" bigint NOT NULL, - "time_spent" integer DEFAULT 0 -); - - --- --- Name: transitions_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "transitions_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: transitions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "transitions_id_seq" OWNED BY "transitions"."id"; - - --- --- Name: user_has_metadata; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "user_has_metadata" ( - "user_id" integer NOT NULL, - "name" character varying(50) NOT NULL, - "value" character varying(255) DEFAULT ''::character varying, - "changed_by" integer DEFAULT 0 NOT NULL, - "changed_on" integer DEFAULT 0 NOT NULL -); - - --- --- Name: user_has_notification_types; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "user_has_notification_types" ( - "id" integer NOT NULL, - "user_id" integer NOT NULL, - "notification_type" character varying(50) -); - - --- --- Name: user_has_notification_types_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "user_has_notification_types_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: user_has_notification_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "user_has_notification_types_id_seq" OWNED BY "user_has_notification_types"."id"; - - --- --- Name: user_has_notifications; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "user_has_notifications" ( - "user_id" integer NOT NULL, - "project_id" integer -); - - --- --- Name: user_has_unread_notifications; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "user_has_unread_notifications" ( - "id" integer NOT NULL, - "user_id" integer NOT NULL, - "date_creation" bigint NOT NULL, - "event_name" character varying(50) NOT NULL, - "event_data" "text" NOT NULL -); - - --- --- Name: user_has_unread_notifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "user_has_unread_notifications_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: user_has_unread_notifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "user_has_unread_notifications_id_seq" OWNED BY "user_has_unread_notifications"."id"; - - --- --- Name: users; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE "users" ( - "id" integer NOT NULL, - "username" character varying(50) NOT NULL, - "password" character varying(255), - "is_ldap_user" boolean DEFAULT false, - "name" character varying(255), - "email" character varying(255), - "google_id" character varying(255), - "github_id" character varying(30), - "notifications_enabled" boolean DEFAULT false, - "timezone" character varying(50), - "language" character varying(5), - "disable_login_form" boolean DEFAULT false, - "twofactor_activated" boolean DEFAULT false, - "twofactor_secret" character(16), - "token" character varying(255) DEFAULT ''::character varying, - "notifications_filter" integer DEFAULT 4, - "nb_failed_login" integer DEFAULT 0, - "lock_expiration_date" bigint DEFAULT 0, - "gitlab_id" integer, - "role" character varying(25) DEFAULT 'app-user'::character varying NOT NULL, - "is_active" boolean DEFAULT true, - "avatar_path" character varying(255) -); - - --- --- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE "users_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE "users_id_seq" OWNED BY "users"."id"; - - --- --- Name: 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: - --- - -ALTER TABLE ONLY "actions" ALTER COLUMN "id" SET DEFAULT "nextval"('"actions_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -ALTER TABLE ONLY "comments" ALTER COLUMN "id" SET DEFAULT "nextval"('"comments_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -ALTER TABLE ONLY "groups" ALTER COLUMN "id" SET DEFAULT "nextval"('"groups_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -ALTER TABLE ONLY "links" ALTER COLUMN "id" SET DEFAULT "nextval"('"links_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -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: - --- - -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: - --- - -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: - --- - -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: - --- - -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: - --- - -ALTER TABLE ONLY "projects" ALTER COLUMN "id" SET DEFAULT "nextval"('"projects_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -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: - --- - -ALTER TABLE ONLY "subtasks" ALTER COLUMN "id" SET DEFAULT "nextval"('"task_has_subtasks_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -ALTER TABLE ONLY "tags" ALTER COLUMN "id" SET DEFAULT "nextval"('"tags_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -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: - --- - -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: - --- - -ALTER TABLE ONLY "tasks" ALTER COLUMN "id" SET DEFAULT "nextval"('"tasks_id_seq"'::"regclass"); - - --- --- Name: 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: - --- - -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: - --- - -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: - --- - -ALTER TABLE ONLY "users" ALTER COLUMN "id" SET DEFAULT "nextval"('"users_id_seq"'::"regclass"); - - --- --- Name: action_has_params_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "action_has_params" - ADD CONSTRAINT "action_has_params_pkey" PRIMARY KEY ("id"); - - --- --- Name: actions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "actions" - ADD CONSTRAINT "actions_pkey" PRIMARY KEY ("id"); - - --- --- Name: columns_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "columns" - ADD CONSTRAINT "columns_pkey" PRIMARY KEY ("id"); - - --- --- Name: columns_title_project_id_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "columns" - ADD CONSTRAINT "columns_title_project_id_key" UNIQUE ("title", "project_id"); - - --- --- Name: comments_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "comments" - ADD CONSTRAINT "comments_pkey" PRIMARY KEY ("id"); - - --- --- Name: currencies_currency_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "currencies" - ADD CONSTRAINT "currencies_currency_key" UNIQUE ("currency"); - - --- --- Name: custom_filters_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "custom_filters" - ADD CONSTRAINT "custom_filters_pkey" PRIMARY KEY ("id"); - - --- --- Name: group_has_users_group_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "group_has_users" - ADD CONSTRAINT "group_has_users_group_id_user_id_key" UNIQUE ("group_id", "user_id"); - - --- --- Name: groups_name_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "groups" - ADD CONSTRAINT "groups_name_key" UNIQUE ("name"); - - --- --- Name: groups_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "groups" - ADD CONSTRAINT "groups_pkey" PRIMARY KEY ("id"); - - --- --- Name: last_logins_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "last_logins" - ADD CONSTRAINT "last_logins_pkey" PRIMARY KEY ("id"); - - --- --- Name: links_label_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "links" - ADD CONSTRAINT "links_label_key" UNIQUE ("label"); - - --- --- Name: links_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "links" - ADD CONSTRAINT "links_pkey" PRIMARY KEY ("id"); - - --- --- Name: password_reset_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "password_reset" - ADD CONSTRAINT "password_reset_pkey" PRIMARY KEY ("token"); - - --- --- Name: plugin_schema_versions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "plugin_schema_versions" - ADD CONSTRAINT "plugin_schema_versions_pkey" PRIMARY KEY ("plugin"); - - --- --- Name: project_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_activities" - ADD CONSTRAINT "project_activities_pkey" PRIMARY KEY ("id"); - - --- --- Name: project_daily_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_daily_stats" - ADD CONSTRAINT "project_daily_stats_pkey" PRIMARY KEY ("id"); - - --- --- Name: project_daily_summaries_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_daily_column_stats" - ADD CONSTRAINT "project_daily_summaries_pkey" PRIMARY KEY ("id"); - - --- --- Name: project_has_categories_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_categories" - ADD CONSTRAINT "project_has_categories_pkey" PRIMARY KEY ("id"); - - --- --- Name: project_has_categories_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_categories" - ADD CONSTRAINT "project_has_categories_project_id_name_key" UNIQUE ("project_id", "name"); - - --- --- Name: project_has_files_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_files" - ADD CONSTRAINT "project_has_files_pkey" PRIMARY KEY ("id"); - - --- --- Name: project_has_groups_group_id_project_id_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_groups" - ADD CONSTRAINT "project_has_groups_group_id_project_id_key" UNIQUE ("group_id", "project_id"); - - --- --- Name: project_has_metadata_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_metadata" - ADD CONSTRAINT "project_has_metadata_project_id_name_key" UNIQUE ("project_id", "name"); - - --- --- Name: project_has_notification_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_notification_types" - ADD CONSTRAINT "project_has_notification_types_pkey" PRIMARY KEY ("id"); - - --- --- Name: project_has_notification_types_project_id_notification_type_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_notification_types" - ADD CONSTRAINT "project_has_notification_types_project_id_notification_type_key" UNIQUE ("project_id", "notification_type"); - - --- --- Name: project_has_users_project_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_users" - ADD CONSTRAINT "project_has_users_project_id_user_id_key" UNIQUE ("project_id", "user_id"); - - --- --- Name: projects_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "projects" - ADD CONSTRAINT "projects_pkey" PRIMARY KEY ("id"); - - --- --- Name: remember_me_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "remember_me" - ADD CONSTRAINT "remember_me_pkey" PRIMARY KEY ("id"); - - --- --- Name: settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "settings" - ADD CONSTRAINT "settings_pkey" PRIMARY KEY ("option"); - - --- --- Name: subtask_time_tracking_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "subtask_time_tracking" - ADD CONSTRAINT "subtask_time_tracking_pkey" PRIMARY KEY ("id"); - - --- --- Name: swimlanes_name_project_id_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "swimlanes" - ADD CONSTRAINT "swimlanes_name_project_id_key" UNIQUE ("name", "project_id"); - - --- --- Name: swimlanes_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "swimlanes" - ADD CONSTRAINT "swimlanes_pkey" PRIMARY KEY ("id"); - - --- --- Name: tags_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "tags" - ADD CONSTRAINT "tags_pkey" PRIMARY KEY ("id"); - - --- --- Name: tags_project_id_name_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "tags" - ADD CONSTRAINT "tags_project_id_name_key" UNIQUE ("project_id", "name"); - - --- --- Name: task_has_external_links_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_external_links" - ADD CONSTRAINT "task_has_external_links_pkey" PRIMARY KEY ("id"); - - --- --- Name: task_has_files_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_files" - ADD CONSTRAINT "task_has_files_pkey" PRIMARY KEY ("id"); - - --- --- Name: task_has_links_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_links" - ADD CONSTRAINT "task_has_links_pkey" PRIMARY KEY ("id"); - - --- --- Name: task_has_metadata_task_id_name_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_metadata" - ADD CONSTRAINT "task_has_metadata_task_id_name_key" UNIQUE ("task_id", "name"); - - --- --- Name: task_has_subtasks_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "subtasks" - ADD CONSTRAINT "task_has_subtasks_pkey" PRIMARY KEY ("id"); - - --- --- Name: task_has_tags_tag_id_task_id_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_tags" - ADD CONSTRAINT "task_has_tags_tag_id_task_id_key" UNIQUE ("tag_id", "task_id"); - - --- --- Name: tasks_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "tasks" - ADD CONSTRAINT "tasks_pkey" PRIMARY KEY ("id"); - - --- --- Name: transitions_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "transitions" - ADD CONSTRAINT "transitions_pkey" PRIMARY KEY ("id"); - - --- --- Name: user_has_metadata_user_id_name_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_metadata" - ADD CONSTRAINT "user_has_metadata_user_id_name_key" UNIQUE ("user_id", "name"); - - --- --- Name: user_has_notification_types_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_notification_types" - ADD CONSTRAINT "user_has_notification_types_pkey" PRIMARY KEY ("id"); - - --- --- Name: user_has_notifications_project_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_notifications" - ADD CONSTRAINT "user_has_notifications_project_id_user_id_key" UNIQUE ("project_id", "user_id"); - - --- --- Name: user_has_unread_notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_unread_notifications" - ADD CONSTRAINT "user_has_unread_notifications_pkey" PRIMARY KEY ("id"); - - --- --- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "users" - ADD CONSTRAINT "users_pkey" PRIMARY KEY ("id"); - - --- --- Name: categories_project_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "categories_project_idx" ON "project_has_categories" USING "btree" ("project_id"); - - --- --- Name: columns_project_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "columns_project_idx" ON "columns" USING "btree" ("project_id"); - - --- --- Name: comments_reference_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "comments_reference_idx" ON "comments" USING "btree" ("reference"); - - --- --- Name: comments_task_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "comments_task_idx" ON "comments" USING "btree" ("task_id"); - - --- --- Name: files_task_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "files_task_idx" ON "task_has_files" USING "btree" ("task_id"); - - --- --- Name: project_daily_column_stats_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "project_daily_column_stats_idx" ON "project_daily_column_stats" USING "btree" ("day", "project_id", "column_id"); - - --- --- Name: project_daily_stats_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "project_daily_stats_idx" ON "project_daily_stats" USING "btree" ("day", "project_id"); - - --- --- Name: subtasks_task_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "subtasks_task_idx" ON "subtasks" USING "btree" ("task_id"); - - --- --- Name: swimlanes_project_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "swimlanes_project_idx" ON "swimlanes" USING "btree" ("project_id"); - - --- --- Name: task_has_links_task_index; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "task_has_links_task_index" ON "task_has_links" USING "btree" ("task_id"); - - --- --- Name: task_has_links_unique; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "task_has_links_unique" ON "task_has_links" USING "btree" ("link_id", "task_id", "opposite_task_id"); - - --- --- Name: tasks_project_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "tasks_project_idx" ON "tasks" USING "btree" ("project_id"); - - --- --- Name: tasks_reference_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "tasks_reference_idx" ON "tasks" USING "btree" ("reference"); - - --- --- Name: transitions_project_index; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "transitions_project_index" ON "transitions" USING "btree" ("project_id"); - - --- --- Name: transitions_task_index; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "transitions_task_index" ON "transitions" USING "btree" ("task_id"); - - --- --- Name: transitions_user_index; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX "transitions_user_index" ON "transitions" USING "btree" ("user_id"); - - --- --- Name: user_has_notification_types_user_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "user_has_notification_types_user_idx" ON "user_has_notification_types" USING "btree" ("user_id", "notification_type"); - - --- --- Name: users_username_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX "users_username_idx" ON "users" USING "btree" ("username"); - - --- --- Name: action_has_params_action_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "action_has_params" - ADD CONSTRAINT "action_has_params_action_id_fkey" FOREIGN KEY ("action_id") REFERENCES "actions"("id") ON DELETE CASCADE; - - --- --- Name: actions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "actions" - ADD CONSTRAINT "actions_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: columns_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "columns" - ADD CONSTRAINT "columns_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: comments_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "comments" - ADD CONSTRAINT "comments_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: group_has_users_group_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "group_has_users" - ADD CONSTRAINT "group_has_users_group_id_fkey" FOREIGN KEY ("group_id") REFERENCES "groups"("id") ON DELETE CASCADE; - - --- --- Name: group_has_users_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "group_has_users" - ADD CONSTRAINT "group_has_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: last_logins_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "last_logins" - ADD CONSTRAINT "last_logins_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: password_reset_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "password_reset" - ADD CONSTRAINT "password_reset_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: project_activities_creator_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_activities" - ADD CONSTRAINT "project_activities_creator_id_fkey" FOREIGN KEY ("creator_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: project_activities_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_activities" - ADD CONSTRAINT "project_activities_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_activities_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_activities" - ADD CONSTRAINT "project_activities_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: project_daily_stats_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_daily_stats" - ADD CONSTRAINT "project_daily_stats_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_daily_summaries_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_daily_column_stats" - ADD CONSTRAINT "project_daily_summaries_column_id_fkey" FOREIGN KEY ("column_id") REFERENCES "columns"("id") ON DELETE CASCADE; - - --- --- Name: project_daily_summaries_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_daily_column_stats" - ADD CONSTRAINT "project_daily_summaries_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_has_categories_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_categories" - ADD CONSTRAINT "project_has_categories_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_has_files_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_files" - ADD CONSTRAINT "project_has_files_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_has_groups_group_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_groups" - ADD CONSTRAINT "project_has_groups_group_id_fkey" FOREIGN KEY ("group_id") REFERENCES "groups"("id") ON DELETE CASCADE; - - --- --- Name: project_has_groups_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_groups" - ADD CONSTRAINT "project_has_groups_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_has_metadata_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_metadata" - ADD CONSTRAINT "project_has_metadata_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_has_notification_types_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_notification_types" - ADD CONSTRAINT "project_has_notification_types_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_has_users_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_users" - ADD CONSTRAINT "project_has_users_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: project_has_users_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "project_has_users" - ADD CONSTRAINT "project_has_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: remember_me_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "remember_me" - ADD CONSTRAINT "remember_me_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: subtask_time_tracking_subtask_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "subtask_time_tracking" - ADD CONSTRAINT "subtask_time_tracking_subtask_id_fkey" FOREIGN KEY ("subtask_id") REFERENCES "subtasks"("id") ON DELETE CASCADE; - - --- --- Name: subtask_time_tracking_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "subtask_time_tracking" - ADD CONSTRAINT "subtask_time_tracking_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: swimlanes_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "swimlanes" - ADD CONSTRAINT "swimlanes_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: task_has_external_links_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_external_links" - ADD CONSTRAINT "task_has_external_links_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: task_has_files_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_files" - ADD CONSTRAINT "task_has_files_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: task_has_links_link_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_links" - ADD CONSTRAINT "task_has_links_link_id_fkey" FOREIGN KEY ("link_id") REFERENCES "links"("id") ON DELETE CASCADE; - - --- --- Name: task_has_links_opposite_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_links" - ADD CONSTRAINT "task_has_links_opposite_task_id_fkey" FOREIGN KEY ("opposite_task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: task_has_links_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_links" - ADD CONSTRAINT "task_has_links_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: task_has_metadata_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_metadata" - ADD CONSTRAINT "task_has_metadata_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: task_has_subtasks_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "subtasks" - ADD CONSTRAINT "task_has_subtasks_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: task_has_tags_tag_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_tags" - ADD CONSTRAINT "task_has_tags_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "tags"("id") ON DELETE CASCADE; - - --- --- Name: task_has_tags_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "task_has_tags" - ADD CONSTRAINT "task_has_tags_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: tasks_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "tasks" - ADD CONSTRAINT "tasks_column_id_fkey" FOREIGN KEY ("column_id") REFERENCES "columns"("id") ON DELETE CASCADE; - - --- --- Name: tasks_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "tasks" - ADD CONSTRAINT "tasks_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: transitions_dst_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "transitions" - ADD CONSTRAINT "transitions_dst_column_id_fkey" FOREIGN KEY ("dst_column_id") REFERENCES "columns"("id") ON DELETE CASCADE; - - --- --- Name: transitions_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "transitions" - ADD CONSTRAINT "transitions_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: transitions_src_column_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "transitions" - ADD CONSTRAINT "transitions_src_column_id_fkey" FOREIGN KEY ("src_column_id") REFERENCES "columns"("id") ON DELETE CASCADE; - - --- --- Name: transitions_task_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "transitions" - ADD CONSTRAINT "transitions_task_id_fkey" FOREIGN KEY ("task_id") REFERENCES "tasks"("id") ON DELETE CASCADE; - - --- --- Name: transitions_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "transitions" - ADD CONSTRAINT "transitions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: user_has_metadata_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_metadata" - ADD CONSTRAINT "user_has_metadata_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: user_has_notification_types_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_notification_types" - ADD CONSTRAINT "user_has_notification_types_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: user_has_notifications_project_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_notifications" - ADD CONSTRAINT "user_has_notifications_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE; - - --- --- Name: user_has_notifications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_notifications" - ADD CONSTRAINT "user_has_notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- Name: user_has_unread_notifications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY "user_has_unread_notifications" - ADD CONSTRAINT "user_has_unread_notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE; - - --- --- PostgreSQL database dump complete --- - --- --- PostgreSQL database dump --- - --- Dumped from database version 9.5.2 --- Dumped by pg_dump version 9.5.2 - -SET statement_timeout = 0; -SET lock_timeout = 0; -SET client_encoding = 'UTF8'; -SET standard_conforming_strings = on; -SET check_function_bodies = false; -SET client_min_messages = warning; -SET row_security = off; - -SET search_path = public, pg_catalog; - --- --- Data for Name: settings; Type: TABLE DATA; Schema: public; Owner: postgres --- - -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_highlight_period', '172800', 0, 0); -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', '1aff324d30632aaed0d4f4dc1281be0d5bbc7b4fcddccc4badcd6c8f3d43', 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); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_date_format', 'm/d/Y', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('project_categories', '', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('subtask_restriction', '0', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_stylesheet', '', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_currency', 'USD', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('integration_gravatar', '0', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('calendar_user_subtasks_time_tracking', '0', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('calendar_user_tasks', 'date_started', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('calendar_project_tasks', 'date_started', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('webhook_url', '', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('default_color', 'yellow', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('subtask_time_tracking', '1', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('cfd_include_closed_tasks', '1', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('password_reset', '1', 0, 0); -INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('api_token', '19ffd9709d03ce50675c3a43d1c49c1ac207f4bc45f06c5b2701fbdf8929', 0, 0); - - --- --- PostgreSQL database dump complete --- - --- --- PostgreSQL database dump --- - --- Dumped from database version 9.5.2 --- Dumped by pg_dump version 9.5.2 - -SET statement_timeout = 0; -SET lock_timeout = 0; -SET client_encoding = 'UTF8'; -SET standard_conforming_strings = on; -SET check_function_bodies = false; -SET client_min_messages = warning; -SET row_security = off; - -SET search_path = public, pg_catalog; - --- --- Data for Name: links; Type: TABLE DATA; Schema: public; Owner: postgres --- - -INSERT INTO links (id, label, opposite_id) VALUES (1, 'relates to', 0); -INSERT INTO links (id, label, opposite_id) VALUES (2, 'blocks', 3); -INSERT INTO links (id, label, opposite_id) VALUES (3, 'is blocked by', 2); -INSERT INTO links (id, label, opposite_id) VALUES (4, 'duplicates', 5); -INSERT INTO links (id, label, opposite_id) VALUES (5, 'is duplicated by', 4); -INSERT INTO links (id, label, opposite_id) VALUES (6, 'is a child of', 7); -INSERT INTO links (id, label, opposite_id) VALUES (7, 'is a parent of', 6); -INSERT INTO links (id, label, opposite_id) VALUES (8, 'targets milestone', 9); -INSERT INTO links (id, label, opposite_id) VALUES (9, 'is a milestone of', 8); -INSERT INTO links (id, label, opposite_id) VALUES (10, 'fixes', 11); -INSERT INTO links (id, label, opposite_id) VALUES (11, 'is fixed by', 10); - - --- --- Name: links_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres --- - -SELECT pg_catalog.setval('links_id_seq', 11, true); - - --- --- PostgreSQL database dump complete --- - -INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$Kv6fus67I/ZG/3LYJ7bRLeis8bk8455Lwtu12ElgnGm3lhRs/z7Ni', 'app-admin');INSERT INTO schema_version VALUES ('90'); diff --git a/sources/app/Schema/Sqlite.php b/sources/app/Schema/Sqlite.php deleted file mode 100644 index dac348d..0000000 --- a/sources/app/Schema/Sqlite.php +++ /dev/null @@ -1,1290 +0,0 @@ -<?php - -namespace Schema; - -use Kanboard\Core\Security\Token; -use Kanboard\Core\Security\Role; -use PDO; - -const VERSION = 102; - -function version_102(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE tags ( - id INTEGER PRIMARY KEY, - name TEXT NOT NULL, - project_id INTEGER NOT NULL, - UNIQUE(project_id, name) - ) - "); - - $pdo->exec(" - CREATE TABLE task_has_tags ( - task_id INTEGER NOT NULL, - tag_id INTEGER NOT NULL, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(tag_id) REFERENCES tags(id) ON DELETE CASCADE, - UNIQUE(tag_id, task_id) - ) - "); -} - -function version_101(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN avatar_path TEXT"); -} - -function version_100(PDO $pdo) -{ - $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE user_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE project_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE task_has_metadata ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); - - $pdo->exec("ALTER TABLE settings ADD COLUMN changed_by INTEGER DEFAULT 0 NOT NULL"); - $pdo->exec("ALTER TABLE settings ADD COLUMN changed_on INTEGER DEFAULT 0 NOT NULL"); - -} - -function version_99(PDO $pdo) -{ - $pdo->exec("UPDATE project_activities SET event_name='task.file.create' WHERE event_name='file.create'"); -} - -function version_98(PDO $pdo) -{ - $pdo->exec('ALTER TABLE files RENAME TO task_has_files'); - - $pdo->exec(" - CREATE TABLE project_has_files ( - id INTEGER PRIMARY KEY, - project_id INTEGER NOT NULL, - name TEXT COLLATE NOCASE NOT NULL, - path TEXT NOT NULL, - is_image INTEGER DEFAULT 0, - size INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - date INTEGER DEFAULT 0 NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - )" - ); -} - -function version_97(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_active INTEGER DEFAULT 1"); -} - -function version_96(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_external_links ( - id INTEGER PRIMARY KEY, - link_type TEXT NOT NULL, - dependency TEXT NOT NULL, - title TEXT NOT NULL, - url TEXT NOT NULL, - date_creation INTEGER NOT NULL, - date_modification INTEGER NOT NULL, - task_id INTEGER NOT NULL, - creator_id INTEGER DEFAULT 0, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ) - "); -} - -function version_95(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_default INTEGER DEFAULT 0"); - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_start INTEGER DEFAULT 0"); - $pdo->exec("ALTER TABLE projects ADD COLUMN priority_end INTEGER DEFAULT 3"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN priority INTEGER DEFAULT 0"); -} - -function version_94(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN owner_id INTEGER DEFAULT 0"); -} - -function version_93(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE password_reset ( - token TEXT PRIMARY KEY, - user_id INTEGER NOT NULL, - date_expiration INTEGER NOT NULL, - date_creation INTEGER NOT NULL, - ip TEXT NOT NULL, - user_agent TEXT NOT NULL, - is_active INTEGER NOT NULL, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) - "); - - $pdo->exec("INSERT INTO settings VALUES ('password_reset', '1')"); -} - -function version_92(PDO $pdo) -{ - $rq = $pdo->prepare('SELECT * FROM actions'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE actions SET action_name=? WHERE id=?'); - - foreach ($rows as $row) { - if ($row['action_name'] === 'TaskAssignCurrentUser' && $row['event_name'] === 'task.move.column') { - $row['action_name'] = '\Kanboard\Action\TaskAssignCurrentUserColumn'; - } elseif ($row['action_name'] === 'TaskClose' && $row['event_name'] === 'task.move.column') { - $row['action_name'] = '\Kanboard\Action\TaskCloseColumn'; - } elseif ($row['action_name'] === 'TaskLogMoveAnotherColumn') { - $row['action_name'] = '\Kanboard\Action\CommentCreationMoveTaskColumn'; - } elseif ($row['action_name']{0} !== '\\') { - $row['action_name'] = '\Kanboard\Action\\'.$row['action_name']; - } - - $rq->execute(array($row['action_name'], $row['id'])); - } -} - -function version_91(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT '".Role::APP_USER."'"); - - $rq = $pdo->prepare('SELECT * FROM users'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE users SET "role"=? WHERE "id"=?'); - - foreach ($rows as $row) { - $role = Role::APP_USER; - - if ($row['is_admin'] == 1) { - $role = Role::APP_ADMIN; - } else if ($row['is_project_admin']) { - $role = Role::APP_MANAGER; - } - - $rq->execute(array($role, $row['id'])); - } -} - -function version_90(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_groups ( - group_id INTEGER NOT NULL, - project_id INTEGER NOT NULL, - role TEXT NOT NULL, - FOREIGN KEY(group_id) REFERENCES groups(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(group_id, project_id) - ) - "); - - $pdo->exec("ALTER TABLE project_has_users ADD COLUMN role TEXT NOT NULL DEFAULT '".Role::PROJECT_VIEWER."'"); - - $rq = $pdo->prepare('SELECT * FROM project_has_users'); - $rq->execute(); - $rows = $rq->fetchAll(PDO::FETCH_ASSOC) ?: array(); - - $rq = $pdo->prepare('UPDATE project_has_users SET "role"=? WHERE "id"=?'); - - foreach ($rows as $row) { - $rq->execute(array( - $row['is_owner'] == 1 ? Role::PROJECT_MANAGER : Role::PROJECT_MEMBER, - $row['id'], - )); - } -} - -function version_89(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE groups ( - id INTEGER PRIMARY KEY, - external_id TEXT DEFAULT '', - name TEXT NOCASE NOT NULL UNIQUE - ) - "); - - $pdo->exec(" - CREATE TABLE group_has_users ( - group_id INTEGER NOT NULL, - user_id INTEGER NOT NULL, - FOREIGN KEY(group_id) REFERENCES groups(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(group_id, user_id) - ) - "); -} - -function version_88(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE user_has_metadata ( - user_id INTEGER NOT NULL, - name TEXT NOT NULL, - value TEXT DEFAULT '', - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(user_id, name) - ) - "); - - $pdo->exec(" - CREATE TABLE project_has_metadata ( - project_id INTEGER NOT NULL, - name TEXT NOT NULL, - value TEXT DEFAULT '', - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, name) - ) - "); - - $pdo->exec(" - CREATE TABLE task_has_metadata ( - task_id INTEGER NOT NULL, - name TEXT NOT NULL, - value TEXT DEFAULT '', - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - UNIQUE(task_id, name) - ) - "); - - $pdo->exec("DROP TABLE project_integrations"); - - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_server'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_domain'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_username'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_password'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_nickname'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_jabber_room'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_api_url'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_id'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_hipchat_room_token'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_url'"); - $pdo->exec("DELETE FROM settings WHERE \"option\"='integration_slack_webhook_channel'"); -} - -function version_87(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_notification_types ( - id INTEGER PRIMARY KEY, - project_id INTEGER NOT NULL, - notification_type TEXT NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, notification_type) - ) - "); -} - -function version_86(PDO $pdo) -{ - $pdo->exec("ALTER TABLE custom_filters ADD COLUMN append INTEGER DEFAULT 0"); -} - -function version_85(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE user_has_unread_notifications ( - id INTEGER PRIMARY KEY, - user_id INTEGER NOT NULL, - date_creation INTEGER NOT NULL, - event_name TEXT NOT NULL, - event_data TEXT NOT NULL, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) - "); - - $pdo->exec(" - CREATE TABLE user_has_notification_types ( - id INTEGER PRIMARY KEY, - user_id INTEGER NOT NULL, - notification_type TEXT, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('CREATE UNIQUE INDEX user_has_notification_types_user_idx ON user_has_notification_types(user_id, notification_type)'); - - // Migrate people who have notification enabled before - $rq = $pdo->prepare('SELECT id FROM users WHERE notifications_enabled=1'); - $rq->execute(); - $user_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0); - - foreach ($user_ids as $user_id) { - $rq = $pdo->prepare('INSERT INTO user_has_notification_types (user_id, notification_type) VALUES (?, ?)'); - $rq->execute(array($user_id, 'email')); - } -} - -function version_84(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE custom_filters ( - id INTEGER PRIMARY KEY, - filter TEXT NOT NULL, - project_id INTEGER NOT NULL, - user_id INTEGER NOT NULL, - name TEXT NOT NULL, - is_shared INTEGER DEFAULT 0 - ) - "); -} - -function version_83(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE plugin_schema_versions ( - plugin TEXT NOT NULL PRIMARY KEY, - version INTEGER NOT NULL DEFAULT 0 - ) - "); -} - -function version_82(PDO $pdo) -{ - $pdo->exec("ALTER TABLE swimlanes ADD COLUMN description TEXT"); -} - -function version_81(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN gitlab_id INTEGER"); -} - -function version_80(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN start_date TEXT DEFAULT ''"); - $pdo->exec("ALTER TABLE projects ADD COLUMN end_date TEXT DEFAULT ''"); -} - -function version_79(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_project_admin INTEGER DEFAULT 0"); -} - -function version_78(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN nb_failed_login INTEGER DEFAULT 0"); - $pdo->exec("ALTER TABLE users ADD COLUMN lock_expiration_date INTEGER DEFAULT 0"); -} - -function version_77(PDO $pdo) -{ - $pdo->exec("INSERT INTO settings VALUES ('subtask_time_tracking', '1')"); - $pdo->exec("INSERT INTO settings VALUES ('cfd_include_closed_tasks', '1')"); -} - -function version_76(PDO $pdo) -{ - $pdo->exec("INSERT INTO settings VALUES ('default_color', 'yellow')"); -} - -function version_75(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_daily_stats ( - id INTEGER PRIMARY KEY, - day TEXT NOT NULL, - project_id INTEGER NOT NULL, - avg_lead_time INTEGER NOT NULL DEFAULT 0, - avg_cycle_time INTEGER NOT NULL DEFAULT 0, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('CREATE UNIQUE INDEX project_daily_stats_idx ON project_daily_stats(day, project_id)'); - - $pdo->exec('ALTER TABLE project_daily_summaries RENAME TO project_daily_column_stats'); -} - -function version_74(PDO $pdo) -{ - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN slack_webhook_channel TEXT DEFAULT ''"); - $pdo->exec("INSERT INTO settings VALUES ('integration_slack_webhook_channel', '')"); -} - -function version_73(PDO $pdo) -{ - $pdo->exec("DELETE FROM settings WHERE option='subtask_time_tracking'"); -} - -function version_72(PDO $pdo) -{ - $pdo->exec( - 'ALTER TABLE comments RENAME TO comments_bak' - ); - - $pdo->exec( - 'CREATE TABLE comments ( - id INTEGER PRIMARY KEY, - task_id INTEGER NOT NULL, - user_id INTEGER DEFAULT 0, - date_creation INTEGER NOT NULL, - comment TEXT NOT NULL, - reference VARCHAR(50), - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - )' - ); - - $pdo->exec( - 'INSERT INTO comments SELECT * FROM comments_bak' - ); - - $pdo->exec( - 'DROP TABLE comments_bak' - ); -} - -function version_71(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN notifications_filter INTEGER DEFAULT 4"); -} - -function version_70(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('webhook_url', '')); - - $pdo->exec("DELETE FROM settings WHERE option='webhook_url_task_creation'"); - $pdo->exec("DELETE FROM settings WHERE option='webhook_url_task_modification'"); -} - -function version_69(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN token TEXT DEFAULT ''"); -} - -function version_68(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('calendar_user_subtasks_time_tracking', 0)); - $rq->execute(array('calendar_user_tasks', 'date_started')); - $rq->execute(array('calendar_project_tasks', 'date_started')); - - $pdo->exec("DELETE FROM settings WHERE option='subtask_forecast'"); -} - -function version_67(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_jabber', '0')); - $rq->execute(array('integration_jabber_server', '')); - $rq->execute(array('integration_jabber_domain', '')); - $rq->execute(array('integration_jabber_username', '')); - $rq->execute(array('integration_jabber_password', '')); - $rq->execute(array('integration_jabber_nickname', 'kanboard')); - $rq->execute(array('integration_jabber_room', '')); - - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber INTEGER DEFAULT '0'"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_server TEXT DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_domain TEXT DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_username TEXT DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_password TEXT DEFAULT ''"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_nickname TEXT DEFAULT 'kanboard'"); - $pdo->exec("ALTER TABLE project_integrations ADD COLUMN jabber_room TEXT DEFAULT ''"); -} - -function version_66(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_status INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_trigger INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_factor INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_timeframe INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_basedate INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_parent INTEGER'); - $pdo->exec('ALTER TABLE tasks ADD COLUMN recurrence_child INTEGER'); -} - -function version_65(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN identifier TEXT DEFAULT ''"); -} - -function version_64(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_integrations ( - id INTEGER PRIMARY KEY, - project_id INTEGER NOT NULL UNIQUE, - hipchat INTEGER DEFAULT 0, - hipchat_api_url TEXT DEFAULT 'https://api.hipchat.com', - hipchat_room_id TEXT, - hipchat_room_token TEXT, - slack INTEGER DEFAULT 0, - slack_webhook_url TEXT, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) - "); -} - -function version_63(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_daily_summaries ADD COLUMN score INTEGER NOT NULL DEFAULT 0'); -} - -function version_62(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_has_categories ADD COLUMN description TEXT'); -} - -function version_61(PDO $pdo) -{ - $pdo->exec('ALTER TABLE files ADD COLUMN "date" INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE files ADD COLUMN "user_id" INTEGER NOT NULL DEFAULT 0'); - $pdo->exec('ALTER TABLE files ADD COLUMN "size" INTEGER NOT NULL DEFAULT 0'); -} - -function version_60(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN twofactor_activated INTEGER DEFAULT 0'); - $pdo->exec('ALTER TABLE users ADD COLUMN twofactor_secret TEXT'); -} - -function version_59(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_gravatar', '0')); -} - -function version_58(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_hipchat', '0')); - $rq->execute(array('integration_hipchat_api_url', 'https://api.hipchat.com')); - $rq->execute(array('integration_hipchat_room_id', '')); - $rq->execute(array('integration_hipchat_room_token', '')); -} - -function version_57(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('integration_slack_webhook', '0')); - $rq->execute(array('integration_slack_webhook_url', '')); -} - -function version_56(PDO $pdo) -{ - $pdo->exec('CREATE TABLE currencies ("currency" TEXT NOT NULL UNIQUE, "rate" REAL DEFAULT 0)'); - - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_currency', 'USD')); -} - -function version_55(PDO $pdo) -{ - $pdo->exec('CREATE TABLE transitions ( - "id" INTEGER PRIMARY KEY, - "user_id" INTEGER NOT NULL, - "project_id" INTEGER NOT NULL, - "task_id" INTEGER NOT NULL, - "src_column_id" INTEGER NOT NULL, - "dst_column_id" INTEGER NOT NULL, - "date" INTEGER NOT NULL, - "time_spent" INTEGER DEFAULT 0, - FOREIGN KEY(src_column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(dst_column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - )'); - - $pdo->exec("CREATE INDEX transitions_task_index ON transitions(task_id)"); - $pdo->exec("CREATE INDEX transitions_project_index ON transitions(project_id)"); - $pdo->exec("CREATE INDEX transitions_user_index ON transitions(user_id)"); -} - -function version_54(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('subtask_forecast', '0')); -} - -function version_53(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_stylesheet', '')); -} - -function version_52(PDO $pdo) -{ - $pdo->exec("ALTER TABLE subtask_time_tracking ADD COLUMN time_spent REAL DEFAULT 0"); -} - -function version_48(PDO $pdo) -{ - $pdo->exec('ALTER TABLE subtasks ADD COLUMN position INTEGER DEFAULT 1'); - - // Migrate all subtasks position - - $task_id = 0; - $position = 1; - $urq = $pdo->prepare('UPDATE subtasks SET position=? WHERE id=?'); - - $rq = $pdo->prepare('SELECT * FROM subtasks ORDER BY task_id, id ASC'); - $rq->execute(); - - foreach ($rq->fetchAll(PDO::FETCH_ASSOC) as $subtask) { - if ($task_id != $subtask['task_id']) { - $position = 1; - $task_id = $subtask['task_id']; - } - - $urq->execute(array($position, $subtask['id'])); - $position++; - } -} - -function version_47(PDO $pdo) -{ - $pdo->exec('ALTER TABLE task_has_files RENAME TO files'); - $pdo->exec('ALTER TABLE task_has_subtasks RENAME TO subtasks'); -} - -function version_46(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects ADD COLUMN description TEXT'); -} - -function version_45(PDO $pdo) -{ - $pdo->exec("CREATE TABLE links ( - id INTEGER PRIMARY KEY, - label TEXT NOT NULL, - opposite_id INTEGER DEFAULT 0, - UNIQUE(label) - )"); - - $pdo->exec("CREATE TABLE task_has_links ( - id INTEGER PRIMARY KEY, - link_id INTEGER NOT NULL, - task_id INTEGER NOT NULL, - opposite_task_id INTEGER NOT NULL, - FOREIGN KEY(link_id) REFERENCES links(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(opposite_task_id) REFERENCES tasks(id) ON DELETE CASCADE - )"); - - $pdo->exec("CREATE INDEX task_has_links_task_index ON task_has_links(task_id)"); - $pdo->exec("CREATE UNIQUE INDEX task_has_links_unique ON task_has_links(link_id, task_id, opposite_task_id)"); - - $rq = $pdo->prepare('INSERT INTO links (label, opposite_id) VALUES (?, ?)'); - $rq->execute(array('relates to', 0)); - $rq->execute(array('blocks', 3)); - $rq->execute(array('is blocked by', 2)); - $rq->execute(array('duplicates', 5)); - $rq->execute(array('is duplicated by', 4)); - $rq->execute(array('is a child of', 7)); - $rq->execute(array('is a parent of', 6)); - $rq->execute(array('targets milestone', 9)); - $rq->execute(array('is a milestone of', 8)); - $rq->execute(array('fixes', 11)); - $rq->execute(array('is fixed by', 10)); -} - -function version_44(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ADD COLUMN date_moved INTEGER DEFAULT 0'); - - /* Update tasks.date_moved from project_activities table if tasks.date_moved = null or 0. - * We take max project_activities.date_creation where event_name in task.create','task.move.column - * since creation date is always less than task moves - */ - $pdo->exec("UPDATE tasks - SET date_moved = ( - SELECT md - FROM ( - SELECT task_id, max(date_creation) md - FROM project_activities - WHERE event_name IN ('task.create', 'task.move.column') - GROUP BY task_id - ) src - WHERE id = src.task_id - ) - WHERE (date_moved IS NULL OR date_moved = 0) AND id IN ( - SELECT task_id - FROM ( - SELECT task_id, max(date_creation) md - FROM project_activities - WHERE event_name IN ('task.create', 'task.move.column') - GROUP BY task_id - ) src - )"); - - // If there is no activities for some tasks use the date_creation - $pdo->exec("UPDATE tasks SET date_moved = date_creation WHERE date_moved IS NULL OR date_moved = 0"); -} - -function version_43(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN disable_login_form INTEGER DEFAULT 0'); -} - -function version_42(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('subtask_restriction', '0')); - $rq->execute(array('subtask_time_tracking', '0')); - - $pdo->exec(" - CREATE TABLE subtask_time_tracking ( - id INTEGER PRIMARY KEY, - user_id INTEGER NOT NULL, - subtask_id INTEGER NOT NULL, - start INTEGER DEFAULT 0, - end INTEGER DEFAULT 0, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(subtask_id) REFERENCES task_has_subtasks(id) ON DELETE CASCADE - ) - "); -} - -function version_41(PDO $pdo) -{ - $pdo->exec('ALTER TABLE columns ADD COLUMN description TEXT'); -} - -function version_40(PDO $pdo) -{ - $pdo->exec('ALTER TABLE users ADD COLUMN timezone TEXT'); - $pdo->exec('ALTER TABLE users ADD COLUMN language TEXT'); -} - -function version_39(PDO $pdo) -{ - // Avoid some full table scans - $pdo->exec('CREATE INDEX users_admin_idx ON users(is_admin)'); - $pdo->exec('CREATE INDEX columns_project_idx ON columns(project_id)'); - $pdo->exec('CREATE INDEX tasks_project_idx ON tasks(project_id)'); - $pdo->exec('CREATE INDEX swimlanes_project_idx ON swimlanes(project_id)'); - $pdo->exec('CREATE INDEX categories_project_idx ON project_has_categories(project_id)'); - $pdo->exec('CREATE INDEX subtasks_task_idx ON task_has_subtasks(task_id)'); - $pdo->exec('CREATE INDEX files_task_idx ON task_has_files(task_id)'); - $pdo->exec('CREATE INDEX comments_task_idx ON comments(task_id)'); - - // Set the ownership for all private projects - $rq = $pdo->prepare('SELECT id FROM projects WHERE is_private=1'); - $rq->execute(); - $project_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0); - - $rq = $pdo->prepare('UPDATE project_has_users SET is_owner=1 WHERE project_id=?'); - - foreach ($project_ids as $project_id) { - $rq->execute(array($project_id)); - } -} - -function version_38(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('project_categories', '')); -} - -function version_37(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE swimlanes ( - id INTEGER PRIMARY KEY, - name TEXT NOT NULL, - position INTEGER DEFAULT 1, - is_active INTEGER DEFAULT 1, - project_id INTEGER NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE (name, project_id) - ) - "); - - $pdo->exec('ALTER TABLE tasks ADD COLUMN swimlane_id INTEGER DEFAULT 0'); - $pdo->exec("ALTER TABLE projects ADD COLUMN default_swimlane TEXT DEFAULT 'Default swimlane'"); - $pdo->exec("ALTER TABLE projects ADD COLUMN show_default_swimlane INTEGER DEFAULT 1"); -} - -function version_36(PDO $pdo) -{ - $pdo->exec('ALTER TABLE project_has_users ADD COLUMN is_owner INTEGER DEFAULT "0"'); -} - -function version_35(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_daily_summaries ( - id INTEGER PRIMARY KEY, - day TEXT NOT NULL, - project_id INTEGER NOT NULL, - column_id INTEGER NOT NULL, - total INTEGER NOT NULL DEFAULT 0, - FOREIGN KEY(column_id) REFERENCES columns(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('CREATE UNIQUE INDEX project_daily_column_stats_idx ON project_daily_summaries(day, project_id, column_id)'); -} - -function version_34(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects ADD COLUMN is_everybody_allowed INTEGER DEFAULT "0"'); -} - -function version_33(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_activities ( - id INTEGER PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name TEXT NOT NULL, - creator_id INTEGE NOT NULL, - project_id INTEGER NOT NULL, - task_id INTEGER NOT NULL, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ) - "); - - $pdo->exec('DROP TABLE task_has_events'); - $pdo->exec('DROP TABLE comment_has_events'); - $pdo->exec('DROP TABLE subtask_has_events'); -} - -function version_32(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN date_started INTEGER"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN time_spent NUMERIC DEFAULT 0"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN time_estimated NUMERIC DEFAULT 0"); -} - -function version_31(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects ADD COLUMN is_private INTEGER DEFAULT "0"'); -} - -function version_30(PDO $pdo) -{ - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('application_date_format', 'm/d/Y')); -} - -function version_29(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE settings ( - option TEXT PRIMARY KEY, - value TEXT DEFAULT '' - ) - "); - - // Migrate old config parameters - $rq = $pdo->prepare('SELECT * FROM config'); - $rq->execute(); - $parameters = $rq->fetch(PDO::FETCH_ASSOC); - - $rq = $pdo->prepare('INSERT INTO settings VALUES (?, ?)'); - $rq->execute(array('board_highlight_period', defined('RECENT_TASK_PERIOD') ? RECENT_TASK_PERIOD : 48*60*60)); - $rq->execute(array('board_public_refresh_interval', defined('BOARD_PUBLIC_CHECK_INTERVAL') ? BOARD_PUBLIC_CHECK_INTERVAL : 60)); - $rq->execute(array('board_private_refresh_interval', defined('BOARD_CHECK_INTERVAL') ? BOARD_CHECK_INTERVAL : 10)); - $rq->execute(array('board_columns', $parameters['default_columns'])); - $rq->execute(array('webhook_url_task_creation', $parameters['webhooks_url_task_creation'])); - $rq->execute(array('webhook_url_task_modification', $parameters['webhooks_url_task_modification'])); - $rq->execute(array('webhook_token', $parameters['webhooks_token'])); - $rq->execute(array('api_token', $parameters['api_token'])); - $rq->execute(array('application_language', $parameters['language'])); - $rq->execute(array('application_timezone', $parameters['timezone'])); - $rq->execute(array('application_url', defined('KANBOARD_URL') ? KANBOARD_URL : '')); - - $pdo->exec('DROP TABLE config'); -} - -function version_28(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN reference TEXT DEFAULT ''"); - $pdo->exec("ALTER TABLE comments ADD COLUMN reference TEXT DEFAULT ''"); - - $pdo->exec('CREATE INDEX tasks_reference_idx ON tasks(reference)'); - $pdo->exec('CREATE INDEX comments_reference_idx ON comments(reference)'); -} - -function version_27(PDO $pdo) -{ - $pdo->exec('CREATE UNIQUE INDEX users_username_idx ON users(username)'); -} - -function version_26(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN default_columns TEXT DEFAULT ''"); -} - -function version_25(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_events ( - id INTEGER PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name TEXT NOT NULL, - creator_id INTEGER, - project_id INTEGER, - task_id INTEGER, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - "); - - $pdo->exec(" - CREATE TABLE subtask_has_events ( - id INTEGER PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name TEXT NOT NULL, - creator_id INTEGER, - project_id INTEGER, - subtask_id INTEGER, - task_id INTEGER, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(subtask_id) REFERENCES task_has_subtasks(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - "); - - $pdo->exec(" - CREATE TABLE comment_has_events ( - id INTEGER PRIMARY KEY, - date_creation INTEGER NOT NULL, - event_name TEXT NOT NULL, - creator_id INTEGER, - project_id INTEGER, - comment_id INTEGER, - task_id INTEGER, - data TEXT, - FOREIGN KEY(creator_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(comment_id) REFERENCES comments(id) ON DELETE CASCADE, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - ); - "); -} - -function version_24(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects ADD COLUMN is_public INTEGER DEFAULT "0"'); -} - -function version_23(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN notifications_enabled INTEGER DEFAULT '0'"); - - $pdo->exec(" - CREATE TABLE user_has_notifications ( - user_id INTEGER NOT NULL, - project_id INTEGER NOT NULL, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE(project_id, user_id) - ); - "); -} - -function version_22(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_modification TEXT"); - $pdo->exec("ALTER TABLE config ADD COLUMN webhooks_url_task_creation TEXT"); -} - -function version_21(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN creator_id INTEGER DEFAULT '0'"); - $pdo->exec("ALTER TABLE tasks ADD COLUMN date_modification INTEGER DEFAULT '0'"); -} - -function version_20(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN github_id TEXT"); -} - -function version_19(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN api_token TEXT DEFAULT ''"); - $pdo->exec("UPDATE config SET api_token='".Token::getToken()."'"); -} - -function version_18(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_subtasks ( - id INTEGER PRIMARY KEY, - title TEXT COLLATE NOCASE NOT NULL, - status INTEGER DEFAULT 0, - time_estimated NUMERIC DEFAULT 0, - time_spent NUMERIC DEFAULT 0, - task_id INTEGER NOT NULL, - user_id INTEGER, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - )" - ); -} - -function version_17(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE task_has_files ( - id INTEGER PRIMARY KEY, - name TEXT COLLATE NOCASE NOT NULL, - path TEXT, - is_image INTEGER DEFAULT 0, - task_id INTEGER NOT NULL, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE - )" - ); -} - -function version_16(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_categories ( - id INTEGER PRIMARY KEY, - name TEXT COLLATE NOCASE NOT NULL, - project_id INTEGER NOT NULL, - UNIQUE (project_id, name), - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - )" - ); - - $pdo->exec("ALTER TABLE tasks ADD COLUMN category_id INTEGER DEFAULT 0"); -} - -function version_15(PDO $pdo) -{ - $pdo->exec("ALTER TABLE projects ADD COLUMN last_modified INTEGER DEFAULT 0"); -} - -function version_14(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN name TEXT"); - $pdo->exec("ALTER TABLE users ADD COLUMN email TEXT"); - $pdo->exec("ALTER TABLE users ADD COLUMN google_id TEXT"); -} - -function version_13(PDO $pdo) -{ - $pdo->exec("ALTER TABLE users ADD COLUMN is_ldap_user INTEGER DEFAULT 0"); -} - -function version_12(PDO $pdo) -{ - $pdo->exec( - 'CREATE TABLE remember_me ( - id INTEGER PRIMARY KEY, - user_id INTEGER NOT NULL, - ip TEXT, - user_agent TEXT, - token TEXT, - sequence TEXT, - expiration INTEGER, - date_creation INTEGER, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - )' - ); - - $pdo->exec( - 'CREATE TABLE last_logins ( - id INTEGER PRIMARY KEY, - auth_type TEXT, - user_id INTEGER NOT NULL, - ip TEXT, - user_agent TEXT, - date_creation INTEGER, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - )' - ); - - $pdo->exec('CREATE INDEX last_logins_user_idx ON last_logins(user_id)'); -} - -function version_11(PDO $pdo) -{ - $pdo->exec( - 'ALTER TABLE comments RENAME TO comments_bak' - ); - - $pdo->exec( - 'CREATE TABLE comments ( - id INTEGER PRIMARY KEY, - task_id INTEGER, - user_id INTEGER, - date INTEGER, - comment TEXT, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE - )' - ); - - $pdo->exec( - 'INSERT INTO comments SELECT * FROM comments_bak' - ); - - $pdo->exec( - 'DROP TABLE comments_bak' - ); -} - -function version_10(PDO $pdo) -{ - $pdo->exec( - 'CREATE TABLE actions ( - id INTEGER PRIMARY KEY, - project_id INTEGER NOT NULL, - event_name TEXT NOT NULL, - action_name TEXT NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE - )' - ); - - $pdo->exec( - 'CREATE TABLE action_has_params ( - id INTEGER PRIMARY KEY, - action_id INTEGER NOT NULL, - name TEXT NOT NULL, - value TEXT NOT NULL, - FOREIGN KEY(action_id) REFERENCES actions(id) ON DELETE CASCADE - )' - ); -} - -function version_9(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN date_due INTEGER"); -} - -function version_8(PDO $pdo) -{ - $pdo->exec( - 'CREATE TABLE comments ( - id INTEGER PRIMARY KEY, - task_id INTEGER, - user_id INTEGER, - date INTEGER, - comment TEXT, - FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES tasks(id) ON DELETE CASCADE - )' - ); -} - -function version_7(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE project_has_users ( - project_id INTEGER NOT NULL, - user_id INTEGER NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE, - UNIQUE(project_id, user_id) - ) - "); -} - -function version_6(PDO $pdo) -{ - $pdo->exec("ALTER TABLE columns ADD COLUMN task_limit INTEGER DEFAULT '0'"); -} - -function version_5(PDO $pdo) -{ - $pdo->exec("ALTER TABLE tasks ADD COLUMN score INTEGER"); -} - -function version_4(PDO $pdo) -{ - $pdo->exec("ALTER TABLE config ADD COLUMN timezone TEXT DEFAULT 'UTC'"); -} - -function version_3(PDO $pdo) -{ - $pdo->exec('ALTER TABLE projects ADD COLUMN token TEXT'); -} - -function version_2(PDO $pdo) -{ - $pdo->exec('ALTER TABLE tasks ADD COLUMN date_completed INTEGER'); - $pdo->exec('UPDATE tasks SET date_completed=date_creation WHERE is_active=0'); -} - -function version_1(PDO $pdo) -{ - $pdo->exec(" - CREATE TABLE config ( - language TEXT DEFAULT 'en_US', - webhooks_token TEXT DEFAULT '' - ) - "); - - $pdo->exec(" - CREATE TABLE users ( - id INTEGER PRIMARY KEY, - username TEXT NOT NULL, - password TEXT, - is_admin INTEGER DEFAULT 0 - ) - "); - - $pdo->exec(" - CREATE TABLE projects ( - id INTEGER PRIMARY KEY, - name TEXT NOCASE NOT NULL, - is_active INTEGER DEFAULT 1 - ) - "); - - $pdo->exec(" - CREATE TABLE columns ( - id INTEGER PRIMARY KEY, - title TEXT NOT NULL, - position INTEGER, - project_id INTEGER NOT NULL, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - UNIQUE (title, project_id) - ) - "); - - $pdo->exec(" - CREATE TABLE tasks ( - id INTEGER PRIMARY KEY, - title TEXT NOCASE NOT NULL, - description TEXT, - date_creation INTEGER, - color_id TEXT, - project_id INTEGER, - column_id INTEGER, - owner_id INTEGER DEFAULT '0', - position INTEGER, - is_active INTEGER DEFAULT 1, - FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, - FOREIGN KEY(column_id) REFERENCES columns(id) ON DELETE CASCADE - ) - "); - - $pdo->exec(" - INSERT INTO users - (username, password, is_admin) - VALUES ('admin', '".\password_hash('admin', PASSWORD_BCRYPT)."', '1') - "); - - $pdo->exec(" - INSERT INTO config - (webhooks_token) - VALUES ('".Token::getToken()."') - "); -} diff --git a/sources/app/ServiceProvider/ActionProvider.php b/sources/app/ServiceProvider/ActionProvider.php deleted file mode 100644 index 3420205..0000000 --- a/sources/app/ServiceProvider/ActionProvider.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Kanboard\Action\TaskAssignColorPriority; -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\Action\ActionManager; -use Kanboard\Action\CommentCreation; -use Kanboard\Action\CommentCreationMoveTaskColumn; -use Kanboard\Action\TaskAssignCategoryColor; -use Kanboard\Action\TaskAssignCategoryLabel; -use Kanboard\Action\TaskAssignCategoryLink; -use Kanboard\Action\TaskAssignColorCategory; -use Kanboard\Action\TaskAssignColorColumn; -use Kanboard\Action\TaskAssignColorLink; -use Kanboard\Action\TaskAssignColorUser; -use Kanboard\Action\TaskAssignCurrentUser; -use Kanboard\Action\TaskAssignCurrentUserColumn; -use Kanboard\Action\TaskAssignSpecificUser; -use Kanboard\Action\TaskAssignUser; -use Kanboard\Action\TaskClose; -use Kanboard\Action\TaskCloseColumn; -use Kanboard\Action\TaskCreation; -use Kanboard\Action\TaskDuplicateAnotherProject; -use Kanboard\Action\TaskEmail; -use Kanboard\Action\TaskEmailNoActivity; -use Kanboard\Action\TaskMoveAnotherProject; -use Kanboard\Action\TaskMoveColumnAssigned; -use Kanboard\Action\TaskMoveColumnCategoryChange; -use Kanboard\Action\TaskMoveColumnUnAssigned; -use Kanboard\Action\TaskOpen; -use Kanboard\Action\TaskUpdateStartDate; -use Kanboard\Action\TaskCloseNoActivity; - -/** - * Action Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class ActionProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['actionManager'] = new ActionManager($container); - $container['actionManager']->register(new CommentCreation($container)); - $container['actionManager']->register(new CommentCreationMoveTaskColumn($container)); - $container['actionManager']->register(new TaskAssignCategoryColor($container)); - $container['actionManager']->register(new TaskAssignCategoryLabel($container)); - $container['actionManager']->register(new TaskAssignCategoryLink($container)); - $container['actionManager']->register(new TaskAssignColorCategory($container)); - $container['actionManager']->register(new TaskAssignColorColumn($container)); - $container['actionManager']->register(new TaskAssignColorLink($container)); - $container['actionManager']->register(new TaskAssignColorUser($container)); - $container['actionManager']->register(new TaskAssignColorPriority($container)); - $container['actionManager']->register(new TaskAssignCurrentUser($container)); - $container['actionManager']->register(new TaskAssignCurrentUserColumn($container)); - $container['actionManager']->register(new TaskAssignSpecificUser($container)); - $container['actionManager']->register(new TaskAssignUser($container)); - $container['actionManager']->register(new TaskClose($container)); - $container['actionManager']->register(new TaskCloseColumn($container)); - $container['actionManager']->register(new TaskCloseNoActivity($container)); - $container['actionManager']->register(new TaskCreation($container)); - $container['actionManager']->register(new TaskDuplicateAnotherProject($container)); - $container['actionManager']->register(new TaskEmail($container)); - $container['actionManager']->register(new TaskEmailNoActivity($container)); - $container['actionManager']->register(new TaskMoveAnotherProject($container)); - $container['actionManager']->register(new TaskMoveColumnAssigned($container)); - $container['actionManager']->register(new TaskMoveColumnCategoryChange($container)); - $container['actionManager']->register(new TaskMoveColumnUnAssigned($container)); - $container['actionManager']->register(new TaskOpen($container)); - $container['actionManager']->register(new TaskUpdateStartDate($container)); - - return $container; - } -} diff --git a/sources/app/ServiceProvider/ApiProvider.php b/sources/app/ServiceProvider/ApiProvider.php deleted file mode 100644 index 5cf6231..0000000 --- a/sources/app/ServiceProvider/ApiProvider.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use JsonRPC\Server; -use Kanboard\Api\Procedure\ActionProcedure; -use Kanboard\Api\Procedure\AppProcedure; -use Kanboard\Api\Procedure\BoardProcedure; -use Kanboard\Api\Procedure\CategoryProcedure; -use Kanboard\Api\Procedure\ColumnProcedure; -use Kanboard\Api\Procedure\CommentProcedure; -use Kanboard\Api\Procedure\ProjectFileProcedure; -use Kanboard\Api\Procedure\TaskExternalLinkProcedure; -use Kanboard\Api\Procedure\TaskFileProcedure; -use Kanboard\Api\Procedure\GroupProcedure; -use Kanboard\Api\Procedure\GroupMemberProcedure; -use Kanboard\Api\Procedure\LinkProcedure; -use Kanboard\Api\Procedure\MeProcedure; -use Kanboard\Api\Middleware\AuthenticationMiddleware; -use Kanboard\Api\Procedure\ProjectProcedure; -use Kanboard\Api\Procedure\ProjectPermissionProcedure; -use Kanboard\Api\Procedure\SubtaskProcedure; -use Kanboard\Api\Procedure\SubtaskTimeTrackingProcedure; -use Kanboard\Api\Procedure\SwimlaneProcedure; -use Kanboard\Api\Procedure\TaskProcedure; -use Kanboard\Api\Procedure\TaskLinkProcedure; -use Kanboard\Api\Procedure\UserProcedure; -use Pimple\Container; -use Pimple\ServiceProviderInterface; - -/** - * Class ApiProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class ApiProvider implements ServiceProviderInterface -{ - /** - * Registers services on the given container. - * - * @param Container $container - * @return Container - */ - public function register(Container $container) - { - $server = new Server(); - $server->setAuthenticationHeader(API_AUTHENTICATION_HEADER); - $server->getMiddlewareHandler() - ->withMiddleware(new AuthenticationMiddleware($container)) - ; - - $server->getProcedureHandler() - ->withObject(new MeProcedure($container)) - ->withObject(new ActionProcedure($container)) - ->withObject(new AppProcedure($container)) - ->withObject(new BoardProcedure($container)) - ->withObject(new ColumnProcedure($container)) - ->withObject(new CategoryProcedure($container)) - ->withObject(new CommentProcedure($container)) - ->withObject(new TaskFileProcedure($container)) - ->withObject(new ProjectFileProcedure($container)) - ->withObject(new LinkProcedure($container)) - ->withObject(new ProjectProcedure($container)) - ->withObject(new ProjectPermissionProcedure($container)) - ->withObject(new SubtaskProcedure($container)) - ->withObject(new SubtaskTimeTrackingProcedure($container)) - ->withObject(new SwimlaneProcedure($container)) - ->withObject(new TaskProcedure($container)) - ->withObject(new TaskLinkProcedure($container)) - ->withObject(new TaskExternalLinkProcedure($container)) - ->withObject(new UserProcedure($container)) - ->withObject(new GroupProcedure($container)) - ->withObject(new GroupMemberProcedure($container)) - ->withBeforeMethod('beforeProcedure') - ; - - $container['api'] = $server; - return $container; - } -} diff --git a/sources/app/ServiceProvider/AuthenticationProvider.php b/sources/app/ServiceProvider/AuthenticationProvider.php deleted file mode 100644 index 978bc05..0000000 --- a/sources/app/ServiceProvider/AuthenticationProvider.php +++ /dev/null @@ -1,213 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\Security\AuthenticationManager; -use Kanboard\Core\Security\AccessMap; -use Kanboard\Core\Security\Authorization; -use Kanboard\Core\Security\Role; -use Kanboard\Auth\RememberMeAuth; -use Kanboard\Auth\DatabaseAuth; -use Kanboard\Auth\LdapAuth; -use Kanboard\Auth\TotpAuth; -use Kanboard\Auth\ReverseProxyAuth; - -/** - * Authentication Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class AuthenticationProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['authenticationManager'] = new AuthenticationManager($container); - $container['authenticationManager']->register(new TotpAuth($container)); - $container['authenticationManager']->register(new RememberMeAuth($container)); - $container['authenticationManager']->register(new DatabaseAuth($container)); - - if (REVERSE_PROXY_AUTH) { - $container['authenticationManager']->register(new ReverseProxyAuth($container)); - } - - if (LDAP_AUTH) { - $container['authenticationManager']->register(new LdapAuth($container)); - } - - $container['projectAccessMap'] = $this->getProjectAccessMap(); - $container['applicationAccessMap'] = $this->getApplicationAccessMap(); - $container['apiAccessMap'] = $this->getApiAccessMap(); - $container['apiProjectAccessMap'] = $this->getApiProjectAccessMap(); - - $container['projectAuthorization'] = new Authorization($container['projectAccessMap']); - $container['applicationAuthorization'] = new Authorization($container['applicationAccessMap']); - $container['apiAuthorization'] = new Authorization($container['apiAccessMap']); - $container['apiProjectAuthorization'] = new Authorization($container['apiProjectAccessMap']); - - return $container; - } - - /** - * Get ACL for projects - * - * @access public - * @return AccessMap - */ - public function getProjectAccessMap() - { - $acl = new AccessMap; - $acl->setDefaultRole(Role::PROJECT_VIEWER); - $acl->setRoleHierarchy(Role::PROJECT_MANAGER, array(Role::PROJECT_MEMBER, Role::PROJECT_VIEWER)); - $acl->setRoleHierarchy(Role::PROJECT_MEMBER, array(Role::PROJECT_VIEWER)); - - $acl->add('ActionController', '*', Role::PROJECT_MANAGER); - $acl->add('ProjectActionDuplicationController', '*', Role::PROJECT_MANAGER); - $acl->add('ActionCreationController', '*', Role::PROJECT_MANAGER); - $acl->add('AnalyticController', '*', Role::PROJECT_MANAGER); - $acl->add('BoardAjaxController', 'save', Role::PROJECT_MEMBER); - $acl->add('BoardPopoverController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskPopoverController', '*', Role::PROJECT_MEMBER); - $acl->add('CalendarController', 'save', Role::PROJECT_MEMBER); - $acl->add('CategoryController', '*', Role::PROJECT_MANAGER); - $acl->add('ColumnController', '*', Role::PROJECT_MANAGER); - $acl->add('CommentController', '*', Role::PROJECT_MEMBER); - $acl->add('CustomFilterController', '*', Role::PROJECT_MEMBER); - $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); - $acl->add('ProjectFileController', '*', Role::PROJECT_MEMBER); - $acl->add('ProjectUserOverviewController', '*', Role::PROJECT_MANAGER); - $acl->add('ProjectStatusController', '*', Role::PROJECT_MANAGER); - $acl->add('ProjectTagController', '*', Role::PROJECT_MANAGER); - $acl->add('SubtaskController', '*', Role::PROJECT_MEMBER); - $acl->add('SubtaskRestrictionController', '*', Role::PROJECT_MEMBER); - $acl->add('SubtaskStatusController', '*', Role::PROJECT_MEMBER); - $acl->add('SwimlaneController', '*', Role::PROJECT_MANAGER); - $acl->add('TaskSuppressionController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskCreationController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskBulkController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskDuplicationController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskRecurrenceController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskImportController', '*', Role::PROJECT_MANAGER); - $acl->add('TaskInternalLinkController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskExternalLinkController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskModificationController', '*', Role::PROJECT_MEMBER); - $acl->add('TaskStatusController', '*', Role::PROJECT_MEMBER); - $acl->add('UserAjaxController', array('mention'), Role::PROJECT_MEMBER); - - return $acl; - } - - /** - * Get ACL for the application - * - * @access public - * @return AccessMap - */ - public function getApplicationAccessMap() - { - $acl = new AccessMap; - $acl->setDefaultRole(Role::APP_USER); - $acl->setRoleHierarchy(Role::APP_ADMIN, array(Role::APP_MANAGER, Role::APP_USER, Role::APP_PUBLIC)); - $acl->setRoleHierarchy(Role::APP_MANAGER, array(Role::APP_USER, Role::APP_PUBLIC)); - $acl->setRoleHierarchy(Role::APP_USER, array(Role::APP_PUBLIC)); - - $acl->add('AuthController', array('login', 'check'), Role::APP_PUBLIC); - $acl->add('CaptchaController', '*', Role::APP_PUBLIC); - $acl->add('PasswordResetController', '*', Role::APP_PUBLIC); - $acl->add('TaskViewController', 'readonly', Role::APP_PUBLIC); - $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('ConfigController', '*', Role::APP_ADMIN); - $acl->add('TagController', '*', Role::APP_ADMIN); - $acl->add('PluginController', '*', Role::APP_ADMIN); - $acl->add('CurrencyController', '*', Role::APP_ADMIN); - $acl->add('ProjectGanttController', '*', Role::APP_MANAGER); - $acl->add('GroupListController', '*', Role::APP_ADMIN); - $acl->add('GroupCreationController', '*', Role::APP_ADMIN); - $acl->add('GroupModificationController', '*', Role::APP_ADMIN); - $acl->add('LinkController', '*', Role::APP_ADMIN); - $acl->add('ProjectCreationController', 'create', Role::APP_MANAGER); - $acl->add('ProjectUserOverviewController', '*', Role::APP_MANAGER); - $acl->add('TwoFactorController', 'disable', Role::APP_ADMIN); - $acl->add('UserImportController', '*', Role::APP_ADMIN); - $acl->add('UserCreationController', '*', Role::APP_ADMIN); - $acl->add('UserListController', '*', Role::APP_ADMIN); - $acl->add('UserStatusController', '*', Role::APP_ADMIN); - $acl->add('UserCredentialController', array('changeAuthentication', 'saveAuthentication'), Role::APP_ADMIN); - - return $acl; - } - - /** - * Get ACL for the API - * - * @access public - * @return AccessMap - */ - public function getApiAccessMap() - { - $acl = new AccessMap; - $acl->setDefaultRole(Role::APP_USER); - $acl->setRoleHierarchy(Role::APP_ADMIN, array(Role::APP_MANAGER, Role::APP_USER, Role::APP_PUBLIC)); - $acl->setRoleHierarchy(Role::APP_MANAGER, array(Role::APP_USER, Role::APP_PUBLIC)); - - $acl->add('UserProcedure', '*', Role::APP_ADMIN); - $acl->add('GroupMemberProcedure', '*', Role::APP_ADMIN); - $acl->add('GroupProcedure', '*', Role::APP_ADMIN); - $acl->add('LinkProcedure', '*', Role::APP_ADMIN); - $acl->add('TaskProcedure', array('getOverdueTasks'), Role::APP_ADMIN); - $acl->add('ProjectProcedure', array('getAllProjects'), Role::APP_ADMIN); - $acl->add('ProjectProcedure', array('createProject'), Role::APP_MANAGER); - - return $acl; - } - - /** - * Get ACL for the API - * - * @access public - * @return AccessMap - */ - public function getApiProjectAccessMap() - { - $acl = new AccessMap; - $acl->setDefaultRole(Role::PROJECT_VIEWER); - $acl->setRoleHierarchy(Role::PROJECT_MANAGER, array(Role::PROJECT_MEMBER, Role::PROJECT_VIEWER)); - $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('CommentProcedure', array('removeComment', 'createComment', 'updateComment'), Role::PROJECT_MEMBER); - $acl->add('ProjectPermissionProcedure', '*', 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('TaskExternalLinkProcedure', array('createExternalTaskLink', 'updateExternalTaskLink', 'removeExternalTaskLink'), Role::PROJECT_MEMBER); - $acl->add('TaskProcedure', '*', Role::PROJECT_MEMBER); - - return $acl; - } -} diff --git a/sources/app/ServiceProvider/AvatarProvider.php b/sources/app/ServiceProvider/AvatarProvider.php deleted file mode 100644 index d17985e..0000000 --- a/sources/app/ServiceProvider/AvatarProvider.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\User\Avatar\AvatarManager; -use Kanboard\User\Avatar\GravatarProvider; -use Kanboard\User\Avatar\AvatarFileProvider; -use Kanboard\User\Avatar\LetterAvatarProvider; - -/** - * Avatar Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class AvatarProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['avatarManager'] = new AvatarManager; - $container['avatarManager']->register(new LetterAvatarProvider($container)); - $container['avatarManager']->register(new GravatarProvider($container)); - $container['avatarManager']->register(new AvatarFileProvider($container)); - return $container; - } -} diff --git a/sources/app/ServiceProvider/ClassProvider.php b/sources/app/ServiceProvider/ClassProvider.php deleted file mode 100644 index e32c0d4..0000000 --- a/sources/app/ServiceProvider/ClassProvider.php +++ /dev/null @@ -1,180 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\ObjectStorage\FileStorage; -use Kanboard\Core\Paginator; -use Kanboard\Core\Http\OAuth2; -use Kanboard\Core\Tool; -use Kanboard\Core\Http\Client as HttpClient; - -/** - * Class ClassProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class ClassProvider implements ServiceProviderInterface -{ - private $classes = array( - 'Analytic' => array( - 'TaskDistributionAnalytic', - 'UserDistributionAnalytic', - 'EstimatedTimeComparisonAnalytic', - 'AverageLeadCycleTimeAnalytic', - 'AverageTimeSpentColumnAnalytic', - ), - 'Model' => array( - 'ActionModel', - 'ActionParameterModel', - 'AvatarFileModel', - 'BoardModel', - 'CategoryModel', - 'ColorModel', - 'ColumnModel', - 'CommentModel', - 'ConfigModel', - 'CurrencyModel', - 'CustomFilterModel', - 'GroupModel', - 'GroupMemberModel', - 'LanguageModel', - 'LastLoginModel', - 'LinkModel', - 'NotificationModel', - 'PasswordResetModel', - 'ProjectModel', - 'ProjectFileModel', - 'ProjectActivityModel', - 'ProjectDuplicationModel', - 'ProjectDailyColumnStatsModel', - 'ProjectDailyStatsModel', - 'ProjectPermissionModel', - 'ProjectNotificationModel', - 'ProjectMetadataModel', - 'ProjectGroupRoleModel', - 'ProjectTaskDuplicationModel', - 'ProjectTaskPriorityModel', - 'ProjectUserRoleModel', - 'RememberMeSessionModel', - 'SubtaskModel', - 'SubtaskTimeTrackingModel', - 'SwimlaneModel', - 'TagDuplicationModel', - 'TagModel', - 'TaskModel', - 'TaskAnalyticModel', - 'TaskCreationModel', - 'TaskDuplicationModel', - 'TaskProjectDuplicationModel', - 'TaskProjectMoveModel', - 'TaskRecurrenceModel', - 'TaskExternalLinkModel', - 'TaskFinderModel', - 'TaskFileModel', - 'TaskLinkModel', - 'TaskModificationModel', - 'TaskPositionModel', - 'TaskStatusModel', - 'TaskTagModel', - 'TaskMetadataModel', - 'TimezoneModel', - 'TransitionModel', - 'UserModel', - 'UserLockingModel', - 'UserMentionModel', - 'UserNotificationModel', - 'UserNotificationFilterModel', - 'UserUnreadNotificationModel', - 'UserMetadataModel', - ), - 'Validator' => array( - 'ActionValidator', - 'AuthValidator', - 'CategoryValidator', - 'ColumnValidator', - 'CommentValidator', - 'CurrencyValidator', - 'CustomFilterValidator', - 'ExternalLinkValidator', - 'GroupValidator', - 'LinkValidator', - 'PasswordResetValidator', - 'ProjectValidator', - 'SubtaskValidator', - 'SwimlaneValidator', - 'TagValidator', - 'TaskLinkValidator', - 'TaskValidator', - 'UserValidator', - ), - 'Import' => array( - 'TaskImport', - 'UserImport', - ), - 'Export' => array( - 'SubtaskExport', - 'TaskExport', - 'TransitionExport', - ), - 'Core' => array( - 'DateParser', - 'Lexer', - ), - 'Core\Event' => array( - 'EventManager', - ), - 'Core\Http' => array( - 'Request', - 'Response', - 'RememberMeCookie', - ), - 'Core\Cache' => array( - 'MemoryCache', - ), - 'Core\Plugin' => array( - 'Hook', - ), - 'Core\Security' => array( - 'Token', - 'Role', - ), - 'Core\User' => array( - 'GroupSync', - 'UserSync', - 'UserSession', - 'UserProfile', - ) - ); - - public function register(Container $container) - { - Tool::buildDIC($container, $this->classes); - - $container['paginator'] = $container->factory(function ($c) { - return new Paginator($c); - }); - - $container['oauth'] = $container->factory(function ($c) { - return new OAuth2($c); - }); - - $container['httpClient'] = function ($c) { - return new HttpClient($c); - }; - - $container['objectStorage'] = function () { - return new FileStorage(FILES_DIR); - }; - - $container['cspRules'] = array( - 'default-src' => "'self'", - 'style-src' => "'self' 'unsafe-inline'", - 'img-src' => '* data:', - ); - - return $container; - } -} diff --git a/sources/app/ServiceProvider/CommandProvider.php b/sources/app/ServiceProvider/CommandProvider.php deleted file mode 100644 index 55c2712..0000000 --- a/sources/app/ServiceProvider/CommandProvider.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Kanboard\Console\CronjobCommand; -use Kanboard\Console\LocaleComparatorCommand; -use Kanboard\Console\LocaleSyncCommand; -use Kanboard\Console\PluginInstallCommand; -use Kanboard\Console\PluginUninstallCommand; -use Kanboard\Console\PluginUpgradeCommand; -use Kanboard\Console\ProjectDailyColumnStatsExportCommand; -use Kanboard\Console\ProjectDailyStatsCalculationCommand; -use Kanboard\Console\ResetPasswordCommand; -use Kanboard\Console\ResetTwoFactorCommand; -use Kanboard\Console\SubtaskExportCommand; -use Kanboard\Console\TaskExportCommand; -use Kanboard\Console\TaskOverdueNotificationCommand; -use Kanboard\Console\TaskTriggerCommand; -use Kanboard\Console\TransitionExportCommand; -use Kanboard\Console\WorkerCommand; -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Symfony\Component\Console\Application; - -/** - * Class CommandProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class CommandProvider implements ServiceProviderInterface -{ - /** - * Registers services on the given container. - * - * @param Container $container - * @return Container - */ - public function register(Container $container) - { - $application = new Application('Kanboard', APP_VERSION); - $application->add(new TaskOverdueNotificationCommand($container)); - $application->add(new SubtaskExportCommand($container)); - $application->add(new TaskExportCommand($container)); - $application->add(new ProjectDailyStatsCalculationCommand($container)); - $application->add(new ProjectDailyColumnStatsExportCommand($container)); - $application->add(new TransitionExportCommand($container)); - $application->add(new LocaleSyncCommand($container)); - $application->add(new LocaleComparatorCommand($container)); - $application->add(new TaskTriggerCommand($container)); - $application->add(new CronjobCommand($container)); - $application->add(new WorkerCommand($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)); - - $container['cli'] = $application; - return $container; - } -} diff --git a/sources/app/ServiceProvider/DatabaseProvider.php b/sources/app/ServiceProvider/DatabaseProvider.php deleted file mode 100644 index a3f5745..0000000 --- a/sources/app/ServiceProvider/DatabaseProvider.php +++ /dev/null @@ -1,129 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use LogicException; -use RuntimeException; -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use PicoDb\Database; - -/** - * Class DatabaseProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class DatabaseProvider implements ServiceProviderInterface -{ - /** - * Register provider - * - * @access public - * @param Container $container - * @return Container - */ - public function register(Container $container) - { - $container['db'] = $this->getInstance(); - - if (DEBUG) { - $container['db']->getStatementHandler() - ->withLogging() - ->withStopWatch() - ; - } - - return $container; - } - - /** - * Setup the database driver and execute schema migration - * - * @access public - * @return \PicoDb\Database - */ - public function getInstance() - { - switch (DB_DRIVER) { - case 'sqlite': - $db = $this->getSqliteInstance(); - break; - case 'mysql': - $db = $this->getMysqlInstance(); - break; - case 'postgres': - $db = $this->getPostgresInstance(); - break; - default: - throw new LogicException('Database driver not supported'); - } - - if ($db->schema()->check(\Schema\VERSION)) { - return $db; - } else { - $messages = $db->getLogMessages(); - throw new RuntimeException('Unable to run SQL migrations: '.implode(', ', $messages).' (You may have to fix it manually)'); - } - } - - /** - * Setup the Sqlite database driver - * - * @access private - * @return \PicoDb\Database - */ - private function getSqliteInstance() - { - require_once __DIR__.'/../Schema/Sqlite.php'; - - return new Database(array( - 'driver' => 'sqlite', - 'filename' => DB_FILENAME - )); - } - - /** - * Setup the Mysql database driver - * - * @access private - * @return \PicoDb\Database - */ - private function getMysqlInstance() - { - require_once __DIR__.'/../Schema/Mysql.php'; - - return new Database(array( - 'driver' => 'mysql', - 'hostname' => DB_HOSTNAME, - 'username' => DB_USERNAME, - 'password' => DB_PASSWORD, - 'database' => DB_NAME, - 'charset' => 'utf8', - 'port' => DB_PORT, - 'ssl_key' => DB_SSL_KEY, - 'ssl_ca' => DB_SSL_CA, - 'ssl_cert' => DB_SSL_CERT, - )); - } - - /** - * Setup the Postgres database driver - * - * @access private - * @return \PicoDb\Database - */ - private function getPostgresInstance() - { - require_once __DIR__.'/../Schema/Postgres.php'; - - return new Database(array( - 'driver' => 'postgres', - 'hostname' => DB_HOSTNAME, - 'username' => DB_USERNAME, - 'password' => DB_PASSWORD, - 'database' => DB_NAME, - 'port' => DB_PORT, - )); - } -} diff --git a/sources/app/ServiceProvider/EventDispatcherProvider.php b/sources/app/ServiceProvider/EventDispatcherProvider.php deleted file mode 100644 index 57543fe..0000000 --- a/sources/app/ServiceProvider/EventDispatcherProvider.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Kanboard\Subscriber\LdapUserPhotoSubscriber; -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Symfony\Component\EventDispatcher\EventDispatcher; -use Kanboard\Subscriber\AuthSubscriber; -use Kanboard\Subscriber\BootstrapSubscriber; -use Kanboard\Subscriber\NotificationSubscriber; -use Kanboard\Subscriber\ProjectDailySummarySubscriber; -use Kanboard\Subscriber\ProjectModificationDateSubscriber; -use Kanboard\Subscriber\SubtaskTimeTrackingSubscriber; -use Kanboard\Subscriber\TransitionSubscriber; -use Kanboard\Subscriber\RecurringTaskSubscriber; - -/** - * Class EventDispatcherProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class EventDispatcherProvider implements ServiceProviderInterface -{ - public function register(Container $container) - { - $container['dispatcher'] = new EventDispatcher; - $container['dispatcher']->addSubscriber(new BootstrapSubscriber($container)); - $container['dispatcher']->addSubscriber(new AuthSubscriber($container)); - $container['dispatcher']->addSubscriber(new ProjectDailySummarySubscriber($container)); - $container['dispatcher']->addSubscriber(new ProjectModificationDateSubscriber($container)); - $container['dispatcher']->addSubscriber(new NotificationSubscriber($container)); - $container['dispatcher']->addSubscriber(new SubtaskTimeTrackingSubscriber($container)); - $container['dispatcher']->addSubscriber(new TransitionSubscriber($container)); - $container['dispatcher']->addSubscriber(new RecurringTaskSubscriber($container)); - - if (LDAP_AUTH && LDAP_USER_ATTRIBUTE_PHOTO !== '') { - $container['dispatcher']->addSubscriber(new LdapUserPhotoSubscriber($container)); - } - - return $container; - } -} diff --git a/sources/app/ServiceProvider/ExternalLinkProvider.php b/sources/app/ServiceProvider/ExternalLinkProvider.php deleted file mode 100644 index 2cec768..0000000 --- a/sources/app/ServiceProvider/ExternalLinkProvider.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\ExternalLink\ExternalLinkManager; -use Kanboard\ExternalLink\WebLinkProvider; -use Kanboard\ExternalLink\AttachmentLinkProvider; -use Kanboard\ExternalLink\FileLinkProvider; - -/** - * External Link Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class ExternalLinkProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['externalLinkManager'] = new ExternalLinkManager($container); - $container['externalLinkManager']->register(new WebLinkProvider($container)); - $container['externalLinkManager']->register(new AttachmentLinkProvider($container)); - $container['externalLinkManager']->register(new FileLinkProvider($container)); - - return $container; - } -} diff --git a/sources/app/ServiceProvider/FilterProvider.php b/sources/app/ServiceProvider/FilterProvider.php deleted file mode 100644 index 20281a0..0000000 --- a/sources/app/ServiceProvider/FilterProvider.php +++ /dev/null @@ -1,178 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Kanboard\Core\Filter\LexerBuilder; -use Kanboard\Core\Filter\QueryBuilder; -use Kanboard\Filter\ProjectActivityCreationDateFilter; -use Kanboard\Filter\ProjectActivityCreatorFilter; -use Kanboard\Filter\ProjectActivityProjectNameFilter; -use Kanboard\Filter\ProjectActivityTaskStatusFilter; -use Kanboard\Filter\ProjectActivityTaskTitleFilter; -use Kanboard\Filter\TaskAssigneeFilter; -use Kanboard\Filter\TaskCategoryFilter; -use Kanboard\Filter\TaskColorFilter; -use Kanboard\Filter\TaskColumnFilter; -use Kanboard\Filter\TaskCommentFilter; -use Kanboard\Filter\TaskCreationDateFilter; -use Kanboard\Filter\TaskCreatorFilter; -use Kanboard\Filter\TaskDescriptionFilter; -use Kanboard\Filter\TaskDueDateFilter; -use Kanboard\Filter\TaskIdFilter; -use Kanboard\Filter\TaskLinkFilter; -use Kanboard\Filter\TaskModificationDateFilter; -use Kanboard\Filter\TaskProjectFilter; -use Kanboard\Filter\TaskReferenceFilter; -use Kanboard\Filter\TaskStatusFilter; -use Kanboard\Filter\TaskSubtaskAssigneeFilter; -use Kanboard\Filter\TaskSwimlaneFilter; -use Kanboard\Filter\TaskTagFilter; -use Kanboard\Filter\TaskTitleFilter; -use Kanboard\Model\ProjectModel; -use Kanboard\Model\ProjectGroupRoleModel; -use Kanboard\Model\ProjectUserRoleModel; -use Kanboard\Model\UserModel; -use Pimple\Container; -use Pimple\ServiceProviderInterface; - -/** - * Filter Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class FilterProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $this->createUserFilter($container); - $this->createProjectFilter($container); - $this->createTaskFilter($container); - return $container; - } - - public function createUserFilter(Container $container) - { - $container['userQuery'] = $container->factory(function ($c) { - $builder = new QueryBuilder(); - $builder->withQuery($c['db']->table(UserModel::TABLE)); - return $builder; - }); - - return $container; - } - - public function createProjectFilter(Container $container) - { - $container['projectGroupRoleQuery'] = $container->factory(function ($c) { - $builder = new QueryBuilder(); - $builder->withQuery($c['db']->table(ProjectGroupRoleModel::TABLE)); - return $builder; - }); - - $container['projectUserRoleQuery'] = $container->factory(function ($c) { - $builder = new QueryBuilder(); - $builder->withQuery($c['db']->table(ProjectUserRoleModel::TABLE)); - return $builder; - }); - - $container['projectQuery'] = $container->factory(function ($c) { - $builder = new QueryBuilder(); - $builder->withQuery($c['db']->table(ProjectModel::TABLE)); - return $builder; - }); - - $container['projectActivityLexer'] = $container->factory(function ($c) { - $builder = new LexerBuilder(); - $builder - ->withQuery($c['projectActivityModel']->getQuery()) - ->withFilter(new ProjectActivityTaskTitleFilter(), true) - ->withFilter(new ProjectActivityTaskStatusFilter()) - ->withFilter(new ProjectActivityProjectNameFilter()) - ->withFilter(ProjectActivityCreationDateFilter::getInstance() - ->setDateParser($c['dateParser']) - ) - ->withFilter(ProjectActivityCreatorFilter::getInstance() - ->setCurrentUserId($c['userSession']->getId()) - ) - ; - - return $builder; - }); - - $container['projectActivityQuery'] = $container->factory(function ($c) { - $builder = new QueryBuilder(); - $builder->withQuery($c['projectActivityModel']->getQuery()); - - return $builder; - }); - - return $container; - } - - public function createTaskFilter(Container $container) - { - $container['taskQuery'] = $container->factory(function ($c) { - $builder = new QueryBuilder(); - $builder->withQuery($c['taskFinderModel']->getExtendedQuery()); - return $builder; - }); - - $container['taskLexer'] = $container->factory(function ($c) { - $builder = new LexerBuilder(); - - $builder - ->withQuery($c['taskFinderModel']->getExtendedQuery()) - ->withFilter(TaskAssigneeFilter::getInstance() - ->setCurrentUserId($c['userSession']->getId()) - ) - ->withFilter(new TaskCategoryFilter()) - ->withFilter(TaskColorFilter::getInstance() - ->setColorModel($c['colorModel']) - ) - ->withFilter(new TaskColumnFilter()) - ->withFilter(new TaskCommentFilter()) - ->withFilter(TaskCreationDateFilter::getInstance() - ->setDateParser($c['dateParser']) - ) - ->withFilter(TaskCreatorFilter::getInstance() - ->setCurrentUserId($c['userSession']->getId()) - ) - ->withFilter(new TaskDescriptionFilter()) - ->withFilter(TaskDueDateFilter::getInstance() - ->setDateParser($c['dateParser']) - ) - ->withFilter(new TaskIdFilter()) - ->withFilter(TaskLinkFilter::getInstance() - ->setDatabase($c['db']) - ) - ->withFilter(TaskModificationDateFilter::getInstance() - ->setDateParser($c['dateParser']) - ) - ->withFilter(new TaskProjectFilter()) - ->withFilter(new TaskReferenceFilter()) - ->withFilter(new TaskStatusFilter()) - ->withFilter(TaskSubtaskAssigneeFilter::getInstance() - ->setCurrentUserId($c['userSession']->getId()) - ->setDatabase($c['db']) - ) - ->withFilter(new TaskSwimlaneFilter()) - ->withFilter(TaskTagFilter::getInstance() - ->setDatabase($c['db']) - ) - ->withFilter(new TaskTitleFilter(), true) - ; - - return $builder; - }); - - return $container; - } -} diff --git a/sources/app/ServiceProvider/GroupProvider.php b/sources/app/ServiceProvider/GroupProvider.php deleted file mode 100644 index 08548c7..0000000 --- a/sources/app/ServiceProvider/GroupProvider.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\Group\GroupManager; -use Kanboard\Group\DatabaseBackendGroupProvider; -use Kanboard\Group\LdapBackendGroupProvider; - -/** - * Group Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class GroupProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['groupManager'] = new GroupManager; - - if (DB_GROUP_PROVIDER) { - $container['groupManager']->register(new DatabaseBackendGroupProvider($container)); - } - - if (LDAP_AUTH && LDAP_GROUP_PROVIDER) { - $container['groupManager']->register(new LdapBackendGroupProvider($container)); - } - - return $container; - } -} diff --git a/sources/app/ServiceProvider/HelperProvider.php b/sources/app/ServiceProvider/HelperProvider.php deleted file mode 100644 index a909e3c..0000000 --- a/sources/app/ServiceProvider/HelperProvider.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Kanboard\Core\Helper; -use Kanboard\Core\Template; -use Pimple\Container; -use Pimple\ServiceProviderInterface; - -/** - * Class HelperProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class HelperProvider implements ServiceProviderInterface -{ - public function register(Container $container) - { - $container['helper'] = new Helper($container); - $container['helper']->register('app', '\Kanboard\Helper\AppHelper'); - $container['helper']->register('calendar', '\Kanboard\Helper\CalendarHelper'); - $container['helper']->register('asset', '\Kanboard\Helper\AssetHelper'); - $container['helper']->register('board', '\Kanboard\Helper\BoardHelper'); - $container['helper']->register('dt', '\Kanboard\Helper\DateHelper'); - $container['helper']->register('file', '\Kanboard\Helper\FileHelper'); - $container['helper']->register('form', '\Kanboard\Helper\FormHelper'); - $container['helper']->register('hook', '\Kanboard\Helper\HookHelper'); - $container['helper']->register('ical', '\Kanboard\Helper\ICalHelper'); - $container['helper']->register('layout', '\Kanboard\Helper\LayoutHelper'); - $container['helper']->register('model', '\Kanboard\Helper\ModelHelper'); - $container['helper']->register('subtask', '\Kanboard\Helper\SubtaskHelper'); - $container['helper']->register('task', '\Kanboard\Helper\TaskHelper'); - $container['helper']->register('text', '\Kanboard\Helper\TextHelper'); - $container['helper']->register('url', '\Kanboard\Helper\UrlHelper'); - $container['helper']->register('user', '\Kanboard\Helper\UserHelper'); - $container['helper']->register('avatar', '\Kanboard\Helper\AvatarHelper'); - $container['helper']->register('projectHeader', '\Kanboard\Helper\ProjectHeaderHelper'); - $container['helper']->register('projectActivity', '\Kanboard\Helper\ProjectActivityHelper'); - $container['helper']->register('mail', '\Kanboard\Helper\MailHelper'); - - $container['template'] = new Template($container['helper']); - - return $container; - } -} diff --git a/sources/app/ServiceProvider/LoggingProvider.php b/sources/app/ServiceProvider/LoggingProvider.php deleted file mode 100644 index cb6d0ba..0000000 --- a/sources/app/ServiceProvider/LoggingProvider.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Psr\Log\LogLevel; -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use SimpleLogger\Logger; -use SimpleLogger\Stderr; -use SimpleLogger\Stdout; -use SimpleLogger\Syslog; -use SimpleLogger\File; - -/** - * Class LoggingProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class LoggingProvider implements ServiceProviderInterface -{ - public function register(Container $container) - { - $logger = new Logger; - $driver = null; - - switch (LOG_DRIVER) { - case 'syslog': - $driver = new Syslog('kanboard'); - break; - case 'stdout': - $driver = new Stdout(); - break; - case 'stderr': - $driver = new Stderr(); - break; - case 'file': - $driver = new File(LOG_FILE); - break; - } - - if ($driver !== null) { - if (! DEBUG) { - $driver->setLevel(LogLevel::INFO); - } - - $logger->setLogger($driver); - } - - $container['logger'] = $logger; - return $container; - } -} diff --git a/sources/app/ServiceProvider/MailProvider.php b/sources/app/ServiceProvider/MailProvider.php deleted file mode 100644 index 685709e..0000000 --- a/sources/app/ServiceProvider/MailProvider.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Kanboard\Core\Mail\Client as EmailClient; -use Pimple\Container; -use Pimple\ServiceProviderInterface; - -/** - * Mail Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class MailProvider implements ServiceProviderInterface -{ - /** - * Registers services on the given container. - * - * @param Container $container - */ - public function register(Container $container) - { - $container['emailClient'] = function ($container) { - $mailer = new EmailClient($container); - $mailer->setTransport('smtp', '\Kanboard\Core\Mail\Transport\Smtp'); - $mailer->setTransport('sendmail', '\Kanboard\Core\Mail\Transport\Sendmail'); - $mailer->setTransport('mail', '\Kanboard\Core\Mail\Transport\Mail'); - return $mailer; - }; - - return $container; - } -} diff --git a/sources/app/ServiceProvider/NotificationProvider.php b/sources/app/ServiceProvider/NotificationProvider.php deleted file mode 100644 index a057120..0000000 --- a/sources/app/ServiceProvider/NotificationProvider.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Model\UserNotificationTypeModel; -use Kanboard\Model\ProjectNotificationTypeModel; -use Kanboard\Notification\MailNotification as MailNotification; -use Kanboard\Notification\WebNotification as WebNotification; - -/** - * Notification Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class NotificationProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['userNotificationTypeModel'] = function ($container) { - $type = new UserNotificationTypeModel($container); - $type->setType(MailNotification::TYPE, t('Email'), '\Kanboard\Notification\MailNotification'); - $type->setType(WebNotification::TYPE, t('Web'), '\Kanboard\Notification\WebNotification'); - return $type; - }; - - $container['projectNotificationTypeModel'] = function ($container) { - $type = new ProjectNotificationTypeModel($container); - $type->setType('webhook', 'Webhook', '\Kanboard\Notification\WebhookNotification', true); - $type->setType('activity_stream', 'ActivityStream', '\Kanboard\Notification\ActivityStreamNotification', true); - return $type; - }; - - return $container; - } -} diff --git a/sources/app/ServiceProvider/PluginProvider.php b/sources/app/ServiceProvider/PluginProvider.php deleted file mode 100644 index 4cf5725..0000000 --- a/sources/app/ServiceProvider/PluginProvider.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\Plugin\Loader; - -/** - * Plugin Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class PluginProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['pluginLoader'] = new Loader($container); - $container['pluginLoader']->scan(); - - return $container; - } -} diff --git a/sources/app/ServiceProvider/QueueProvider.php b/sources/app/ServiceProvider/QueueProvider.php deleted file mode 100644 index 946b436..0000000 --- a/sources/app/ServiceProvider/QueueProvider.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Kanboard\Core\Queue\QueueManager; -use Pimple\Container; -use Pimple\ServiceProviderInterface; - -/** - * Class QueueProvider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class QueueProvider implements ServiceProviderInterface -{ - /** - * Registers services on the given container. - * - * @param Container $container - */ - public function register(Container $container) - { - $container['queueManager'] = new QueueManager($container); - return $container; - } -} diff --git a/sources/app/ServiceProvider/RouteProvider.php b/sources/app/ServiceProvider/RouteProvider.php deleted file mode 100644 index 8801e3d..0000000 --- a/sources/app/ServiceProvider/RouteProvider.php +++ /dev/null @@ -1,199 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\Http\Route; -use Kanboard\Core\Http\Router; - -/** - * Route Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class RouteProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['router'] = new Router($container); - $container['route'] = new Route($container); - - if (ENABLE_URL_REWRITE) { - $container['route']->enable(); - - // Dashboard - $container['route']->addRoute('dashboard', 'DashboardController', 'show'); - $container['route']->addRoute('dashboard/:user_id', 'DashboardController', 'show'); - $container['route']->addRoute('dashboard/:user_id/projects', 'DashboardController', 'projects'); - $container['route']->addRoute('dashboard/:user_id/tasks', 'DashboardController', 'tasks'); - $container['route']->addRoute('dashboard/:user_id/subtasks', 'DashboardController', 'subtasks'); - $container['route']->addRoute('dashboard/:user_id/calendar', 'DashboardController', 'calendar'); - $container['route']->addRoute('dashboard/:user_id/activity', 'DashboardController', 'activity'); - $container['route']->addRoute('dashboard/:user_id/notifications', 'DashboardController', 'notifications'); - - // Search routes - $container['route']->addRoute('search', 'SearchController', 'index'); - $container['route']->addRoute('search/activity', 'SearchController', 'activity'); - - // ProjectCreation routes - $container['route']->addRoute('project/create', 'ProjectCreationController', 'create'); - $container['route']->addRoute('project/create/private', 'ProjectCreationController', 'createPrivate'); - - // Project routes - $container['route']->addRoute('projects', 'ProjectListController', 'show'); - $container['route']->addRoute('project/:project_id', 'ProjectViewController', 'show'); - $container['route']->addRoute('p/:project_id', 'ProjectViewController', 'show'); - $container['route']->addRoute('project/:project_id/customer-filters', 'CustomFilterController', 'index'); - $container['route']->addRoute('project/:project_id/share', 'ProjectViewController', 'share'); - $container['route']->addRoute('project/:project_id/notifications', 'ProjectViewController', 'notifications'); - $container['route']->addRoute('project/:project_id/integrations', 'ProjectViewController', 'integrations'); - $container['route']->addRoute('project/:project_id/duplicate', 'ProjectViewController', 'duplicate'); - $container['route']->addRoute('project/:project_id/permissions', 'ProjectPermissionController', 'index'); - $container['route']->addRoute('project/:project_id/activity', 'ActivityController', 'project'); - $container['route']->addRoute('project/:project_id/tags', 'ProjectTagController', 'index'); - - // Project Overview - $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'); - - // ProjectUser routes - $container['route']->addRoute('projects/managers/:user_id', 'ProjectUserOverviewController', 'managers'); - $container['route']->addRoute('projects/members/:user_id', 'ProjectUserOverviewController', 'members'); - $container['route']->addRoute('projects/tasks/:user_id/opens', 'ProjectUserOverviewController', 'opens'); - $container['route']->addRoute('projects/tasks/:user_id/closed', 'ProjectUserOverviewController', 'closed'); - $container['route']->addRoute('projects/managers', 'ProjectUserOverviewController', 'managers'); - - // Action routes - $container['route']->addRoute('project/:project_id/actions', 'ActionController', 'index'); - - // Column routes - $container['route']->addRoute('project/:project_id/columns', 'ColumnController', 'index'); - - // Swimlane routes - $container['route']->addRoute('project/:project_id/swimlanes', 'SwimlaneController', 'index'); - - // Category routes - $container['route']->addRoute('project/:project_id/categories', 'CategoryController', 'index'); - - // Import routes - $container['route']->addRoute('project/:project_id/import', 'TaskImportController', 'show'); - - // Task routes - $container['route']->addRoute('project/:project_id/task/:task_id', 'TaskViewController', 'show'); - $container['route']->addRoute('t/:task_id', 'TaskViewController', 'show'); - $container['route']->addRoute('public/task/:task_id/:token', 'TaskViewController', 'readonly'); - - $container['route']->addRoute('project/:project_id/task/:task_id/activity', 'ActivityController', 'task'); - $container['route']->addRoute('project/:project_id/task/:task_id/transitions', 'TaskViewController', 'transitions'); - $container['route']->addRoute('project/:project_id/task/:task_id/analytics', 'TaskViewController', 'analytics'); - $container['route']->addRoute('project/:project_id/task/:task_id/time-tracking', 'TaskViewController', 'timetracking'); - - // Exports - $container['route']->addRoute('export/tasks/:project_id', 'ExportController', 'tasks'); - $container['route']->addRoute('export/subtasks/:project_id', 'ExportController', 'subtasks'); - $container['route']->addRoute('export/transitions/:project_id', 'ExportController', 'transitions'); - $container['route']->addRoute('export/summary/:project_id', 'ExportController', 'summary'); - - // Analytics routes - $container['route']->addRoute('analytics/tasks/:project_id', 'AnalyticController', 'tasks'); - $container['route']->addRoute('analytics/users/:project_id', 'AnalyticController', 'users'); - $container['route']->addRoute('analytics/cfd/:project_id', 'AnalyticController', 'cfd'); - $container['route']->addRoute('analytics/burndown/:project_id', 'AnalyticController', 'burndown'); - $container['route']->addRoute('analytics/average-time-column/:project_id', 'AnalyticController', 'averageTimeByColumn'); - $container['route']->addRoute('analytics/lead-cycle-time/:project_id', 'AnalyticController', 'leadAndCycleTime'); - $container['route']->addRoute('analytics/estimated-spent-time/:project_id', 'AnalyticController', 'compareHours'); - - // Board routes - $container['route']->addRoute('board/:project_id', 'BoardViewController', 'show'); - $container['route']->addRoute('b/:project_id', 'BoardViewController', 'show'); - $container['route']->addRoute('public/board/:token', 'BoardViewController', 'readonly'); - - // Calendar routes - $container['route']->addRoute('calendar/:project_id', 'CalendarController', 'show'); - $container['route']->addRoute('c/:project_id', 'CalendarController', 'show'); - - // Listing routes - $container['route']->addRoute('list/:project_id', 'TaskListController', 'show'); - $container['route']->addRoute('l/:project_id', 'TaskListController', 'show'); - - // Gantt routes - $container['route']->addRoute('gantt/:project_id', 'TaskGanttController', 'show'); - $container['route']->addRoute('gantt/:project_id/sort/:sorting', 'TaskGanttController', 'show'); - - // Feed routes - $container['route']->addRoute('feed/project/:token', 'FeedController', 'project'); - $container['route']->addRoute('feed/user/:token', 'FeedController', 'user'); - - // Ical routes - $container['route']->addRoute('ical/project/:token', 'ICalendarController', 'project'); - $container['route']->addRoute('ical/user/:token', 'ICalendarController', 'user'); - - // Users - $container['route']->addRoute('users', 'UserListController', 'show'); - $container['route']->addRoute('user/profile/:user_id', 'UserViewController', 'profile'); - $container['route']->addRoute('user/show/:user_id', 'UserViewController', 'show'); - $container['route']->addRoute('user/show/:user_id/timesheet', 'UserViewController', 'timesheet'); - $container['route']->addRoute('user/show/:user_id/last-logins', 'UserViewController', 'lastLogin'); - $container['route']->addRoute('user/show/:user_id/sessions', 'UserViewController', 'sessions'); - $container['route']->addRoute('user/:user_id/edit', 'UserModificationController', 'show'); - $container['route']->addRoute('user/:user_id/password', 'UserCredentialController', 'changePassword'); - $container['route']->addRoute('user/:user_id/share', 'UserViewController', 'share'); - $container['route']->addRoute('user/:user_id/notifications', 'UserViewController', 'notifications'); - $container['route']->addRoute('user/:user_id/accounts', 'UserViewController', 'external'); - $container['route']->addRoute('user/:user_id/integrations', 'UserViewController', 'integrations'); - $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'); - - // Groups - $container['route']->addRoute('groups', 'GroupListController', 'index'); - $container['route']->addRoute('group/:group_id/members', 'GroupListController', 'users'); - - // Config - $container['route']->addRoute('settings', 'ConfigController', 'index'); - $container['route']->addRoute('settings/application', 'ConfigController', 'application'); - $container['route']->addRoute('settings/project', 'ConfigController', 'project'); - $container['route']->addRoute('settings/project', 'ConfigController', 'project'); - $container['route']->addRoute('settings/board', 'ConfigController', 'board'); - $container['route']->addRoute('settings/calendar', 'ConfigController', 'calendar'); - $container['route']->addRoute('settings/integrations', 'ConfigController', 'integrations'); - $container['route']->addRoute('settings/webhook', 'ConfigController', 'webhook'); - $container['route']->addRoute('settings/api', 'ConfigController', 'api'); - $container['route']->addRoute('settings/links', 'LinkController', 'index'); - $container['route']->addRoute('settings/currencies', 'CurrencyController', 'index'); - $container['route']->addRoute('settings/tags', 'TagController', 'index'); - - // Plugins - $container['route']->addRoute('extensions', 'PluginController', 'show'); - $container['route']->addRoute('extensions/directory', 'PluginController', 'directory'); - - // Doc - $container['route']->addRoute('documentation/:file', 'DocumentationController', 'show'); - $container['route']->addRoute('documentation', 'DocumentationController', 'show'); - - // Auth routes - $container['route']->addRoute('login', 'AuthController', 'login'); - $container['route']->addRoute('logout', 'AuthController', 'logout'); - - // PasswordReset - $container['route']->addRoute('forgot-password', 'PasswordResetController', 'create'); - $container['route']->addRoute('forgot-password/change/:token', 'PasswordResetController', 'change'); - } - - return $container; - } -} diff --git a/sources/app/ServiceProvider/SessionProvider.php b/sources/app/ServiceProvider/SessionProvider.php deleted file mode 100644 index 96dcac2..0000000 --- a/sources/app/ServiceProvider/SessionProvider.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -namespace Kanboard\ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Kanboard\Core\Session\SessionManager; -use Kanboard\Core\Session\SessionStorage; -use Kanboard\Core\Session\FlashMessage; - -/** - * Session Provider - * - * @package Kanboard\ServiceProvider - * @author Frederic Guillot - */ -class SessionProvider implements ServiceProviderInterface -{ - /** - * Register providers - * - * @access public - * @param \Pimple\Container $container - * @return \Pimple\Container - */ - public function register(Container $container) - { - $container['sessionStorage'] = function() { - return new SessionStorage; - }; - - $container['sessionManager'] = function($c) { - return new SessionManager($c); - }; - - $container['flash'] = function($c) { - return new FlashMessage($c); - }; - - return $container; - } -} diff --git a/sources/app/Subscriber/AuthSubscriber.php b/sources/app/Subscriber/AuthSubscriber.php deleted file mode 100644 index 0097c40..0000000 --- a/sources/app/Subscriber/AuthSubscriber.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Kanboard\Core\Security\AuthenticationManager; -use Kanboard\Core\Session\SessionManager; -use Kanboard\Event\AuthSuccessEvent; -use Kanboard\Event\AuthFailureEvent; - -/** - * Authentication Subscriber - * - * @package subscriber - * @author Frederic Guillot - */ -class AuthSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - /** - * Get event listeners - * - * @static - * @access public - * @return array - */ - public static function getSubscribedEvents() - { - return array( - AuthenticationManager::EVENT_SUCCESS => 'afterLogin', - AuthenticationManager::EVENT_FAILURE => 'onLoginFailure', - SessionManager::EVENT_DESTROY => 'afterLogout', - ); - } - - /** - * After Login callback - * - * @access public - * @param AuthSuccessEvent $event - */ - public function afterLogin(AuthSuccessEvent $event) - { - $this->logger->debug('Subscriber executed: '.__METHOD__); - - $userAgent = $this->request->getUserAgent(); - $ipAddress = $this->request->getIpAddress(); - - $this->userLockingModel->resetFailedLogin($this->userSession->getUsername()); - - $this->lastLoginModel->create( - $event->getAuthType(), - $this->userSession->getId(), - $ipAddress, - $userAgent - ); - - if ($event->getAuthType() === 'RememberMe') { - $this->userSession->validatePostAuthentication(); - } - - if (isset($this->sessionStorage->hasRememberMe) && $this->sessionStorage->hasRememberMe) { - $session = $this->rememberMeSessionModel->create($this->userSession->getId(), $ipAddress, $userAgent); - $this->rememberMeCookie->write($session['token'], $session['sequence'], $session['expiration']); - } - } - - /** - * Destroy RememberMe session on logout - * - * @access public - */ - public function afterLogout() - { - $this->logger->debug('Subscriber executed: '.__METHOD__); - $credentials = $this->rememberMeCookie->read(); - - if ($credentials !== false) { - $session = $this->rememberMeSessionModel->find($credentials['token'], $credentials['sequence']); - - if (! empty($session)) { - $this->rememberMeSessionModel->remove($session['id']); - } - - $this->rememberMeCookie->remove(); - } - } - - /** - * Increment failed login counter - * - * @access public - * @param AuthFailureEvent $event - */ - public function onLoginFailure(AuthFailureEvent $event) - { - $this->logger->debug('Subscriber executed: '.__METHOD__); - $username = $event->getUsername(); - - if (! empty($username)) { - $this->userLockingModel->incrementFailedLogin($username); - - if ($this->userLockingModel->getFailedLogin($username) > BRUTEFORCE_LOCKDOWN) { - $this->userLockingModel->lock($username, BRUTEFORCE_LOCKDOWN_DURATION); - } - } - } -} diff --git a/sources/app/Subscriber/BaseSubscriber.php b/sources/app/Subscriber/BaseSubscriber.php deleted file mode 100644 index fdea29f..0000000 --- a/sources/app/Subscriber/BaseSubscriber.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Kanboard\Core\Base; - -/** - * Base class for subscribers - * - * @package subscriber - * @author Frederic Guillot - */ -class BaseSubscriber extends Base -{ - /** - * Method called - * - * @access private - * @var array - */ - private $called = array(); - - /** - * Check if a listener has been executed - * - * @access public - * @param string $key - * @return boolean - */ - public function isExecuted($key = '') - { - if (isset($this->called[$key])) { - return true; - } - - $this->called[$key] = true; - return false; - } -} diff --git a/sources/app/Subscriber/BootstrapSubscriber.php b/sources/app/Subscriber/BootstrapSubscriber.php deleted file mode 100644 index 7d12e9a..0000000 --- a/sources/app/Subscriber/BootstrapSubscriber.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -class BootstrapSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - 'app.bootstrap' => 'execute', - ); - } - - public function execute() - { - $this->logger->debug('Subscriber executed: '.__METHOD__); - $this->languageModel->loadCurrentLanguage(); - $this->timezoneModel->setCurrentTimezone(); - $this->actionManager->attachEvents(); - - if ($this->userSession->isLogged()) { - $this->sessionStorage->hasSubtaskInProgress = $this->subtaskModel->hasSubtaskInProgress($this->userSession->getId()); - } - } - - public function __destruct() - { - if (DEBUG) { - foreach ($this->db->getLogMessages() as $message) { - $this->logger->debug('SQL: ' . $message); - } - - $this->logger->debug('APP: nb_queries={nb}', array('nb' => $this->db->getStatementHandler()->getNbQueries())); - $this->logger->debug('APP: rendering_time={time}', array('time' => microtime(true) - $this->request->getStartTime())); - $this->logger->debug('APP: memory_usage='.$this->helper->text->bytes(memory_get_usage())); - $this->logger->debug('APP: uri='.$this->request->getUri()); - $this->logger->debug('###############################################'); - } - } -} diff --git a/sources/app/Subscriber/LdapUserPhotoSubscriber.php b/sources/app/Subscriber/LdapUserPhotoSubscriber.php deleted file mode 100644 index 93672cd..0000000 --- a/sources/app/Subscriber/LdapUserPhotoSubscriber.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Kanboard\Core\User\UserProfile; -use Kanboard\Event\UserProfileSyncEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * Class LdapUserPhotoSubscriber - * - * @package Kanboard\Subscriber - * @author Frederic Guillot - */ -class LdapUserPhotoSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - /** - * Get event listeners - * - * @static - * @access public - * @return array - */ - public static function getSubscribedEvents() - { - return array( - UserProfile::EVENT_USER_PROFILE_AFTER_SYNC => 'syncUserPhoto', - ); - } - - /** - * Save the user profile photo from LDAP to the object storage - * - * @access public - * @param UserProfileSyncEvent $event - */ - public function syncUserPhoto(UserProfileSyncEvent $event) - { - if (is_a($event->getUser(), 'Kanboard\User\LdapUserProvider')) { - $profile = $event->getProfile(); - $photo = $event->getUser()->getPhoto(); - - if (empty($profile['avatar_path']) && ! empty($photo)) { - $this->logger->info('Saving user photo from LDAP profile'); - $this->avatarFileModel->uploadImageContent($profile['id'], $photo); - } - } - } -} diff --git a/sources/app/Subscriber/NotificationSubscriber.php b/sources/app/Subscriber/NotificationSubscriber.php deleted file mode 100644 index db11e58..0000000 --- a/sources/app/Subscriber/NotificationSubscriber.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Kanboard\Event\GenericEvent; -use Kanboard\Job\NotificationJob; -use Kanboard\Model\TaskModel; -use Kanboard\Model\CommentModel; -use Kanboard\Model\SubtaskModel; -use Kanboard\Model\TaskFileModel; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -class NotificationSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - 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', - CommentModel::EVENT_CREATE => 'handleEvent', - CommentModel::EVENT_UPDATE => 'handleEvent', - CommentModel::EVENT_USER_MENTION => 'handleEvent', - TaskFileModel::EVENT_CREATE => 'handleEvent', - ); - } - - public function handleEvent(GenericEvent $event, $eventName) - { - if (!$this->isExecuted($eventName)) { - $this->logger->debug('Subscriber executed: ' . __METHOD__); - - $this->queueManager->push(NotificationJob::getInstance($this->container) - ->withParams($event, $eventName, get_class($event)) - ); - } - } -} diff --git a/sources/app/Subscriber/ProjectDailySummarySubscriber.php b/sources/app/Subscriber/ProjectDailySummarySubscriber.php deleted file mode 100644 index 6971a12..0000000 --- a/sources/app/Subscriber/ProjectDailySummarySubscriber.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Kanboard\Event\TaskEvent; -use Kanboard\Job\ProjectMetricJob; -use Kanboard\Model\TaskModel; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -class ProjectDailySummarySubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - TaskModel::EVENT_CREATE_UPDATE => 'execute', - TaskModel::EVENT_CLOSE => 'execute', - TaskModel::EVENT_OPEN => 'execute', - TaskModel::EVENT_MOVE_COLUMN => 'execute', - TaskModel::EVENT_MOVE_SWIMLANE => 'execute', - ); - } - - public function execute(TaskEvent $event) - { - if (isset($event['project_id']) && !$this->isExecuted()) { - $this->logger->debug('Subscriber executed: '.__METHOD__); - $this->queueManager->push(ProjectMetricJob::getInstance($this->container)->withParams($event['project_id'])); - } - } -} diff --git a/sources/app/Subscriber/ProjectModificationDateSubscriber.php b/sources/app/Subscriber/ProjectModificationDateSubscriber.php deleted file mode 100644 index fee04ea..0000000 --- a/sources/app/Subscriber/ProjectModificationDateSubscriber.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Kanboard\Event\GenericEvent; -use Kanboard\Model\TaskModel; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -class ProjectModificationDateSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - TaskModel::EVENT_CREATE_UPDATE => 'execute', - TaskModel::EVENT_CLOSE => 'execute', - TaskModel::EVENT_OPEN => 'execute', - TaskModel::EVENT_MOVE_SWIMLANE => 'execute', - TaskModel::EVENT_MOVE_COLUMN => 'execute', - TaskModel::EVENT_MOVE_POSITION => 'execute', - TaskModel::EVENT_MOVE_PROJECT => 'execute', - TaskModel::EVENT_ASSIGNEE_CHANGE => 'execute', - ); - } - - public function execute(GenericEvent $event) - { - if (isset($event['project_id']) && !$this->isExecuted()) { - $this->logger->debug('Subscriber executed: '.__METHOD__); - $this->projectModel->updateModificationDate($event['project_id']); - } - } -} diff --git a/sources/app/Subscriber/RecurringTaskSubscriber.php b/sources/app/Subscriber/RecurringTaskSubscriber.php deleted file mode 100644 index 21cd399..0000000 --- a/sources/app/Subscriber/RecurringTaskSubscriber.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Kanboard\Event\TaskEvent; -use Kanboard\Model\TaskModel; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -class RecurringTaskSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - TaskModel::EVENT_MOVE_COLUMN => 'onMove', - TaskModel::EVENT_CLOSE => 'onClose', - ); - } - - public function onMove(TaskEvent $event) - { - $this->logger->debug('Subscriber executed: '.__METHOD__); - - if ($event['recurrence_status'] == TaskModel::RECURRING_STATUS_PENDING) { - if ($event['recurrence_trigger'] == TaskModel::RECURRING_TRIGGER_FIRST_COLUMN && $this->columnModel->getFirstColumnId($event['project_id']) == $event['src_column_id']) { - $this->taskRecurrenceModel->duplicateRecurringTask($event['task_id']); - } elseif ($event['recurrence_trigger'] == TaskModel::RECURRING_TRIGGER_LAST_COLUMN && $this->columnModel->getLastColumnId($event['project_id']) == $event['dst_column_id']) { - $this->taskRecurrenceModel->duplicateRecurringTask($event['task_id']); - } - } - } - - public function onClose(TaskEvent $event) - { - $this->logger->debug('Subscriber executed: '.__METHOD__); - - if ($event['recurrence_status'] == TaskModel::RECURRING_STATUS_PENDING && $event['recurrence_trigger'] == TaskModel::RECURRING_TRIGGER_CLOSE) { - $this->taskRecurrenceModel->duplicateRecurringTask($event['task_id']); - } - } -} diff --git a/sources/app/Subscriber/SubtaskTimeTrackingSubscriber.php b/sources/app/Subscriber/SubtaskTimeTrackingSubscriber.php deleted file mode 100644 index 7e39c12..0000000 --- a/sources/app/Subscriber/SubtaskTimeTrackingSubscriber.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Kanboard\Model\SubtaskModel; -use Kanboard\Event\SubtaskEvent; - -class SubtaskTimeTrackingSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - SubtaskModel::EVENT_CREATE => 'updateTaskTime', - SubtaskModel::EVENT_DELETE => 'updateTaskTime', - SubtaskModel::EVENT_UPDATE => array( - array('logStartEnd', 10), - array('updateTaskTime', 0), - ) - ); - } - - public function updateTaskTime(SubtaskEvent $event) - { - if (isset($event['task_id'])) { - $this->logger->debug('Subscriber executed: '.__METHOD__); - $this->subtaskTimeTrackingModel->updateTaskTimeTracking($event['task_id']); - } - } - - public function logStartEnd(SubtaskEvent $event) - { - if (isset($event['status']) && $this->configModel->get('subtask_time_tracking') == 1) { - $this->logger->debug('Subscriber executed: '.__METHOD__); - $subtask = $this->subtaskModel->getById($event['id']); - - if (empty($subtask['user_id'])) { - return false; - } - - if ($subtask['status'] == SubtaskModel::STATUS_INPROGRESS) { - return $this->subtaskTimeTrackingModel->logStartTime($subtask['id'], $subtask['user_id']); - } else { - return $this->subtaskTimeTrackingModel->logEndTime($subtask['id'], $subtask['user_id']); - } - } - } -} diff --git a/sources/app/Subscriber/TransitionSubscriber.php b/sources/app/Subscriber/TransitionSubscriber.php deleted file mode 100644 index 26d08f8..0000000 --- a/sources/app/Subscriber/TransitionSubscriber.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -namespace Kanboard\Subscriber; - -use Kanboard\Event\TaskEvent; -use Kanboard\Model\TaskModel; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -class TransitionSubscriber extends BaseSubscriber implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - TaskModel::EVENT_MOVE_COLUMN => 'execute', - ); - } - - public function execute(TaskEvent $event) - { - $this->logger->debug('Subscriber executed: '.__METHOD__); - - $user_id = $this->userSession->getId(); - - if (! empty($user_id)) { - $this->transitionModel->save($user_id, $event->getAll()); - } - } -} diff --git a/sources/app/Template/action/index.php b/sources/app/Template/action/index.php deleted file mode 100644 index 0a94e4f..0000000 --- a/sources/app/Template/action/index.php +++ /dev/null @@ -1,71 +0,0 @@ -<div class="page-header"> - <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') ?> - </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') ?> - </li> - </ul> -</div> - -<?php if (empty($actions)): ?> - <p class="alert"><?= t('There is no action at the moment.') ?></p> -<?php else: ?> - <table> - <tr> - <th><?= t('Automatic actions') ?></th> - <th><?= t('Action parameters') ?></th> - <th><?= t('Action') ?></th> - </tr> - - <?php foreach ($actions as $action): ?> - <tr> - <td> - <ul> - <li> - <?= t('Event name') ?> = - <strong><?= $this->text->in($action['event_name'], $available_events) ?></strong> - </li> - <li> - <?= t('Action name') ?> = - <strong><?= $this->text->in($action['action_name'], $available_actions) ?></strong> - </li> - <ul> - </td> - <td> - <ul> - <?php foreach ($action['params'] as $param_name => $param_value): ?> - <li> - <?= $this->text->in($param_name, $available_params[$action['action_name']]) ?> = - <strong> - <?php if ($this->text->contains($param_name, 'column_id')): ?> - <?= $this->text->in($param_value, $columns_list) ?> - <?php elseif ($this->text->contains($param_name, 'user_id')): ?> - <?= $this->text->in($param_value, $users_list) ?> - <?php elseif ($this->text->contains($param_name, 'project_id')): ?> - <?= $this->text->in($param_value, $projects_list) ?> - <?php elseif ($this->text->contains($param_name, 'color_id')): ?> - <?= $this->text->in($param_value, $colors_list) ?> - <?php elseif ($this->text->contains($param_name, 'category_id')): ?> - <?= $this->text->in($param_value, $categories_list) ?> - <?php elseif ($this->text->contains($param_name, 'link_id')): ?> - <?= $this->text->in($param_value, $links_list) ?> - <?php else: ?> - <?= $this->text->e($param_value) ?> - <?php endif ?> - </strong> - </li> - <?php endforeach ?> - </ul> - </td> - <td> - <?= $this->url->link(t('Remove'), 'ActionController', 'confirm', array('project_id' => $project['id'], 'action_id' => $action['id']), false, 'popover') ?> - </td> - </tr> - <?php endforeach ?> - </table> -<?php endif ?> diff --git a/sources/app/Template/action/remove.php b/sources/app/Template/action/remove.php deleted file mode 100644 index 384bec7..0000000 --- a/sources/app/Template/action/remove.php +++ /dev/null @@ -1,15 +0,0 @@ -<div class="page-header"> - <h2><?= t('Remove an automatic action') ?></h2> -</div> - -<div class="confirm"> - <p class="alert alert-info"> - <?= 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> -</div> diff --git a/sources/app/Template/action_creation/create.php b/sources/app/Template/action_creation/create.php deleted file mode 100644 index c0d2880..0000000 --- a/sources/app/Template/action_creation/create.php +++ /dev/null @@ -1,16 +0,0 @@ -<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'])) ?>"> - <?= $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> -</form> diff --git a/sources/app/Template/action_creation/event.php b/sources/app/Template/action_creation/event.php deleted file mode 100644 index cdf0031..0000000 --- a/sources/app/Template/action_creation/event.php +++ /dev/null @@ -1,27 +0,0 @@ -<div class="page-header"> - <h2><?= t('Choose an event') ?></h2> -</div> - -<form class="popover-form" method="post" action="<?= $this->url->href('ActionCreationController', 'params', array('project_id' => $project['id'])) ?>"> - - <?= $this->form->csrf() ?> - - <?= $this->form->hidden('project_id', $values) ?> - <?= $this->form->hidden('action_name', $values) ?> - - <?= $this->form->label(t('Action'), 'action_name') ?> - <?= $this->form->select('action_name', $available_actions, $values, array(), array('disabled')) ?> - - <?= $this->form->label(t('Event'), 'event_name') ?> - <?= $this->form->select('event_name', $events, $values) ?> - - <div class="form-help"> - <?= 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> -</form> diff --git a/sources/app/Template/action_creation/params.php b/sources/app/Template/action_creation/params.php deleted file mode 100644 index fa89217..0000000 --- a/sources/app/Template/action_creation/params.php +++ /dev/null @@ -1,55 +0,0 @@ -<div class="page-header"> - <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"> - - <?= $this->form->csrf() ?> - - <?= $this->form->hidden('project_id', $values) ?> - <?= $this->form->hidden('event_name', $values) ?> - <?= $this->form->hidden('action_name', $values) ?> - - <?= $this->form->label(t('Action'), 'action_name') ?> - <?= $this->form->select('action_name', $available_actions, $values, array(), array('disabled')) ?> - - <?= $this->form->label(t('Event'), 'event_name') ?> - <?= $this->form->select('event_name', $events, $values, array(), array('disabled')) ?> - - <?php foreach ($action_params as $param_name => $param_desc): ?> - <?php if ($this->text->contains($param_name, 'column_id')): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->select('params['.$param_name.']', $columns_list, $values) ?> - <?php elseif ($this->text->contains($param_name, 'user_id')): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->select('params['.$param_name.']', $users_list, $values) ?> - <?php elseif ($this->text->contains($param_name, 'project_id')): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->select('params['.$param_name.']', $projects_list, $values) ?> - <?php elseif ($this->text->contains($param_name, 'color_id')): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->select('params['.$param_name.']', $colors_list, $values) ?> - <?php elseif ($this->text->contains($param_name, 'category_id')): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->select('params['.$param_name.']', $categories_list, $values) ?> - <?php elseif ($this->text->contains($param_name, 'link_id')): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->select('params['.$param_name.']', $links_list, $values) ?> - <?php elseif ($param_name === 'priority'): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->select('params['.$param_name.']', $priorities_list, $values) ?> - <?php elseif ($this->text->contains($param_name, 'duration')): ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->number('params['.$param_name.']', $values) ?> - <?php else: ?> - <?= $this->form->label($param_desc, $param_name) ?> - <?= $this->form->text('params['.$param_name.']', $values) ?> - <?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> -</form> diff --git a/sources/app/Template/activity/filter_dropdown.php b/sources/app/Template/activity/filter_dropdown.php deleted file mode 100644 index 8d7a7de..0000000 --- a/sources/app/Template/activity/filter_dropdown.php +++ /dev/null @@ -1,14 +0,0 @@ -<div class="dropdown"> - <a href="#" class="dropdown-menu dropdown-menu-link-icon" title="<?= t('Default filters') ?>"><i class="fa fa-filter fa-fw"></i><i class="fa fa-caret-down"></i></a> - <ul> - <li><a href="#" class="filter-helper filter-reset" data-filter="" title="<?= t('Keyboard shortcut: "%s"', 'r') ?>"><?= t('Reset filters') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="creator:me"><?= t('My activities') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="created:<=<?= date('Y-m-d', strtotime('yesterday')) ?>"><?= t('Activity until yesterday') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="created:<=<?= date('Y-m-d')?>"><?= t('Activity until today') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:closed"><?= t('Closed tasks') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open"><?= t('Open tasks') ?></a></li> - <li> - <?= $this->url->doc(t('View advanced search syntax'), 'search') ?> - </li> - </ul> -</div> \ No newline at end of file diff --git a/sources/app/Template/activity/project.php b/sources/app/Template/activity/project.php deleted file mode 100644 index ce1c8c0..0000000 --- a/sources/app/Template/activity/project.php +++ /dev/null @@ -1,14 +0,0 @@ -<section id="main"> - <?= $this->projectHeader->render($project, 'AnalyticController', $this->app->getRouterAction()) ?> - - <?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> - </ul> - </div> - <?php endif ?> - - <?= $this->render('event/events', array('events' => $events)) ?> -</section> diff --git a/sources/app/Template/activity/task.php b/sources/app/Template/activity/task.php deleted file mode 100644 index 04c64c6..0000000 --- a/sources/app/Template/activity/task.php +++ /dev/null @@ -1,9 +0,0 @@ -<div class="task-show-title color-<?= $task['color_id'] ?>"> - <h2><?= $this->text->e($task['title']) ?></h2> -</div> - -<div class="page-header"> - <h2><?= t('Activity stream') ?></h2> -</div> - -<?= $this->render('event/events', array('events' => $events)) ?> \ No newline at end of file diff --git a/sources/app/Template/analytic/avg_time_columns.php b/sources/app/Template/analytic/avg_time_columns.php deleted file mode 100644 index 5f6c6b3..0000000 --- a/sources/app/Template/analytic/avg_time_columns.php +++ /dev/null @@ -1,29 +0,0 @@ -<div class="page-header"> - <h2><?= t('Average time spent into each column') ?></h2> -</div> - -<?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> - - <table class="table-stripped"> - <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> - <?php endforeach ?> - </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> -<?php endif ?> diff --git a/sources/app/Template/analytic/burndown.php b/sources/app/Template/analytic/burndown.php deleted file mode 100644 index e979595..0000000 --- a/sources/app/Template/analytic/burndown.php +++ /dev/null @@ -1,34 +0,0 @@ -<div class="page-header"> - <h2><?= t('Burndown chart') ?></h2> -</div> - -<?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> -<?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->label(t('Start Date'), 'from') ?> - <?= $this->form->text('from', $values, array(), array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - </div> - - <div class="form-inline-group"> - <?= $this->form->label(t('End Date'), 'to') ?> - <?= $this->form->text('to', $values, array(), array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - </div> - - <div class="form-inline-group"> - <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button> - </div> -</form> - -<p class="alert alert-info"><?= t('This chart show the task complexity over the time (Work Remaining).') ?></p> diff --git a/sources/app/Template/analytic/cfd.php b/sources/app/Template/analytic/cfd.php deleted file mode 100644 index 8dfb5b0..0000000 --- a/sources/app/Template/analytic/cfd.php +++ /dev/null @@ -1,32 +0,0 @@ -<div class="page-header"> - <h2><?= t('Cumulative flow diagram') ?></h2> -</div> - -<?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> -<?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->label(t('Start Date'), 'from') ?> - <?= $this->form->text('from', $values, array(), array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - </div> - - <div class="form-inline-group"> - <?= $this->form->label(t('End Date'), 'to') ?> - <?= $this->form->text('to', $values, array(), array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - </div> - - <div class="form-inline-group"> - <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button> - </div> -</form> diff --git a/sources/app/Template/analytic/compare_hours.php b/sources/app/Template/analytic/compare_hours.php deleted file mode 100644 index 70d8d02..0000000 --- a/sources/app/Template/analytic/compare_hours.php +++ /dev/null @@ -1,62 +0,0 @@ -<div class="page-header"> - <h2><?= t('Compare Estimated Time vs Actual Time') ?></h2> -</div> - -<div class="listing"> - <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> - </ul> -</div> - -<?php if (empty($metrics)): ?> - <p class="alert"><?= t('Not enough data to show the graph.') ?></p> -<?php else: ?> -<section id="analytic-compare-hours"> - <div id="chart" - data-metrics='<?= json_encode($metrics, JSON_HEX_APOS)?>' - data-label-spent="<?= t('Hours Spent') ?>" - data-label-estimated="<?= t('Hours Estimated') ?>" - data-label-closed="<?= t('Closed') ?>" - data-label-open="<?= t('Open') ?>"></div> - - <?php if ($paginator->isEmpty()): ?> - <p class="alert"><?= t('No tasks found.') ?></p> - <?php elseif (! $paginator->isEmpty()): ?> - <table class="table-fixed table-small"> - <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> - </tr> - <?php foreach ($paginator->getCollection() as $task): ?> - <tr> - <td class="task-table color-<?= $task['color_id'] ?>"> - <?= $this->url->link('#'.$this->text->e($task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - </td> - <td> - <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - </td> - <td> - <?php if ($task['is_active'] == \Kanboard\Model\TaskModel::STATUS_OPEN): ?> - <?= t('Open') ?> - <?php else: ?> - <?= t('Closed') ?> - <?php endif ?> - </td> - <td> - <?= $this->text->e($task['time_estimated']) ?> - </td> - <td> - <?= $this->text->e($task['time_spent']) ?> - </td> - </tr> - <?php endforeach ?> - </table> - - <?= $paginator ?> - <?php endif ?> -</section> -<?php endif ?> diff --git a/sources/app/Template/analytic/layout.php b/sources/app/Template/analytic/layout.php deleted file mode 100644 index e3c6099..0000000 --- a/sources/app/Template/analytic/layout.php +++ /dev/null @@ -1,10 +0,0 @@ -<section id="main"> - <?= $this->projectHeader->render($project, 'TaskListController', 'show') ?> - <section class="sidebar-container"> - <?= $this->render($sidebar_template, array('project' => $project)) ?> - - <div class="sidebar-content"> - <?= $content_for_sublayout ?> - </div> - </section> -</section> diff --git a/sources/app/Template/analytic/lead_cycle_time.php b/sources/app/Template/analytic/lead_cycle_time.php deleted file mode 100644 index 2dccc13..0000000 --- a/sources/app/Template/analytic/lead_cycle_time.php +++ /dev/null @@ -1,42 +0,0 @@ -<div class="page-header"> - <h2><?= t('Average Lead and Cycle time') ?></h2> -</div> - -<div class="listing"> - <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> - </ul> -</div> - -<?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->label(t('Start Date'), 'from') ?> - <?= $this->form->text('from', $values, array(), array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - </div> - - <div class="form-inline-group"> - <?= $this->form->label(t('End Date'), 'to') ?> - <?= $this->form->text('to', $values, array(), array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - </div> - - <div class="form-inline-group"> - <button type="submit" class="btn btn-blue"><?= t('Execute') ?></button> - </div> - </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> -<?php endif ?> diff --git a/sources/app/Template/analytic/sidebar.php b/sources/app/Template/analytic/sidebar.php deleted file mode 100644 index de3dccf..0000000 --- a/sources/app/Template/analytic/sidebar.php +++ /dev/null @@ -1,29 +0,0 @@ -<div class="sidebar"> - <h2><?= t('Reportings') ?></h2> - <ul> - <li <?= $this->app->checkMenuSelection('AnalyticController', 'tasks') ?>> - <?= $this->url->link(t('Task distribution'), 'AnalyticController', 'tasks', array('project_id' => $project['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('AnalyticController', 'users') ?>> - <?= $this->url->link(t('User repartition'), 'AnalyticController', 'users', 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'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('AnalyticController', 'burndown') ?>> - <?= $this->url->link(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'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('AnalyticController', 'leadAndCycleTime') ?>> - <?= $this->url->link(t('Lead and cycle time'), 'AnalyticController', 'leadAndCycleTime', array('project_id' => $project['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('AnalyticController', 'compareHours') ?>> - <?= $this->url->link(t('Estimated vs actual time'), 'AnalyticController', 'compareHours', array('project_id' => $project['id'])) ?> - </li> - - <?= $this->hook->render('template:analytic:sidebar', array('project' => $project)) ?> - - </ul> -</div> diff --git a/sources/app/Template/analytic/tasks.php b/sources/app/Template/analytic/tasks.php deleted file mode 100644 index 9e7b1fd..0000000 --- a/sources/app/Template/analytic/tasks.php +++ /dev/null @@ -1,34 +0,0 @@ -<div class="page-header"> - <h2><?= t('Task distribution') ?></h2> -</div> - -<?php if (empty($metrics)): ?> - <p class="alert"><?= t('Not enough data to show the graph.') ?></p> -<?php else: ?> - <section id="analytic-task-repartition"> - - <div id="chart" data-metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>'></div> - - <table> - <tr> - <th><?= t('Column') ?></th> - <th><?= t('Number of tasks') ?></th> - <th><?= t('Percentage') ?></th> - </tr> - <?php foreach ($metrics as $metric): ?> - <tr> - <td> - <?= $this->text->e($metric['column_title']) ?> - </td> - <td> - <?= $metric['nb_tasks'] ?> - </td> - <td> - <?= n($metric['percentage']) ?>% - </td> - </tr> - <?php endforeach ?> - </table> - - </section> -<?php endif ?> diff --git a/sources/app/Template/analytic/users.php b/sources/app/Template/analytic/users.php deleted file mode 100644 index 9d1d3a1..0000000 --- a/sources/app/Template/analytic/users.php +++ /dev/null @@ -1,34 +0,0 @@ -<div class="page-header"> - <h2><?= t('User repartition') ?></h2> -</div> - -<?php if (empty($metrics)): ?> - <p class="alert"><?= t('Not enough data to show the graph.') ?></p> -<?php else: ?> - <section id="analytic-user-repartition"> - - <div id="chart" data-metrics='<?= json_encode($metrics, JSON_HEX_APOS) ?>'></div> - - <table> - <tr> - <th><?= t('User') ?></th> - <th><?= t('Number of tasks') ?></th> - <th><?= t('Percentage') ?></th> - </tr> - <?php foreach ($metrics as $metric): ?> - <tr> - <td> - <?= $this->text->e($metric['user']) ?> - </td> - <td> - <?= $metric['nb_tasks'] ?> - </td> - <td> - <?= n($metric['percentage']) ?>% - </td> - </tr> - <?php endforeach ?> - </table> - - </section> -<?php endif ?> diff --git a/sources/app/Template/app/filters_helper.php b/sources/app/Template/app/filters_helper.php deleted file mode 100644 index c16c225..0000000 --- a/sources/app/Template/app/filters_helper.php +++ /dev/null @@ -1,20 +0,0 @@ -<?= $this->hook->render('template:app:filters-helper:before', isset($project) ? array('project' => $project) : array()) ?> -<div class="dropdown"> - <a href="#" class="dropdown-menu dropdown-menu-link-icon" title="<?= t('Default filters') ?>"><i class="fa fa-filter fa-fw"></i><i class="fa fa-caret-down"></i></a> - <ul> - <li><a href="#" class="filter-helper filter-reset" data-filter="<?= isset($reset) ? $reset : '' ?>" title="<?= t('Keyboard shortcut: "%s"', 'r') ?>"><?= t('Reset filters') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open assignee:me"><?= t('My tasks') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open assignee:me due:tomorrow"><?= t('My tasks due tomorrow') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open due:today"><?= t('Tasks due today') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open due:tomorrow"><?= t('Tasks due tomorrow') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open due:yesterday"><?= t('Tasks due yesterday') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:closed"><?= t('Closed tasks') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open"><?= t('Open tasks') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open assignee:nobody"><?= t('Not assigned') ?></a></li> - <li><a href="#" class="filter-helper" data-filter="status:open category:none"><?= t('No category') ?></a></li> - <li> - <?= $this->url->doc(t('View advanced search syntax'), 'search') ?> - </li> - </ul> -</div> -<?= $this->hook->render('template:app:filters-helper:after', isset($project) ? array('project' => $project) : array()) ?> \ No newline at end of file diff --git a/sources/app/Template/app/forbidden.php b/sources/app/Template/app/forbidden.php deleted file mode 100644 index 96e7611..0000000 --- a/sources/app/Template/app/forbidden.php +++ /dev/null @@ -1,5 +0,0 @@ -<section id="main"> - <p class="alert alert-error"> - <?= t('Access Forbidden') ?> - </p> -</section> \ No newline at end of file diff --git a/sources/app/Template/app/notfound.php b/sources/app/Template/app/notfound.php deleted file mode 100644 index 0419902..0000000 --- a/sources/app/Template/app/notfound.php +++ /dev/null @@ -1,5 +0,0 @@ -<section id="main"> - <p class="alert alert-error"> - <?= t('Sorry, I didn\'t find this information in my database!') ?> - </p> -</section> \ No newline at end of file diff --git a/sources/app/Template/auth/index.php b/sources/app/Template/auth/index.php deleted file mode 100644 index 45bbdb8..0000000 --- a/sources/app/Template/auth/index.php +++ /dev/null @@ -1,42 +0,0 @@ -<div class="form-login"> - - <?= $this->hook->render('template:auth:login-form:before') ?> - - <?php if (isset($errors['login'])): ?> - <p class="alert alert-error"><?= $this->text->e($errors['login']) ?></p> - <?php endif ?> - - <?php if (! HIDE_LOGIN_FORM): ?> - <form method="post" action="<?= $this->url->href('AuthController', 'check') ?>"> - - <?= $this->form->csrf() ?> - - <?= $this->form->label(t('Username'), 'username') ?> - <?= $this->form->text('username', $values, $errors, array('autofocus', 'required')) ?> - - <?= $this->form->label(t('Password'), 'password') ?> - <?= $this->form->password('password', $values, $errors, array('required')) ?> - - <?php if (isset($captcha) && $captcha): ?> - <?= $this->form->label(t('Enter the text below'), 'captcha') ?> - <img src="<?= $this->url->href('CaptchaController', 'image') ?>" alt="Captcha"> - <?= $this->form->text('captcha', array(), $errors, array('required')) ?> - <?php endif ?> - - <?php if (REMEMBER_ME_AUTH): ?> - <?= $this->form->checkbox('remember_me', t('Remember Me'), 1, true) ?><br> - <?php endif ?> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Sign in') ?></button> - </div> - <?php if ($this->app->config('password_reset') == 1): ?> - <div class="reset-password"> - <?= $this->url->link(t('Forgot password?'), 'PasswordResetController', 'create') ?> - </div> - <?php endif ?> - </form> - <?php endif ?> - - <?= $this->hook->render('template:auth:login-form:after') ?> -</div> diff --git a/sources/app/Template/avatar_file/show.php b/sources/app/Template/avatar_file/show.php deleted file mode 100644 index 37c56ce..0000000 --- a/sources/app/Template/avatar_file/show.php +++ /dev/null @@ -1,23 +0,0 @@ -<div class="page-header"> - <h2><?= t('Avatar') ?></h2> -</div> - -<?= $this->avatar->render($user['id'], $user['username'], $user['name'], $user['email'], $user['avatar_path'], '') ?> - -<div class="form-actions"> -<?php if (! empty($user['avatar_path'])): ?> - <?= $this->url->link(t('Remove my image'), 'AvatarFileController', 'remove', array('user_id' => $user['id']), true, 'btn btn-red') ?> -<?php endif ?> -</div> - -<hr> - -<h3><?= t('Upload my avatar image') ?></h3> -<form method="post" enctype="multipart/form-data" action="<?= $this->url->href('AvatarFileController', 'upload', array('user_id' => $user['id'])) ?>"> - <?= $this->form->csrf() ?> - <?= $this->form->file('avatar') ?> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Upload my avatar image') ?></button> - </div> -</form> diff --git a/sources/app/Template/board/table_column.php b/sources/app/Template/board/table_column.php deleted file mode 100644 index 6336234..0000000 --- a/sources/app/Template/board/table_column.php +++ /dev/null @@ -1,80 +0,0 @@ -<!-- column titles --> -<tr class="board-swimlane-columns-<?= $swimlane['id'] ?>"> - <?php foreach ($swimlane['columns'] as $column): ?> - <th class="board-column-header board-column-header-<?= $column['id'] ?>" data-column-id="<?= $column['id'] ?>"> - - <!-- column in collapsed mode --> - <div class="board-column-collapsed"> - <span class="board-column-header-task-count" title="<?= t('Show this column') ?>"> - <span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span> - </span> - </div> - - <!-- column in expanded mode --> - <div class="board-column-expanded"> - <?php if (! $not_editable && $this->user->hasProjectAccess('TaskCreationController', 'show', $column['project_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')) ?> - </div> - <?php endif ?> - - <?php if ($swimlane['nb_swimlanes'] > 1 && ! empty($column['column_nb_tasks'])): ?> - <span title="<?= t('Total number of tasks in this column across all swimlanes') ?>" class="board-column-header-task-count"> - (<span><?= $column['column_nb_tasks'] ?></span>) - </span> - <?php endif ?> - - <span class="board-column-title"> - <?php if ($not_editable): ?> - <?= $this->text->e($column['title']) ?> - <?php else: ?> - <span class="dropdown"> - <a href="#" class="dropdown-menu"><?= $this->text->e($column['title']) ?> <i class="fa fa-caret-down"></i></a> - <ul> - <li> - <i class="fa fa-minus-square fa-fw"></i> - <a href="#" class="board-toggle-column-view" data-column-id="<?= $column['id'] ?>"><?= t('Hide this column') ?></a> - </li> - <?php if ($this->user->hasProjectAccess('TaskCreationController', 'show', $column['project_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') ?> - </li> - <?php if ($column['nb_tasks'] > 0): ?> - <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') ?> - </li> - <?php endif ?> - <?php endif ?> - </ul> - </span> - <?php endif ?> - </span> - - <?php if (! $not_editable && ! empty($column['description'])): ?> - <span class="tooltip pull-right" title="<?= $this->text->markdownAttribute($column['description']) ?>"> -  <i class="fa fa-info-circle"></i> - </span> - <?php endif ?> - - <?php if (! empty($column['score'])): ?> - <span class="pull-right" title="<?= t('Score') ?>"> - <?= $column['score'] ?> - </span> - <?php endif ?> - - <?php if ($column['task_limit']): ?> - <span title="<?= t('Task limit') ?>"> - (<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>/<?= $this->text->e($column['task_limit']) ?>) - </span> - <?php else: ?> - <span title="<?= t('Task count') ?>" class="board-column-header-task-count"> - (<span id="task-number-column-<?= $column['id'] ?>"><?= $column['nb_tasks'] ?></span>) - </span> - <?php endif ?> - </div> - - </th> - <?php endforeach ?> -</tr> diff --git a/sources/app/Template/board/table_container.php b/sources/app/Template/board/table_container.php deleted file mode 100644 index a93e700..0000000 --- a/sources/app/Template/board/table_container.php +++ /dev/null @@ -1,58 +0,0 @@ -<div id="board-container"> - <?php if (empty($swimlanes) || empty($swimlanes[0]['nb_columns'])): ?> - <p class="alert alert-error"><?= t('There is no column or swimlane activated in your project!') ?></p> - <?php else: ?> - - <?php if (isset($not_editable)): ?> - <table id="board" class="board-project-<?= $project['id'] ?>"> - <?php else: ?> - <table id="board" - class="board-project-<?= $project['id'] ?>" - data-project-id="<?= $project['id'] ?>" - data-check-interval="<?= $board_private_refresh_interval ?>" - data-save-url="<?= $this->url->href('BoardAjaxController', 'save', array('project_id' => $project['id'])) ?>" - data-reload-url="<?= $this->url->href('BoardAjaxController', 'reload', array('project_id' => $project['id'])) ?>" - data-check-url="<?= $this->url->href('BoardAjaxController', 'check', array('project_id' => $project['id'], 'timestamp' => time())) ?>" - data-task-creation-url="<?= $this->url->href('TaskCreationController', 'show', array('project_id' => $project['id'])) ?>" - > - <?php endif ?> - - <?php foreach ($swimlanes as $index => $swimlane): ?> - <?php if (! ($swimlane['nb_tasks'] === 0 && isset($not_editable))): ?> - - <!-- Note: Do not show swimlane row on the top otherwise we can't collapse columns --> - <?php if ($index > 0 && $swimlane['nb_swimlanes'] > 1): ?> - <?= $this->render('board/table_swimlane', array( - 'project' => $project, - 'swimlane' => $swimlane, - 'not_editable' => isset($not_editable), - )) ?> - <?php endif ?> - - <?= $this->render('board/table_column', array( - 'swimlane' => $swimlane, - 'not_editable' => isset($not_editable), - )) ?> - - <?php if ($index === 0 && $swimlane['nb_swimlanes'] > 1): ?> - <?= $this->render('board/table_swimlane', array( - 'project' => $project, - 'swimlane' => $swimlane, - 'not_editable' => isset($not_editable), - )) ?> - <?php endif ?> - - <?= $this->render('board/table_tasks', array( - 'project' => $project, - 'swimlane' => $swimlane, - 'not_editable' => isset($not_editable), - 'board_highlight_period' => $board_highlight_period, - )) ?> - - <?php endif ?> - <?php endforeach ?> - - </table> - - <?php endif ?> -</div> diff --git a/sources/app/Template/board/table_swimlane.php b/sources/app/Template/board/table_swimlane.php deleted file mode 100644 index c5937e0..0000000 --- a/sources/app/Template/board/table_swimlane.php +++ /dev/null @@ -1,26 +0,0 @@ -<!-- swimlane --> -<tr id="swimlane-<?= $swimlane['id'] ?>"> - <th class="board-swimlane-header" colspan="<?= $swimlane['nb_columns'] ?>"> - <?php if (! $not_editable): ?> - <a href="#" class="board-swimlane-toggle" data-swimlane-id="<?= $swimlane['id'] ?>"> - <i class="fa fa-chevron-circle-up hide-icon-swimlane-<?= $swimlane['id'] ?>" title="<?= t('Collapse swimlane') ?>"></i> - <i class="fa fa-chevron-circle-down show-icon-swimlane-<?= $swimlane['id'] ?>" title="<?= t('Expand swimlane') ?>" style="display: none"></i> - </a> - <?php endif ?> - - <?= $this->text->e($swimlane['name']) ?> - - <?php if (! $not_editable && ! empty($swimlane['description'])): ?> - <span - title="<?= t('Description') ?>" - class="tooltip" - data-href="<?= $this->url->href('BoardTooltipController', 'swimlane', array('swimlane_id' => $swimlane['id'], 'project_id' => $project['id'])) ?>"> - <i class="fa fa-info-circle"></i> - </span> - <?php endif ?> - - <span title="<?= t('Task count') ?>" class="board-column-header-task-count swimlane-task-count-<?= $swimlane['id'] ?>"> - (<?= $swimlane['nb_tasks'] ?>) - </span> - </th> -</tr> diff --git a/sources/app/Template/board/table_tasks.php b/sources/app/Template/board/table_tasks.php deleted file mode 100644 index fd9ce5e..0000000 --- a/sources/app/Template/board/table_tasks.php +++ /dev/null @@ -1,31 +0,0 @@ -<!-- task row --> -<tr class="board-swimlane board-swimlane-tasks-<?= $swimlane['id'] ?>"> - <?php foreach ($swimlane['columns'] as $column): ?> - <td class=" - board-column-<?= $column['id'] ?> - <?= $column['task_limit'] > 0 && $column['nb_tasks'] > $column['task_limit'] ? 'board-task-list-limit' : '' ?> - "> - - <!-- tasks list --> - <div class="board-task-list board-column-expanded" data-column-id="<?= $column['id'] ?>" data-swimlane-id="<?= $swimlane['id'] ?>" data-task-limit="<?= $column['task_limit'] ?>"> - <?php foreach ($column['tasks'] as $task): ?> - <?= $this->render($not_editable ? 'board/task_public' : 'board/task_private', array( - 'project' => $project, - 'task' => $task, - 'board_highlight_period' => $board_highlight_period, - 'not_editable' => $not_editable, - )) ?> - <?php endforeach ?> - </div> - - <!-- column in collapsed mode (rotated text) --> - <div class="board-column-collapsed"> - <div class="board-rotation-wrapper"> - <div class="board-column-title board-rotation board-toggle-column-view" data-column-id="<?= $column['id'] ?>" title="<?= t('Show this column') ?>"> - <i class="fa fa-plus-square tooltip" title="<?= $this->text->e($column['title']) ?>"></i> <?= $this->text->e($column['title']) ?> - </div> - </div> - </div> - </td> - <?php endforeach ?> -</tr> diff --git a/sources/app/Template/board/task_avatar.php b/sources/app/Template/board/task_avatar.php deleted file mode 100644 index 28e0813..0000000 --- a/sources/app/Template/board/task_avatar.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php if (! empty($task['owner_id'])): ?> -<div class="task-board-avatars"> - <span - <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?> - class="task-board-assignee task-board-change-assignee" - data-url="<?= $this->url->href('TaskModificationController', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"> - <?php else: ?> - class="task-board-assignee"> - <?php endif ?> - <?= $this->avatar->small( - $task['owner_id'], - $task['assignee_username'], - $task['assignee_name'], - $task['assignee_email'], - $task['assignee_avatar_path'], - 'avatar-inline' - ) ?> - </span> -</div> -<?php endif ?> diff --git a/sources/app/Template/board/task_footer.php b/sources/app/Template/board/task_footer.php deleted file mode 100644 index bc34363..0000000 --- a/sources/app/Template/board/task_footer.php +++ /dev/null @@ -1,108 +0,0 @@ -<?php if (! empty($task['category_id'])): ?> -<div class="task-board-category-container"> - <span class="task-board-category"> - <?php if ($not_editable): ?> - <?= $this->text->e($task['category_name']) ?> - <?php else: ?> - <?= $this->url->link( - $this->text->e($task['category_name']), - 'TaskModificationController', - 'edit', - array('task_id' => $task['id'], 'project_id' => $task['project_id']), - false, - 'popover' . (! empty($task['category_description']) ? ' tooltip' : ''), - ! empty($task['category_description']) ? $this->text->markdownAttribute($task['category_description']) : t('Change category') - ) ?> - <?php endif ?> - </span> -</div> -<?php endif ?> - -<?php if (! empty($task['tags'])): ?> - <div class="task-tags"> - <ul> - <?php foreach ($task['tags'] as $tag): ?> - <li><?= $this->text->e($tag['name']) ?></li> - <?php endforeach ?> - </ul> - </div> -<?php endif ?> - -<div class="task-board-icons"> - <?php if ($task['score']): ?> - <span class="task-score" title="<?= t('Complexity') ?>"> - <i class="fa fa-trophy"></i> - <?= $this->text->e($task['score']) ?> - </span> - <?php endif ?> - - <?php if (! empty($task['date_due'])): ?> - <?php if (date('Y-m-d') == date('Y-m-d', $task['date_due'])): ?> - <span class="task-board-date task-board-date-today"> - <?php elseif (time() > $task['date_due']): ?> - <span class="task-board-date task-board-date-overdue"> - <?php endif ?> - <i class="fa fa-calendar"></i> - <?= $this->dt->date($task['date_due']) ?> - </span> - <?php endif ?> - - <?php if ($task['recurrence_status'] == \Kanboard\Model\TaskModel::RECURRING_STATUS_PENDING): ?> - <span title="<?= t('Recurrence') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'recurrence', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-refresh fa-rotate-90"></i></span> - <?php endif ?> - - <?php if ($task['recurrence_status'] == \Kanboard\Model\TaskModel::RECURRING_STATUS_PROCESSED): ?> - <span title="<?= t('Recurrence') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'recurrence', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-refresh fa-rotate-90 fa-inverse"></i></span> - <?php endif ?> - - <?php if (! empty($task['nb_links'])): ?> - <span title="<?= t('Links') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'tasklinks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-code-fork fa-fw"></i><?= $task['nb_links'] ?></span> - <?php endif ?> - - <?php if (! empty($task['nb_external_links'])): ?> - <span title="<?= t('External links') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'externallinks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-external-link fa-fw"></i><?= $task['nb_external_links'] ?></span> - <?php endif ?> - - <?php if (! empty($task['nb_subtasks'])): ?> - <span title="<?= t('Sub-Tasks') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'subtasks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-bars"></i> <?= round($task['nb_completed_subtasks']/$task['nb_subtasks']*100, 0).'%' ?></span> - <?php endif ?> - - <?php if (! empty($task['nb_files'])): ?> - <span title="<?= t('Attachments') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'attachments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-paperclip"></i> <?= $task['nb_files'] ?></span> - <?php endif ?> - - <?php if (! empty($task['nb_comments'])): ?> - <span title="<?= $task['nb_comments'] == 1 ? t('%d comment', $task['nb_comments']) : t('%d comments', $task['nb_comments']) ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'comments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><i class="fa fa-comment-o"></i> <?= $task['nb_comments'] ?></span> - <?php endif ?> - - <?php if (! empty($task['description'])): ?> - <span title="<?= t('Description') ?>" class="tooltip" data-href="<?= $this->url->href('BoardTooltipController', 'description', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"> - <i class="fa fa-file-text-o"></i> - </span> - <?php endif ?> - - <?php if (! empty($task['time_estimated'])): ?> - <span class="task-time-estimated" title="<?= t('Time estimated') ?>"><?= $this->text->e($task['time_estimated']).'h' ?></span> - <?php endif ?> - - <?php if ($task['is_milestone'] == 1): ?> - <span title="<?= t('Milestone') ?>"> - <i class="fa fa-flag flag-milestone"></i> - </span> - <?php endif ?> - - <?= $this->hook->render('template:board:task:icons', array('task' => $task)) ?> - - <?= $this->task->formatPriority($project, $task) ?> - - <?php if ($task['is_active'] == 1): ?> - <div class="task-board-age"> - <span title="<?= t('Task age in days')?>" class="task-board-age-total"><?= $this->dt->age($task['date_creation']) ?></span> - <span title="<?= t('Days in this column')?>" class="task-board-age-column"><?= $this->dt->age($task['date_moved']) ?></span> - </div> - <?php else: ?> - <span class="task-board-closed"><i class="fa fa-ban fa-fw"></i><?= t('Closed') ?></span> - <?php endif ?> -</div> - -<?= $this->hook->render('template:board:task:footer', array('task' => $task)) ?> diff --git a/sources/app/Template/board/task_private.php b/sources/app/Template/board/task_private.php deleted file mode 100644 index 94b396a..0000000 --- a/sources/app/Template/board/task_private.php +++ /dev/null @@ -1,62 +0,0 @@ -<div class=" - task-board - <?= $task['is_active'] == 1 ? ($this->user->hasProjectAccess('BoardViewController', 'save', $task['project_id']) ? 'draggable-item ' : '').'task-board-status-open '.($task['date_modification'] > (time() - $board_highlight_period) ? 'task-board-recent' : '') : 'task-board-status-closed' ?> - color-<?= $task['color_id'] ?>" - data-task-id="<?= $task['id'] ?>" - data-column-id="<?= $task['column_id'] ?>" - data-swimlane-id="<?= $task['swimlane_id'] ?>" - data-position="<?= $task['position'] ?>" - data-owner-id="<?= $task['owner_id'] ?>" - data-category-id="<?= $task['category_id'] ?>" - data-due-date="<?= $task['date_due'] ?>" - data-task-url="<?= $this->url->href('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"> - - <div class="task-board-sort-handle" style="display: none;"><i class="fa fa-arrows-alt"></i></div> - - <?php if ($this->board->isCollapsed($task['project_id'])): ?> - <div class="task-board-collapsed"> - <div class="task-board-saving-icon" style="display: none;"><i class="fa fa-spinner fa-pulse"></i></div> - <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?> - <?= $this->render('task/dropdown', array('task' => $task)) ?> - <?php else: ?> - <strong><?= '#'.$task['id'] ?></strong> - <?php endif ?> - - <?php if (! empty($task['assignee_username'])): ?> - <span title="<?= $this->text->e($task['assignee_name'] ?: $task['assignee_username']) ?>"> - <?= $this->text->e($this->user->getInitials($task['assignee_name'] ?: $task['assignee_username'])) ?> - </span> - - <?php endif ?> - <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-board-collapsed-title tooltip', $this->text->e($task['title'])) ?> - </div> - <?php else: ?> - <div class="task-board-expanded"> - <div class="task-board-saving-icon" style="display: none;"><i class="fa fa-spinner fa-pulse fa-2x"></i></div> - <?php if ($this->user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?> - <?= $this->render('task/dropdown', array('task' => $task)) ?> - <?php else: ?> - <strong><?= '#'.$task['id'] ?></strong> - <?php endif ?> - - <?php if ($task['reference']): ?> - <span class="task-board-reference" title="<?= t('Reference') ?>"> - (<?= $task['reference'] ?>) - </span> - <?php endif ?> - - <?= $this->render('board/task_avatar', array('task' => $task)) ?> - - <?= $this->hook->render('template:board:private:task:before-title', array('task' => $task)) ?> - <div class="task-board-title"> - <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - </div> - <?= $this->hook->render('template:board:private:task:after-title', array('task' => $task)) ?> - - <?= $this->render('board/task_footer', array( - 'task' => $task, - 'not_editable' => $not_editable, - 'project' => $project, - )) ?> - </div> - <?php endif ?> -</div> diff --git a/sources/app/Template/board/task_public.php b/sources/app/Template/board/task_public.php deleted file mode 100644 index 82eb653..0000000 --- a/sources/app/Template/board/task_public.php +++ /dev/null @@ -1,24 +0,0 @@ -<div class="task-board color-<?= $task['color_id'] ?> <?= $task['date_modification'] > time() - $board_highlight_period ? 'task-board-recent' : '' ?>"> - - <?= $this->url->link('#'.$task['id'], 'TaskViewController', 'readonly', array('task_id' => $task['id'], 'token' => $project['token'])) ?> - - <?php if ($task['reference']): ?> - <span class="task-board-reference" title="<?= t('Reference') ?>"> - (<?= $task['reference'] ?>) - </span> - <?php endif ?> - - <?= $this->render('board/task_avatar', array('task' => $task)) ?> - - <?= $this->hook->render('template:board:public:task:before-title', array('task' => $task)) ?> - <div class="task-board-title"> - <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'readonly', array('task_id' => $task['id'], 'token' => $project['token'])) ?> - </div> - <?= $this->hook->render('template:board:public:task:after-title', array('task' => $task)) ?> - - <?= $this->render('board/task_footer', array( - 'task' => $task, - 'not_editable' => $not_editable, - 'project' => $project, - )) ?> -</div> diff --git a/sources/app/Template/board/tooltip_comments.php b/sources/app/Template/board/tooltip_comments.php deleted file mode 100644 index a107184..0000000 --- a/sources/app/Template/board/tooltip_comments.php +++ /dev/null @@ -1,9 +0,0 @@ -<div class="tooltip-large"> - <?php foreach ($comments as $comment): ?> - <?= $this->render('comment/show', array( - 'comment' => $comment, - 'task' => $task, - 'hide_actions' => true, - )) ?> - <?php endforeach ?> -</div> diff --git a/sources/app/Template/board/tooltip_description.php b/sources/app/Template/board/tooltip_description.php deleted file mode 100644 index 7e0e343..0000000 --- a/sources/app/Template/board/tooltip_description.php +++ /dev/null @@ -1,5 +0,0 @@ -<section class="tooltip-large"> -<div class="markdown"> - <?= $this->text->markdown($task['description']) ?> -</div> -</section> \ No newline at end of file diff --git a/sources/app/Template/board/tooltip_external_links.php b/sources/app/Template/board/tooltip_external_links.php deleted file mode 100644 index 6533186..0000000 --- a/sources/app/Template/board/tooltip_external_links.php +++ /dev/null @@ -1,22 +0,0 @@ -<div class="tooltip-large"> - <table> - <tr> - <th class="column-20"><?= t('Type') ?></th> - <th class="column-70"><?= t('Title') ?></th> - <th class="column-10"><?= t('Dependency') ?></th> - </tr> - <?php foreach ($links as $link): ?> - <tr> - <td> - <?= $link['type'] ?> - </td> - <td> - <a href="<?= $link['url'] ?>" target="_blank"><?= $this->text->e($link['title']) ?></a> - </td> - <td> - <?= $this->text->e($link['dependency_label']) ?> - </td> - </tr> - <?php endforeach ?> - </table> -</div> diff --git a/sources/app/Template/board/tooltip_files.php b/sources/app/Template/board/tooltip_files.php deleted file mode 100644 index 6f9e264..0000000 --- a/sources/app/Template/board/tooltip_files.php +++ /dev/null @@ -1,20 +0,0 @@ -<div class="tooltip-large"> - <table> - <?php foreach ($files as $file): ?> - <tr> - <th> - <i class="fa <?= $this->file->icon($file['name']) ?> fa-fw"></i> - <?= $this->text->e($file['name']) ?> - </th> - </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'])) ?> - <?php if ($file['is_image'] == 1): ?> -  <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') ?> - <?php endif ?> - </td> - </tr> - <?php endforeach ?> - </table> -</div> diff --git a/sources/app/Template/board/tooltip_subtasks.php b/sources/app/Template/board/tooltip_subtasks.php deleted file mode 100644 index 0322d37..0000000 --- a/sources/app/Template/board/tooltip_subtasks.php +++ /dev/null @@ -1,22 +0,0 @@ -<div class="tooltip-large"> - <table> - <tr> - <th class="column-80"><?= t('Subtask') ?></th> - <th><?= t('Assignee') ?></th> - </tr> - <?php foreach ($subtasks as $subtask): ?> - <tr> - <td> - <?= $this->subtask->toggleStatus($subtask, $task['project_id']) ?> - </td> - <td> - <?php if (! empty($subtask['username'])): ?> - <?= $this->text->e($subtask['name'] ?: $subtask['username']) ?> - <?php else: ?> - <?= t('Not assigned') ?> - <?php endif ?> - </td> - </tr> - <?php endforeach ?> - </table> -</div> diff --git a/sources/app/Template/board/tooltip_tasklinks.php b/sources/app/Template/board/tooltip_tasklinks.php deleted file mode 100644 index d1156cb..0000000 --- a/sources/app/Template/board/tooltip_tasklinks.php +++ /dev/null @@ -1,34 +0,0 @@ -<div class="tooltip-large"> - <table> - <?php foreach ($links as $label => $grouped_links): ?> - <tr> - <th colspan="4"><?= t($label) ?></th> - </tr> - <?php foreach ($grouped_links as $link): ?> - <tr> - <td class="column-10"> - <?= $this->task->getProgress($link).'%' ?> - </td> - <td class="column-60"> - <?= $this->url->link( - $this->text->e('#'.$link['task_id'].' '.$link['title']), - 'TaskViewController', 'show', array('task_id' => $link['task_id'], 'project_id' => $link['project_id']), - false, - $link['is_active'] ? '' : 'task-link-closed' - ) ?> - </td> - <td> - <?php if (! empty($link['task_assignee_username'])): ?> - <?= $this->text->e($link['task_assignee_name'] ?: $link['task_assignee_username']) ?> - <?php else: ?> - <?= t('Not assigned') ?> - <?php endif ?> - </td> - <td> - <?= $link['project_name'] ?> - </td> - </tr> - <?php endforeach ?> - <?php endforeach ?> - </table> -</div> diff --git a/sources/app/Template/board/view_private.php b/sources/app/Template/board/view_private.php deleted file mode 100644 index a89e7d2..0000000 --- a/sources/app/Template/board/view_private.php +++ /dev/null @@ -1,12 +0,0 @@ -<section id="main"> - - <?= $this->projectHeader->render($project, 'BoardViewController', 'show', true) ?> - - <?= $this->render('board/table_container', array( - 'project' => $project, - 'swimlanes' => $swimlanes, - 'board_private_refresh_interval' => $board_private_refresh_interval, - 'board_highlight_period' => $board_highlight_period, - )) ?> - -</section> diff --git a/sources/app/Template/board/view_public.php b/sources/app/Template/board/view_public.php deleted file mode 100644 index aea7203..0000000 --- a/sources/app/Template/board/view_public.php +++ /dev/null @@ -1,11 +0,0 @@ -<section id="main" class="public-board"> - - <?= $this->render('board/table_container', array( - 'project' => $project, - 'swimlanes' => $swimlanes, - 'board_private_refresh_interval' => $board_private_refresh_interval, - 'board_highlight_period' => $board_highlight_period, - 'not_editable' => true, - )) ?> - -</section> \ No newline at end of file diff --git a/sources/app/Template/board_popover/close_all_tasks_column.php b/sources/app/Template/board_popover/close_all_tasks_column.php deleted file mode 100644 index 57f703e..0000000 --- a/sources/app/Template/board_popover/close_all_tasks_column.php +++ /dev/null @@ -1,18 +0,0 @@ -<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) ?> - - <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> diff --git a/sources/app/Template/calendar/show.php b/sources/app/Template/calendar/show.php deleted file mode 100644 index 3635f62..0000000 --- a/sources/app/Template/calendar/show.php +++ /dev/null @@ -1,9 +0,0 @@ -<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> -</section> diff --git a/sources/app/Template/category/edit.php b/sources/app/Template/category/edit.php deleted file mode 100644 index fac56db..0000000 --- a/sources/app/Template/category/edit.php +++ /dev/null @@ -1,23 +0,0 @@ -<div class="page-header"> - <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"> - - <?= $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->label(t('Description'), 'description') ?> - <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?> - - <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> -</form> diff --git a/sources/app/Template/category/index.php b/sources/app/Template/category/index.php deleted file mode 100644 index a103d89..0000000 --- a/sources/app/Template/category/index.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php if (! empty($categories)): ?> -<div class="page-header"> - <h2><?= t('Categories') ?></h2> -</div> -<table> - <tr> - <th><?= t('Category Name') ?></th> - <th class="column-8"><?= t('Actions') ?></th> - </tr> - <?php foreach ($categories as $category_id => $category_name): ?> - <tr> - <td><?= $this->text->e($category_name) ?></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> - <?= $this->url->link(t('Edit'), 'CategoryController', 'edit', array('project_id' => $project['id'], 'category_id' => $category_id), false, 'popover') ?> - </li> - <li> - <?= $this->url->link(t('Remove'), 'CategoryController', 'confirm', array('project_id' => $project['id'], 'category_id' => $category_id), false, 'popover') ?> - </li> - </ul> - </div> - </td> - </tr> - <?php endforeach ?> -</table> -<?php endif ?> - -<div class="page-header"> - <h2><?= t('Add a new category') ?></h2> -</div> -<form method="post" action="<?= $this->url->href('CategoryController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off"> - - <?= $this->form->csrf() ?> - <?= $this->form->hidden('project_id', $values) ?> - - <?= $this->form->label(t('Category Name'), 'name') ?> - <?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> diff --git a/sources/app/Template/category/remove.php b/sources/app/Template/category/remove.php deleted file mode 100644 index e7b9c9b..0000000 --- a/sources/app/Template/category/remove.php +++ /dev/null @@ -1,17 +0,0 @@ -<section id="main"> - <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="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> diff --git a/sources/app/Template/column/create.php b/sources/app/Template/column/create.php deleted file mode 100644 index 023de52..0000000 --- a/sources/app/Template/column/create.php +++ /dev/null @@ -1,24 +0,0 @@ -<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"> - - <?= $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->label(t('Task limit'), 'task_limit') ?> - <?= $this->form->number('task_limit', $values, $errors) ?> - - <?= $this->form->label(t('Description'), 'description') ?> - <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?> - - <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> -</form> diff --git a/sources/app/Template/column/edit.php b/sources/app/Template/column/edit.php deleted file mode 100644 index a742e4b..0000000 --- a/sources/app/Template/column/edit.php +++ /dev/null @@ -1,26 +0,0 @@ -<div class="page-header"> - <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"> - - <?= $this->form->csrf() ?> - - <?= $this->form->hidden('id', $values) ?> - <?= $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->label(t('Task limit'), 'task_limit') ?> - <?= $this->form->number('task_limit', $values, $errors) ?> - - <?= $this->form->label(t('Description'), 'description') ?> - <?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?> - - <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> -</form> diff --git a/sources/app/Template/column/index.php b/sources/app/Template/column/index.php deleted file mode 100644 index 04760a1..0000000 --- a/sources/app/Template/column/index.php +++ /dev/null @@ -1,56 +0,0 @@ -<div class="page-header"> - <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') ?> - </li> - </ul> -</div> - -<?php if (empty($columns)): ?> - <p class="alert alert-error"><?= t('Your board doesn\'t have any columns!') ?></p> -<?php else: ?> - <table - class="columns-table table-stripped" - data-save-position-url="<?= $this->url->href('ColumnController', 'move', array('project_id' => $project['id'])) ?>"> - <thead> - <tr> - <th class="column-70"><?= t('Column title') ?></th> - <th class="column-25"><?= t('Task limit') ?></th> - <th class="column-5"><?= t('Actions') ?></th> - </tr> - </thead> - <tbody> - <?php foreach ($columns as $column): ?> - <tr data-column-id="<?= $column['id'] ?>"> - <td> - <i class="fa fa-arrows-alt draggable-row-handle" title="<?= t('Change column position') ?>"></i> - <?= $this->text->e($column['title']) ?> - <?php if (! empty($column['description'])): ?> - <span class="tooltip" title="<?= $this->text->markdownAttribute($column['description']) ?>"> - <i class="fa fa-info-circle"></i> - </span> - <?php endif ?> - </td> - <td> - <?= $this->text->e($column['task_limit']) ?> - </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> - <?= $this->url->link(t('Edit'), 'ColumnController', 'edit', array('project_id' => $project['id'], 'column_id' => $column['id']), false, 'popover') ?> - </li> - <li> - <?= $this->url->link(t('Remove'), 'ColumnController', 'confirm', array('project_id' => $project['id'], 'column_id' => $column['id']), false, 'popover') ?> - </li> - </ul> - </div> - </td> - </tr> - <?php endforeach ?> - </tbody> - </table> -<?php endif ?> diff --git a/sources/app/Template/column/remove.php b/sources/app/Template/column/remove.php deleted file mode 100644 index b231a9a..0000000 --- a/sources/app/Template/column/remove.php +++ /dev/null @@ -1,15 +0,0 @@ -<div class="page-header"> - <h2><?= t('Remove a column') ?></h2> -</div> - -<div class="confirm"> - <p class="alert alert-info"> - <?= t('Do you really want to remove this column: "%s"?', $column['title']) ?> - <?= 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'], 'remove' => 'yes'), true, 'btn btn-red') ?> - <?= t('or') ?> <?= $this->url->link(t('cancel'), 'ColumnController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?> - </div> -</div> diff --git a/sources/app/Template/comment/create.php b/sources/app/Template/comment/create.php deleted file mode 100644 index 0358107..0000000 --- a/sources/app/Template/comment/create.php +++ /dev/null @@ -1,29 +0,0 @@ -<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"> - <?= $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> - - <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> -</form> diff --git a/sources/app/Template/comment/edit.php b/sources/app/Template/comment/edit.php deleted file mode 100644 index f69fc0c..0000000 --- a/sources/app/Template/comment/edit.php +++ /dev/null @@ -1,27 +0,0 @@ -<div class="page-header"> - <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"> - - <?= $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> - - <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> -</form> diff --git a/sources/app/Template/comment/remove.php b/sources/app/Template/comment/remove.php deleted file mode 100644 index 55587b6..0000000 --- a/sources/app/Template/comment/remove.php +++ /dev/null @@ -1,21 +0,0 @@ -<div class="page-header"> - <h2><?= t('Remove a comment') ?></h2> -</div> - -<div class="confirm"> - <p class="alert alert-info"> - <?= t('Do you really want to remove this comment?') ?> - </p> - - <?= $this->render('comment/show', array( - 'comment' => $comment, - 'task' => $task, - '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> -</div> diff --git a/sources/app/Template/comment/show.php b/sources/app/Template/comment/show.php deleted file mode 100644 index 8419a14..0000000 --- a/sources/app/Template/comment/show.php +++ /dev/null @@ -1,39 +0,0 @@ -<div class="comment <?= isset($preview) ? 'comment-preview' : '' ?>" id="comment-<?= $comment['id'] ?>"> - - <?= $this->avatar->render($comment['user_id'], $comment['username'], $comment['name'], $comment['email'], $comment['avatar_path']) ?> - - <div class="comment-title"> - <?php if (! empty($comment['username'])): ?> - <span class="comment-username"><?= $this->text->e($comment['name'] ?: $comment['username']) ?></span> - <?php endif ?> - - <span class="comment-date"><?= $this->dt->datetime($comment['date_creation']) ?></span> - </div> - - <div class="comment-content"> - <div class="markdown"> - <?= $this->text->markdown($comment['comment'], isset($is_public) && $is_public) ?> - </div> - </div> - - <?php if (! isset($hide_actions)): ?> - <div class="comment-actions"> - <ul> - <li> - <i class="fa fa-link fa-fw"></i> - <a href="#comment-<?= $comment['id'] ?>"><?= t('link') ?></a> - </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') ?> - </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') ?> - </li> - <?php endif ?> - </ul> - </div> - <?php endif ?> -</div> diff --git a/sources/app/Template/comments/create.php b/sources/app/Template/comments/create.php deleted file mode 100644 index 3fa6ddc..0000000 --- a/sources/app/Template/comments/create.php +++ /dev/null @@ -1,24 +0,0 @@ -<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( - '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> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> diff --git a/sources/app/Template/comments/show.php b/sources/app/Template/comments/show.php deleted file mode 100644 index 43f6b2c..0000000 --- a/sources/app/Template/comments/show.php +++ /dev/null @@ -1,33 +0,0 @@ -<section class="accordion-section <?= empty($comments) ? 'accordion-collapsed' : '' ?>"> - <div class="accordion-title"> - <h3><a href="#" class="fa accordion-toggle"></a> <?= t('Comments') ?></h3> - </div> - <div class="accordion-content" id="comments"> - <?php if (!isset($is_public) || !$is_public): ?> - <div class="comment-sorting"> - <i class="fa fa-sort"></i> - <?= $this->url->link(t('change sorting'), 'CommentController', 'toggleSorting', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> - </div> - <?php endif ?> - <?php foreach ($comments as $comment): ?> - <?= $this->render('comment/show', array( - 'comment' => $comment, - 'task' => $task, - 'project' => $project, - 'editable' => $editable, - 'is_public' => isset($is_public) && $is_public, - )) ?> - <?php endforeach ?> - - <?php if ($editable): ?> - <?= $this->render('comments/create', array( - 'values' => array( - 'user_id' => $this->user->getId(), - 'task_id' => $task['id'], - ), - 'errors' => array(), - 'task' => $task, - )) ?> - <?php endif ?> - </div> -</section> diff --git a/sources/app/Template/config/about.php b/sources/app/Template/config/about.php deleted file mode 100644 index 8e2d132..0000000 --- a/sources/app/Template/config/about.php +++ /dev/null @@ -1,86 +0,0 @@ -<div class="page-header"> - <h2><?= t('About') ?></h2> -</div> -<div class="listing"> - <ul> - <li> - <?= t('Official website:') ?> - <a href="https://kanboard.net/" target="_blank" rel="noreferer">https://kanboard.net/</a> - </li> - <li> - <?= t('Author:') ?> - <strong>Frédéric Guillot</strong> (<a href="https://github.com/fguillot/kanboard/blob/master/CONTRIBUTORS.md" target="_blank"><?= t('contributors') ?></a>) - </li> - <li> - <?= t('License:') ?> - <strong>MIT</strong> - </li> - </ul> -</div> - -<div class="page-header"> - <h2><?= t('Configuration') ?></h2> -</div> -<div class="listing"> - <ul> - <li> - <?= t('Application version:') ?> - <strong><?= APP_VERSION ?></strong> - </li> - <li> - <?= t('PHP version:') ?> - <strong><?= PHP_VERSION ?></strong> - </li> - <li> - <?= t('PHP SAPI:') ?> - <strong><?= PHP_SAPI ?></strong> - </li> - <li> - <?= t('OS version:') ?> - <strong><?= php_uname('s').' '.php_uname('r') ?></strong> - </li> - <li> - <?= t('Database driver:') ?> - <strong><?= DB_DRIVER ?></strong> - </li> - <li> - <?= t('Database version:') ?> - <strong><?= $this->text->e($db_version) ?></strong> - </li> - <li> - <?= t('Browser:') ?> - <strong><?= $this->text->e($user_agent) ?></strong> - </li> - </ul> -</div> - -<?php if (DB_DRIVER === 'sqlite'): ?> - <div class="page-header"> - <h2><?= t('Database') ?></h2> - </div> - <div class="listing"> - <ul> - <li> - <?= t('Database size:') ?> - <strong><?= $this->text->bytes($db_size) ?></strong> - </li> - <li> - <?= $this->url->link(t('Download the database'), 'ConfigController', 'downloadDb', array(), true) ?>  - <?= t('(Gzip compressed Sqlite file)') ?> - </li> - <li> - <?= $this->url->link(t('Optimize the database'), 'ConfigController', 'optimizeDb', array(), true) ?>  - <?= t('(VACUUM command)') ?> - </li> - </ul> - </div> -<?php endif ?> - -<?= $this->render('config/keyboard_shortcuts') ?> - -<div class="page-header"> - <h2><?= t('License') ?></h2> -</div> -<div class="listing"> -<?= nl2br(file_get_contents(ROOT_DIR.DIRECTORY_SEPARATOR.'LICENSE')) ?> -</div> diff --git a/sources/app/Template/config/api.php b/sources/app/Template/config/api.php deleted file mode 100644 index 95f7735..0000000 --- a/sources/app/Template/config/api.php +++ /dev/null @@ -1,18 +0,0 @@ -<div class="page-header"> - <h2><?= t('API') ?></h2> -</div> -<section class="listing"> - <ul> - <li> - <?= t('API token:') ?> - <strong><?= $this->text->e($values['api_token']) ?></strong> - </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) ?> - </li> - </ul> -</section> diff --git a/sources/app/Template/config/application.php b/sources/app/Template/config/application.php deleted file mode 100644 index 0f842f6..0000000 --- a/sources/app/Template/config/application.php +++ /dev/null @@ -1,38 +0,0 @@ -<div class="page-header"> - <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) ?> - - <?= $this->form->label(t('Timezone'), 'application_timezone') ?> - <?= $this->form->select('application_timezone', $timezones, $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->label(t('Date and time format'), 'application_datetime_format') ?> - <?= $this->form->select('application_datetime_format', $datetime_formats, $values, $errors) ?> - - <?= $this->form->label(t('Time format'), 'application_time_format') ?> - <?= $this->form->select('application_time_format', $time_formats, $values, $errors) ?> - - <?= $this->form->checkbox('password_reset', t('Enable "Forget Password"'), 1, $values['password_reset'] == 1) ?> - - <?= $this->form->label(t('Custom Stylesheet'), 'application_stylesheet') ?> - <?= $this->form->textarea('application_stylesheet', $values, $errors) ?> - - <?= $this->hook->render('template:config:application', array('values' => $values, 'errors' => $errors)) ?> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> diff --git a/sources/app/Template/config/board.php b/sources/app/Template/config/board.php deleted file mode 100644 index 62a736e..0000000 --- a/sources/app/Template/config/board.php +++ /dev/null @@ -1,23 +0,0 @@ -<div class="page-header"> - <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> - - <?= $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> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> diff --git a/sources/app/Template/config/calendar.php b/sources/app/Template/config/calendar.php deleted file mode 100644 index 90e034e..0000000 --- a/sources/app/Template/config/calendar.php +++ /dev/null @@ -1,34 +0,0 @@ -<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> - <?= $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> - - <div class="listing"> - <h3><?= t('User calendar view') ?></h3> - <?= $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> - - <div class="listing"> - <h3><?= t('Subtasks time tracking') ?></h3> - <?= $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> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> -</section> diff --git a/sources/app/Template/config/email.php b/sources/app/Template/config/email.php deleted file mode 100644 index 6ff76ec..0000000 --- a/sources/app/Template/config/email.php +++ /dev/null @@ -1,18 +0,0 @@ -<div class="page-header"> - <h2><?= t('Email settings') ?></h2> -</div> -<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.'"')) ?> - - <?= $this->form->label(t('Email transport'), 'mail_transport') ?> - <?= $this->form->select('mail_transport', $mail_transports, $values, $errors) ?> - - <?= $this->hook->render('template:config:email', array('values' => $values, 'errors' => $errors)) ?> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> diff --git a/sources/app/Template/config/integrations.php b/sources/app/Template/config/integrations.php deleted file mode 100644 index 3ba4e86..0000000 --- a/sources/app/Template/config/integrations.php +++ /dev/null @@ -1,17 +0,0 @@ -<div class="page-header"> - <h2><?= t('Integration with third-party services') ?></h2> -</div> - -<form method="post" action="<?= $this->url->href('ConfigController', 'save', array('redirect' => 'integrations')) ?>" autocomplete="off"> - <?= $this->form->csrf() ?> - <?= $this->hook->render('template:config:integrations', array('values' => $values)) ?> - - <h3><img src="<?= $this->url->dir() ?>assets/img/gravatar-icon.png"/> <?= t('Gravatar') ?></h3> - <div class="listing"> - <?= $this->form->checkbox('integration_gravatar', t('Enable Gravatar images'), 1, $values['integration_gravatar'] == 1) ?> - </div> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> diff --git a/sources/app/Template/config/keyboard_shortcuts.php b/sources/app/Template/config/keyboard_shortcuts.php deleted file mode 100644 index 1b1a947..0000000 --- a/sources/app/Template/config/keyboard_shortcuts.php +++ /dev/null @@ -1,35 +0,0 @@ -<div class="page-header"> - <h2><?= t('Keyboard shortcuts') ?></h2> -</div> -<div class="listing"> - <h3><?= t('Board/Calendar/List view') ?></h3> - <ul> - <li><?= t('Switch to the project overview') ?> = <strong>v o</strong></li> - <li><?= t('Switch to the board view') ?> = <strong>v b</strong></li> - <li><?= t('Switch to the calendar view') ?> = <strong>v c</strong></li> - <li><?= t('Switch to the list view') ?> = <strong>v l</strong></li> - <li><?= t('Switch to the Gantt chart view') ?> = <strong>v g</strong></li> - </ul> - <h3><?= t('Board view') ?></h3> - <ul> - <li><?= t('New task') ?> = <strong>n</strong></li> - <li><?= t('Expand/collapse tasks') ?> = <strong>s</strong></li> - <li><?= t('Compact/wide view') ?> = <strong>c</strong></li> - </ul> - <h3><?= t('Task view') ?></h3> - <ul> - <li><?= t('Edit task') ?> = <strong>e</strong></li> - <li><?= t('New subtask') ?> = <strong>s</strong></li> - <li><?= t('New comment') ?> = <strong>c</strong></li> - <li><?= t('New internal link') ?> = <strong>l</strong></li> - </ul> - <h3><?= t('Application') ?></h3> - <ul> - <li><?= t('Display list of keyboard shortcuts') ?> = <strong>?</strong></li> - <li><?= t('Open board switcher') ?> = <strong>b</strong></li> - <li><?= t('Go to the search/filter box') ?> = <strong>f</strong></li> - <li><?= t('Reset the search/filter box') ?> = <strong>r</strong></li> - <li><?= t('Close dialog box') ?> = <strong>ESC</strong></li> - <li><?= t('Submit a form') ?> = <strong>CTRL+ENTER</strong> <?= t('or') ?> <strong>⌘+ENTER</strong></li> - </ul> -</div> diff --git a/sources/app/Template/config/layout.php b/sources/app/Template/config/layout.php deleted file mode 100644 index 6eafa59..0000000 --- a/sources/app/Template/config/layout.php +++ /dev/null @@ -1,9 +0,0 @@ -<section id="main"> - <section class="sidebar-container" id="config-section"> - <?= $this->render($sidebar_template) ?> - - <div class="sidebar-content"> - <?= $content_for_sublayout ?> - </div> - </section> -</section> diff --git a/sources/app/Template/config/project.php b/sources/app/Template/config/project.php deleted file mode 100644 index 6d8d131..0000000 --- a/sources/app/Template/config/project.php +++ /dev/null @@ -1,27 +0,0 @@ -<div class="page-header"> - <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) ?> - - <?= $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->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) ?> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> diff --git a/sources/app/Template/config/sidebar.php b/sources/app/Template/config/sidebar.php deleted file mode 100644 index e304f0d..0000000 --- a/sources/app/Template/config/sidebar.php +++ /dev/null @@ -1,42 +0,0 @@ -<div class="sidebar"> - <h2><?= t('Actions') ?></h2> - <ul> - <li <?= $this->app->checkMenuSelection('ConfigController', 'index') ?>> - <?= $this->url->link(t('About'), 'ConfigController', 'index') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'application') ?>> - <?= $this->url->link(t('Application settings'), 'ConfigController', 'application') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'email') ?>> - <?= $this->url->link(t('Email settings'), 'ConfigController', 'email') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'project') ?>> - <?= $this->url->link(t('Project settings'), 'ConfigController', 'project') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'board') ?>> - <?= $this->url->link(t('Board settings'), 'ConfigController', 'board') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'calendar') ?>> - <?= $this->url->link(t('Calendar settings'), 'ConfigController', 'calendar') ?> - </li> - <li <?= $this->app->checkMenuSelection('TagController', 'index') ?>> - <?= $this->url->link(t('Tags management'), 'TagController', 'index') ?> - </li> - <li <?= $this->app->checkMenuSelection('LinkController') ?>> - <?= $this->url->link(t('Link settings'), 'LinkController', 'index') ?> - </li> - <li <?= $this->app->checkMenuSelection('CurrencyController', 'index') ?>> - <?= $this->url->link(t('Currency rates'), 'CurrencyController', 'index') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'integrations') ?>> - <?= $this->url->link(t('Integrations'), 'ConfigController', 'integrations') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'webhook') ?>> - <?= $this->url->link(t('Webhooks'), 'ConfigController', 'webhook') ?> - </li> - <li <?= $this->app->checkMenuSelection('ConfigController', 'api') ?>> - <?= $this->url->link(t('API'), 'ConfigController', 'api') ?> - </li> - <?= $this->hook->render('template:config:sidebar') ?> - </ul> -</div> diff --git a/sources/app/Template/config/webhook.php b/sources/app/Template/config/webhook.php deleted file mode 100644 index e324587..0000000 --- a/sources/app/Template/config/webhook.php +++ /dev/null @@ -1,31 +0,0 @@ -<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') ?> - <?= $this->form->text('webhook_url', $values, $errors) ?> - - <div class="form-actions"> - <button type="submit" class="btn btn-blue"><?= t('Save') ?></button> - </div> -</form> -</section> - -<div class="page-header"> - <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> diff --git a/sources/app/Template/currency/index.php b/sources/app/Template/currency/index.php deleted file mode 100644 index 9881cee..0000000 --- a/sources/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-stripped"> - <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/sources/app/Template/custom_filter/add.php b/sources/app/Template/custom_filter/add.php deleted file mode 100644 index 3801cc3..0000000 --- a/sources/app/Template/custom_filter/add.php +++ /dev/null @@ -1,24 +0,0 @@ -<div class="page-header"> - <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->label(t('Filter'), 'filter') ?> - <?= $this->form->text('filter', $values, $errors, array('required', 'maxlength="100"')) ?> - - <?php if ($this->user->hasProjectAccess('ProjectEditController', 'edit', $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> -</form> diff --git a/sources/app/Template/custom_filter/edit.php b/sources/app/Template/custom_filter/edit.php deleted file mode 100644 index 26da8da..0000000 --- a/sources/app/Template/custom_filter/edit.php +++ /dev/null @@ -1,32 +0,0 @@ -<div class="page-header"> - <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"> - - <?= $this->form->csrf() ?> - - <?= $this->form->hidden('id', $values) ?> - <?= $this->form->hidden('user_id', $values) ?> - <?= $this->form->hidden('project_id', $values) ?> - - <?= $this->form->label(t('Name'), 'name') ?> - <?= $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'])): ?> - <?= $this->form->checkbox('is_shared', t('Share with all project members'), 1, $values['is_shared'] == 1) ?> - <?php else: ?> - <?= $this->form->hidden('is_shared', $values) ?> - <?php endif ?> - - <?= $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> -</form> diff --git a/sources/app/Template/custom_filter/index.php b/sources/app/Template/custom_filter/index.php deleted file mode 100644 index 08c8040..0000000 --- a/sources/app/Template/custom_filter/index.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php if (! empty($custom_filters)): ?> -<div class="page-header"> - <h2><?= t('Custom filters') ?></h2> -</div> -<div> - <table> - <tr> - <th class="column-15"><?= t('Name') ?></th> - <th class="column-30"><?= t('Filter') ?></th> - <th class="column-10"><?= t('Shared') ?></th> - <th class="column-15"><?= t('Append/Replace') ?></th> - <th class="column-25"><?= t('Owner') ?></th> - <th class="column-5"><?= t('Actions') ?></th> - </tr> - <?php foreach ($custom_filters as $filter): ?> - <tr> - <td><?= $this->text->e($filter['name']) ?></td> - <td><?= $this->text->e($filter['filter']) ?></td> - <td> - <?php if ($filter['is_shared'] == 1): ?> - <?= t('Yes') ?> - <?php else: ?> - <?= t('No') ?> - <?php endif ?> - </td> - <td> - <?php if ($filter['append'] == 1): ?> - <?= t('Append') ?> - <?php else: ?> - <?= t('Replace') ?> - <?php endif ?> - </td> - <td><?= $this->text->e($filter['owner_name'] ?: $filter['owner_username']) ?></td> - <td> - <?php if ($filter['user_id'] == $this->user->getId() || $this->user->hasProjectAccess('CustomFilterController', 'edit', $project['id'])): ?> - <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> - </ul> - </div> - <?php endif ?> - </td> - </tr> - <?php endforeach ?> - </table> -</div> -<?php endif ?> - -<?= $this->render('custom_filter/add', array('project' => $project, 'values' => $values, 'errors' => $errors)) ?> diff --git a/sources/app/Template/custom_filter/remove.php b/sources/app/Template/custom_filter/remove.php deleted file mode 100644 index 609f19b..0000000 --- a/sources/app/Template/custom_filter/remove.php +++ /dev/null @@ -1,17 +0,0 @@ -<section id="main"> - <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="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> diff --git a/sources/app/Template/dashboard/activity.php b/sources/app/Template/dashboard/activity.php deleted file mode 100644 index 71a67fb..0000000 --- a/sources/app/Template/dashboard/activity.php +++ /dev/null @@ -1,4 +0,0 @@ -<div class="page-header"> - <h2><?= t('My activity stream') ?></h2> -</div> -<?= $this->render('event/events', array('events' => $events)) ?> \ No newline at end of file diff --git a/sources/app/Template/dashboard/calendar.php b/sources/app/Template/dashboard/calendar.php deleted file mode 100644 index 75c96d8..0000000 --- a/sources/app/Template/dashboard/calendar.php +++ /dev/null @@ -1,5 +0,0 @@ -<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> diff --git a/sources/app/Template/dashboard/layout.php b/sources/app/Template/dashboard/layout.php deleted file mode 100644 index 795537a..0000000 --- a/sources/app/Template/dashboard/layout.php +++ /dev/null @@ -1,32 +0,0 @@ -<section id="main"> - <div class="page-header"> - <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') ?> - </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') ?> - </li> - <?php endif ?> - <li> - <i class="fa fa-search fa-fw"></i> - <?= $this->url->link(t('Search'), 'SearchController', 'index') ?> - </li> - <li> - <i class="fa fa-folder fa-fw"></i> - <?= $this->url->link(t('Project management'), 'ProjectListController', 'show') ?> - </li> - </ul> - </div> - <section class="sidebar-container" id="dashboard"> - <?= $this->render($sidebar_template, array('user' => $user)) ?> - <div class="sidebar-content"> - <?= $content_for_sublayout ?> - </div> - </section> -</section> diff --git a/sources/app/Template/dashboard/notifications.php b/sources/app/Template/dashboard/notifications.php deleted file mode 100644 index 3b70b49..0000000 --- a/sources/app/Template/dashboard/notifications.php +++ /dev/null @@ -1,55 +0,0 @@ -<div class="page-header"> - <h2><?= t('My notifications') ?></h2> - -<?php if (empty($notifications)): ?> -</div> -<p class="alert"><?= t('No new notifications.') ?></p> -<?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'])) ?> - </li> - </ul> -</div> - - <table class="table-fixed table-small"> - <tr> - <th><?= t('Notification') ?></th> - <th class="column-20"><?= t('Date') ?></th> - <th class="column-15"><?= t('Action') ?></th> - </tr> - <?php foreach ($notifications as $notification): ?> - <tr> - <td> - <?php if ($this->text->contains($notification['event_name'], 'subtask')): ?> - <i class="fa fa-tasks fa-fw"></i> - <?php elseif ($this->text->contains($notification['event_name'], 'task.move')): ?> - <i class="fa fa-arrows-alt fa-fw"></i> - <?php elseif ($this->text->contains($notification['event_name'], 'task.overdue')): ?> - <i class="fa fa-calendar-times-o fa-fw"></i> - <?php elseif ($this->text->contains($notification['event_name'], 'task')): ?> - <i class="fa fa-newspaper-o fa-fw"></i> - <?php elseif ($this->text->contains($notification['event_name'], 'comment')): ?> - <i class="fa fa-comments-o fa-fw"></i> - <?php elseif ($this->text->contains($notification['event_name'], 'file')): ?> - <i class="fa fa-file-o fa-fw"></i> - <?php endif ?> - - <?php if ($this->text->contains($notification['event_name'], 'task.overdue') && count($notification['event_data']['tasks']) > 1): ?> - <?= $notification['title'] ?> - <?php else: ?> - <?= $this->url->link($notification['title'], 'WebNotificationController', 'redirect', array('notification_id' => $notification['id'], 'user_id' => $user['id'])) ?> - <?php endif ?> - </td> - <td> - <?= $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'])) ?> - </td> - </tr> - <?php endforeach ?> - </table> -<?php endif ?> diff --git a/sources/app/Template/dashboard/projects.php b/sources/app/Template/dashboard/projects.php deleted file mode 100644 index 962e4d8..0000000 --- a/sources/app/Template/dashboard/projects.php +++ /dev/null @@ -1,55 +0,0 @@ -<div class="page-header"> - <h2><?= $this->url->link(t('My projects'), 'DashboardController', 'projects', array('user_id' => $user['id'])) ?> (<?= $paginator->getTotal() ?>)</h2> -</div> -<?php if ($paginator->isEmpty()): ?> - <p class="alert"><?= t('Your are not member of any project.') ?></p> -<?php else: ?> - <table class="table-fixed table-small"> - <tr> - <th class="column-5"><?= $paginator->order('Id', 'id') ?></th> - <th class="column-3"><?= $paginator->order('<i class="fa fa-lock fa-fw" title="'.t('Private project').'"></i>', 'is_private') ?></th> - <th class="column-25"><?= $paginator->order(t('Project'), \Kanboard\Model\ProjectModel::TABLE.'.name') ?></th> - <th class="column-10"><?= t('Tasks') ?></th> - <th><?= t('Columns') ?></th> - </tr> - <?php foreach ($paginator->getCollection() as $project): ?> - <tr> - <td> - <?= $this->render('project/dropdown', array('project' => $project)) ?> - </td> - <td> - <?php if ($project['is_private']): ?> - <i class="fa fa-lock fa-fw" title="<?= t('Private project') ?>"></i> - <?php endif ?> - </td> - <td> - <?php if ($this->user->hasProjectAccess('TaskGanttController', 'show', $project['id'])): ?> - <?= $this->url->link('<i class="fa fa-sliders fa-fw"></i>', 'TaskGanttController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Gantt chart')) ?> - <?php endif ?> - - <?= $this->url->link('<i class="fa fa-list"></i>', 'TaskListController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('List')) ?>  - <?= $this->url->link('<i class="fa fa-calendar"></i>', 'CalendarController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Calendar')) ?>  - - <?= $this->url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?> - <?php if (! empty($project['description'])): ?> - <span class="tooltip" title="<?= $this->text->markdownAttribute($project['description']) ?>"> - <i class="fa fa-info-circle"></i> - </span> - <?php endif ?> - </td> - <td> - <?= $project['nb_active_tasks'] ?> - </td> - <td class="dashboard-project-stats"> - <?php foreach ($project['columns'] as $column): ?> - <strong title="<?= t('Task count') ?>"><?= $column['nb_tasks'] ?></strong> - <span><?= $this->text->e($column['title']) ?></span> - <?php endforeach ?> - </td> - - </tr> - <?php endforeach ?> - </table> - - <?= $paginator ?> -<?php endif ?> diff --git a/sources/app/Template/dashboard/show.php b/sources/app/Template/dashboard/show.php deleted file mode 100644 index 637b60f..0000000 --- a/sources/app/Template/dashboard/show.php +++ /dev/null @@ -1,12 +0,0 @@ -<div class="filter-box"> - <form method="get" action="<?= $this->url->dir() ?>" class="search"> - <?= $this->form->hidden('controller', array('controller' => 'SearchController')) ?> - <?= $this->form->hidden('action', array('action' => 'index')) ?> - <?= $this->form->text('search', array(), array(), array('placeholder="'.t('Search').'"'), 'form-input-large') ?> - <?= $this->render('app/filters_helper') ?> - </form> -</div> - -<?= $this->render('dashboard/projects', array('paginator' => $project_paginator, 'user' => $user)) ?> -<?= $this->render('dashboard/tasks', array('paginator' => $task_paginator, 'user' => $user)) ?> -<?= $this->render('dashboard/subtasks', array('paginator' => $subtask_paginator, 'user' => $user)) ?> diff --git a/sources/app/Template/dashboard/sidebar.php b/sources/app/Template/dashboard/sidebar.php deleted file mode 100644 index 86cc20f..0000000 --- a/sources/app/Template/dashboard/sidebar.php +++ /dev/null @@ -1,27 +0,0 @@ -<div class="sidebar"> - <h2><?= $this->text->e($user['name'] ?: $user['username']) ?></h2> - <ul> - <li <?= $this->app->checkMenuSelection('DashboardController', 'show') ?>> - <?= $this->url->link(t('Overview'), 'DashboardController', 'show', array('user_id' => $user['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('DashboardController', 'projects') ?>> - <?= $this->url->link(t('My projects'), 'DashboardController', 'projects', array('user_id' => $user['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('DashboardController', 'tasks') ?>> - <?= $this->url->link(t('My tasks'), 'DashboardController', 'tasks', array('user_id' => $user['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('DashboardController', 'subtasks') ?>> - <?= $this->url->link(t('My subtasks'), 'DashboardController', 'subtasks', array('user_id' => $user['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('DashboardController', 'calendar') ?>> - <?= $this->url->link(t('My calendar'), 'DashboardController', 'calendar', array('user_id' => $user['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('DashboardController', 'activity') ?>> - <?= $this->url->link(t('My activity stream'), 'DashboardController', 'activity', array('user_id' => $user['id'])) ?> - </li> - <li <?= $this->app->checkMenuSelection('DashboardController', 'notifications') ?>> - <?= $this->url->link(t('My notifications'), 'DashboardController', 'notifications', array('user_id' => $user['id'])) ?> - </li> - <?= $this->hook->render('template:dashboard:sidebar') ?> - </ul> -</div> diff --git a/sources/app/Template/dashboard/subtasks.php b/sources/app/Template/dashboard/subtasks.php deleted file mode 100644 index 8e0aa3c..0000000 --- a/sources/app/Template/dashboard/subtasks.php +++ /dev/null @@ -1,43 +0,0 @@ -<div class="page-header"> - <h2><?= $this->url->link(t('My subtasks'), 'DashboardController', 'subtasks', array('user_id' => $user['id'])) ?> (<?= $paginator->getTotal() ?>)</h2> -</div> -<?php if ($paginator->isEmpty()): ?> - <p class="alert"><?= t('There is nothing assigned to you.') ?></p> -<?php else: ?> - <table class="table-fixed table-small"> - <tr> - <th class="column-5"><?= $paginator->order('Id', 'tasks.id') ?></th> - <th class="column-20"><?= $paginator->order(t('Project'), 'project_name') ?></th> - <th><?= $paginator->order(t('Task'), 'task_name') ?></th> - <th><?= $paginator->order(t('Subtask'), 'title') ?></th> - <th class="column-20"><?= t('Time tracking') ?></th> - </tr> - <?php foreach ($paginator->getCollection() as $subtask): ?> - <tr> - <td class="task-table color-<?= $subtask['color_id'] ?>"> - <?= $this->render('task/dropdown', array('task' => array('id' => $subtask['task_id'], 'project_id' => $subtask['project_id']))) ?> - </td> - <td> - <?= $this->url->link($this->text->e($subtask['project_name']), 'BoardViewController', 'show', array('project_id' => $subtask['project_id'])) ?> - </td> - <td> - <?= $this->url->link($this->text->e($subtask['task_name']), 'TaskViewController', 'show', array('task_id' => $subtask['task_id'], 'project_id' => $subtask['project_id'])) ?> - </td> - <td> - <?= $this->subtask->toggleStatus($subtask, $subtask['project_id']) ?> - </td> - <td> - <?php if (! empty($subtask['time_spent'])): ?> - <strong><?= $this->text->e($subtask['time_spent']).'h' ?></strong> <?= t('spent') ?> - <?php endif ?> - - <?php if (! empty($subtask['time_estimated'])): ?> - <strong><?= $this->text->e($subtask['time_estimated']).'h' ?></strong> <?= t('estimated') ?> - <?php endif ?> - </td> - </tr> - <?php endforeach ?> - </table> - - <?= $paginator ?> -<?php endif ?> diff --git a/sources/app/Template/dashboard/tasks.php b/sources/app/Template/dashboard/tasks.php deleted file mode 100644 index 4b83a96..0000000 --- a/sources/app/Template/dashboard/tasks.php +++ /dev/null @@ -1,53 +0,0 @@ -<div class="page-header"> - <h2><?= $this->url->link(t('My tasks'), 'DashboardController', 'tasks', array('user_id' => $user['id'])) ?> (<?= $paginator->getTotal() ?>)</h2> -</div> -<?php if ($paginator->isEmpty()): ?> - <p class="alert"><?= t('There is nothing assigned to you.') ?></p> -<?php else: ?> - <table class="table-fixed table-small"> - <tr> - <th class="column-5"><?= $paginator->order('Id', 'tasks.id') ?></th> - <th class="column-20"><?= $paginator->order(t('Project'), 'project_name') ?></th> - <th><?= $paginator->order(t('Task'), 'title') ?></th> - <th class="column-5"><?= $paginator->order('Priority', 'tasks.priority') ?></th> - <th class="column-20"><?= t('Time tracking') ?></th> - <th class="column-10"><?= $paginator->order(t('Due date'), 'date_due') ?></th> - <th class="column-10"><?= $paginator->order(t('Column'), 'column_title') ?></th> - </tr> - <?php foreach ($paginator->getCollection() as $task): ?> - <tr> - <td class="task-table color-<?= $task['color_id'] ?>"> - <?= $this->render('task/dropdown', array('task' => $task)) ?> - </td> - <td> - <?= $this->url->link($this->text->e($task['project_name']), 'BoardViewController', 'show', array('project_id' => $task['project_id'])) ?> - </td> - <td> - <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> - </td> - <td> - <?php if ($task['priority'] >= 0): ?> - P<?= $this->text->e($task['priority'])?> - <?php endif?> - </td> - <td> - <?php if (! empty($task['time_spent'])): ?> - <strong><?= $this->text->e($task['time_spent']).'h' ?></strong> <?= t('spent') ?> - <?php endif ?> - - <?php if (! empty($task['time_estimated'])): ?> - <strong><?= $this->text->e($task['time_estimated']).'h' ?></strong> <?= t('estimated') ?> - <?php endif ?> - </td> - <td> - <?= $this->dt->date($task['date_due']) ?> - </td> - <td> - <?= $this->text->e($task['column_title']) ?> - </td> - </tr> - <?php endforeach ?> - </table> - - <?= $paginator ?> -<?php endif ?> diff --git a/sources/app/Template/doc/show.php b/sources/app/Template/doc/show.php deleted file mode 100644 index a8dbd76..0000000 --- a/sources/app/Template/doc/show.php +++ /dev/null @@ -1,13 +0,0 @@ -<section id="main"> - <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')) ?> - </li> - </ul> - </div> - <div class="markdown documentation"> - <?= $content ?> - </div> -</section> diff --git a/sources/app/Template/event/comment_create.php b/sources/app/Template/event/comment_create.php deleted file mode 100644 index 45132e6..0000000 --- a/sources/app/Template/event/comment_create.php +++ /dev/null @@ -1,11 +0,0 @@ -<p class="activity-title"> - <?= e('%s commented the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> - <div class="markdown"><?= $this->text->markdown($comment['comment']) ?></div> -</div> diff --git a/sources/app/Template/event/comment_update.php b/sources/app/Template/event/comment_update.php deleted file mode 100644 index 5a0821b..0000000 --- a/sources/app/Template/event/comment_update.php +++ /dev/null @@ -1,10 +0,0 @@ -<p class="activity-title"> - <?= e('%s updated a comment on the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/events.php b/sources/app/Template/event/events.php deleted file mode 100644 index c58376c..0000000 --- a/sources/app/Template/event/events.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php if (empty($events)): ?> - <p class="alert"><?= t('There is no activity yet.') ?></p> -<?php else: ?> - <?php foreach ($events as $event): ?> - <div class="activity-event"> - <?= $this->avatar->render( - $event['creator_id'], - $event['author_username'], - $event['author_name'], - $event['email'], - $event['avatar_path'] - ) ?> - - <div class="activity-content"> - <?= $event['event_content'] ?> - </div> - </div> - <?php endforeach ?> -<?php endif ?> - diff --git a/sources/app/Template/event/subtask_create.php b/sources/app/Template/event/subtask_create.php deleted file mode 100644 index 1bf36c0..0000000 --- a/sources/app/Template/event/subtask_create.php +++ /dev/null @@ -1,23 +0,0 @@ -<p class="activity-title"> - <?= e('%s created a subtask for the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> - - <ul> - <li> - <?= $this->text->e($subtask['title']) ?> (<strong><?= $this->text->e($subtask['status_name']) ?></strong>) - </li> - <li> - <?php if ($subtask['username']): ?> - <?= t('Assigned to %s with an estimate of %s/%sh', $subtask['name'] ?: $subtask['username'], $subtask['time_spent'], $subtask['time_estimated']) ?> - <?php else: ?> - <?= t('Not assigned, estimate of %sh', $subtask['time_estimated']) ?> - <?php endif ?> - </li> - </ul> -</div> diff --git a/sources/app/Template/event/subtask_update.php b/sources/app/Template/event/subtask_update.php deleted file mode 100644 index 201402f..0000000 --- a/sources/app/Template/event/subtask_update.php +++ /dev/null @@ -1,23 +0,0 @@ -<p class="activity-title"> - <?= e('%s updated a subtask for the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> - - <ul> - <li> - <?= $this->text->e($subtask['title']) ?> (<strong><?= $this->text->e($subtask['status_name']) ?></strong>) - </li> - <li> - <?php if ($subtask['username']): ?> - <?= t('Assigned to %s with an estimate of %s/%sh', $subtask['name'] ?: $subtask['username'], $subtask['time_spent'], $subtask['time_estimated']) ?> - <?php else: ?> - <?= t('Not assigned, estimate of %sh', $subtask['time_estimated']) ?> - <?php endif ?> - </li> - </ul> -</div> diff --git a/sources/app/Template/event/task_assignee_change.php b/sources/app/Template/event/task_assignee_change.php deleted file mode 100644 index 7c96222..0000000 --- a/sources/app/Template/event/task_assignee_change.php +++ /dev/null @@ -1,17 +0,0 @@ -<p class="activity-title"> - <?php $assignee = $task['assignee_name'] ?: $task['assignee_username'] ?> - - <?php if (! empty($assignee)): ?> - <?= e('%s changed the assignee of the task %s to %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), - $this->text->e($assignee) - ) ?> - <?php else: ?> - <?= e('%s remove the assignee of the task %s', $this->text->e($author), $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))) ?> - <?php endif ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/task_close.php b/sources/app/Template/event/task_close.php deleted file mode 100644 index 90ff920..0000000 --- a/sources/app/Template/event/task_close.php +++ /dev/null @@ -1,10 +0,0 @@ -<p class="activity-title"> - <?= e('%s closed the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/task_create.php b/sources/app/Template/event/task_create.php deleted file mode 100644 index 017a5ad..0000000 --- a/sources/app/Template/event/task_create.php +++ /dev/null @@ -1,10 +0,0 @@ -<p class="activity-title"> - <?= e('%s created the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/task_file_create.php b/sources/app/Template/event/task_file_create.php deleted file mode 100644 index d329529..0000000 --- a/sources/app/Template/event/task_file_create.php +++ /dev/null @@ -1,10 +0,0 @@ -<p class="activity-title"> - <?= e('%s attached a new file to the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($file['name']) ?></p> -</div> diff --git a/sources/app/Template/event/task_move_column.php b/sources/app/Template/event/task_move_column.php deleted file mode 100644 index f3155e4..0000000 --- a/sources/app/Template/event/task_move_column.php +++ /dev/null @@ -1,11 +0,0 @@ -<p class="activity-title"> - <?= e('%s moved the task %s to the column "%s"', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), - $this->text->e($task['column_title']) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/task_move_position.php b/sources/app/Template/event/task_move_position.php deleted file mode 100644 index ecdd02b..0000000 --- a/sources/app/Template/event/task_move_position.php +++ /dev/null @@ -1,12 +0,0 @@ -<p class="activity-title"> - <?= e('%s moved the task %s to the position #%d in the column "%s"', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), - $task['position'], - $this->text->e($task['column_title']) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/task_move_swimlane.php b/sources/app/Template/event/task_move_swimlane.php deleted file mode 100644 index fe9bfb5..0000000 --- a/sources/app/Template/event/task_move_swimlane.php +++ /dev/null @@ -1,18 +0,0 @@ -<p class="activity-title"> - <?php if ($task['swimlane_id'] == 0): ?> - <?= e('%s moved the task %s to the first swimlane', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <?php else: ?> - <?= e('%s moved the task %s to the swimlane "%s"', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), - $this->text->e($task['swimlane_name']) - ) ?> - <?php endif ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/task_open.php b/sources/app/Template/event/task_open.php deleted file mode 100644 index 548aa98..0000000 --- a/sources/app/Template/event/task_open.php +++ /dev/null @@ -1,10 +0,0 @@ -<p class="activity-title"> - <?= e('%s opened the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> -</div> diff --git a/sources/app/Template/event/task_update.php b/sources/app/Template/event/task_update.php deleted file mode 100644 index 7c7507c..0000000 --- a/sources/app/Template/event/task_update.php +++ /dev/null @@ -1,15 +0,0 @@ -<p class="activity-title"> - <?= e('%s updated the task %s', - $this->text->e($author), - $this->url->link(t('#%d', $task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) - ) ?> - <span class="activity-date"><?= $this->dt->datetime($date_creation) ?></span> -</p> -<div class="activity-description"> - <p class="activity-task-title"><?= $this->text->e($task['title']) ?></p> - <?php if (isset($changes)): ?> - <div class="activity-changes"> - <?= $this->render('task/changes', array('changes' => $changes, 'task' => $task)) ?> - </div> - <?php endif ?> -</div> diff --git a/sources/app/Template/export/sidebar.php b/sources/app/Template/export/sidebar.php deleted file mode 100644 index 55fbaee..0000000 --- a/sources/app/Template/export/sidebar.php +++ /dev/null @@ -1,18 +0,0 @@ -<div class="sidebar"> - <h2><?= t('Exports') ?></h2> - <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/sources/app/Template/export/subtasks.php b/sources/app/Template/export/subtasks.php deleted file mode 100644 index a82cb3d..0000000 --- a/sources/app/Template/export/subtasks.php +++ /dev/null @@ -1,24 +0,0 @@ -<div class="page-header"> - <h2><?= t('Subtasks exportation for "%s"', $project['name']) ?></h2> -</div> - -<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) ?> - <?= $this->form->hidden('project_id', $values) ?> - - <?= $this->form->label(t('Start Date'), 'from') ?> - <?= $this->form->text('from', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <?= $this->form->label(t('End Date'), 'to') ?> - <?= $this->form->text('to', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <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> - </div> -</form> \ No newline at end of file diff --git a/sources/app/Template/export/summary.php b/sources/app/Template/export/summary.php deleted file mode 100644 index 60aa306..0000000 --- a/sources/app/Template/export/summary.php +++ /dev/null @@ -1,24 +0,0 @@ -<div class="page-header"> - <h2><?= t('Daily project summary export for "%s"', $project['name']) ?></h2> -</div> - -<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) ?> - <?= $this->form->hidden('project_id', $values) ?> - - <?= $this->form->label(t('Start Date'), 'from') ?> - <?= $this->form->text('from', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <?= $this->form->label(t('End Date'), 'to') ?> - <?= $this->form->text('to', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <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> - </div> -</form> \ No newline at end of file diff --git a/sources/app/Template/export/tasks.php b/sources/app/Template/export/tasks.php deleted file mode 100644 index bed8ab9..0000000 --- a/sources/app/Template/export/tasks.php +++ /dev/null @@ -1,24 +0,0 @@ -<div class="page-header"> - <h2><?= t('Tasks exportation for "%s"', $project['name']) ?></h2> -</div> - -<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) ?> - <?= $this->form->hidden('project_id', $values) ?> - - <?= $this->form->label(t('Start Date'), 'from') ?> - <?= $this->form->text('from', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <?= $this->form->label(t('End Date'), 'to') ?> - <?= $this->form->text('to', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <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> - </div> -</form> \ No newline at end of file diff --git a/sources/app/Template/export/transitions.php b/sources/app/Template/export/transitions.php deleted file mode 100644 index 093930a..0000000 --- a/sources/app/Template/export/transitions.php +++ /dev/null @@ -1,24 +0,0 @@ -<div class="page-header"> - <h2><?= t('Task transitions export') ?></h2> -</div> - -<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) ?> - <?= $this->form->hidden('project_id', $values) ?> - - <?= $this->form->label(t('Start Date'), 'from') ?> - <?= $this->form->text('from', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <?= $this->form->label(t('End Date'), 'to') ?> - <?= $this->form->text('to', $values, $errors, array('required', 'placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?> - - <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> - </div> -</form> \ No newline at end of file diff --git a/sources/app/Template/feed/project.php b/sources/app/Template/feed/project.php deleted file mode 100644 index 213a04d..0000000 --- a/sources/app/Template/feed/project.php +++ /dev/null @@ -1,27 +0,0 @@ -<?= '<?xml version="1.0" encoding="utf-8"?>' ?> -<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"> - <title><?= t('%s\'s activity', $project['name']) ?> - - - - url->href('FeedController', 'project', array('token' => $project['token']), false, '', true) ?> - url->base() ?>assets/img/favicon.png - - - - <?= $e['event_title'] ?> - - - - - - text->e($e['author']) ?> - - - - ]]> - - - - diff --git a/sources/app/Template/feed/user.php b/sources/app/Template/feed/user.php deleted file mode 100644 index 0c45f03..0000000 --- a/sources/app/Template/feed/user.php +++ /dev/null @@ -1,27 +0,0 @@ -' ?> - - <?= t('Project activities for %s', $user['name'] ?: $user['username']) ?> - - - - url->href('FeedController', 'user', array('token' => $user['token']), false, '', true) ?> - url->base() ?>assets/img/favicon.png - - - - <?= $e['event_title'] ?> - - - - - - text->e($e['author']) ?> - - - - ]]> - - - - diff --git a/sources/app/Template/file_viewer/show.php b/sources/app/Template/file_viewer/show.php deleted file mode 100644 index e829a17..0000000 --- a/sources/app/Template/file_viewer/show.php +++ /dev/null @@ -1,14 +0,0 @@ - -
- - <?= $this->text->e($file['name']) ?> - -
- text->markdown($content) ?> -
- -
- -
diff --git a/sources/app/Template/group/associate.php b/sources/app/Template/group/associate.php deleted file mode 100644 index 8778756..0000000 --- a/sources/app/Template/group/associate.php +++ /dev/null @@ -1,20 +0,0 @@ - - -

- -
- form->csrf() ?> - form->hidden('group_id', $values) ?> - - form->label(t('User'), 'user_id') ?> - form->select('user_id', $users, $values, $errors, array('required'), 'chosen-select') ?> - -
- - - url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?> -
-
- diff --git a/sources/app/Template/group/dissociate.php b/sources/app/Template/group/dissociate.php deleted file mode 100644 index 50ef6d6..0000000 --- a/sources/app/Template/group/dissociate.php +++ /dev/null @@ -1,12 +0,0 @@ - -
-

- -
- url->link(t('Yes'), 'GroupListController', 'removeUser', array('group_id' => $group['id'], 'user_id' => $user['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'GroupListController', 'users', array('group_id' => $group['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/group/index.php b/sources/app/Template/group/index.php deleted file mode 100644 index 1062e18..0000000 --- a/sources/app/Template/group/index.php +++ /dev/null @@ -1,46 +0,0 @@ -
- - isEmpty()): ?> -

- - - - - - - - - getCollection() as $group): ?> - - - - - - - -
order(t('Id'), 'id') ?>order(t('External Id'), 'external_id') ?>order(t('Name'), 'name') ?>
- # - - text->e($group['external_id']) ?> - - url->link($this->text->e($group['name']), 'GroupListController', 'users', array('group_id' => $group['id'])) ?> - - -
- - - -
diff --git a/sources/app/Template/group/remove.php b/sources/app/Template/group/remove.php deleted file mode 100644 index 408b3d8..0000000 --- a/sources/app/Template/group/remove.php +++ /dev/null @@ -1,12 +0,0 @@ - -
-

- -
- url->link(t('Yes'), 'GroupListController', 'remove', array('group_id' => $group['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/group/users.php b/sources/app/Template/group/users.php deleted file mode 100644 index a4895ab..0000000 --- a/sources/app/Template/group/users.php +++ /dev/null @@ -1,43 +0,0 @@ -
- - isEmpty()): ?> -

- - - - - - - - - - getCollection() as $user): ?> - - - - - - - - -
order(t('Id'), 'id') ?>order(t('Username'), 'username') ?>order(t('Name'), 'name') ?>order(t('Email'), 'email') ?>
- url->link('#'.$user['id'], 'UserViewController', 'show', array('user_id' => $user['id'])) ?> - - url->link($this->text->e($user['username']), 'UserViewController', 'show', array('user_id' => $user['id'])) ?> - - text->e($user['name']) ?> - - text->e($user['email']) ?> - - - url->link(t('Remove this user'), 'GroupListController', 'dissociate', array('group_id' => $group['id'], 'user_id' => $user['id']), false, 'popover') ?> -
- - - -
diff --git a/sources/app/Template/group_creation/show.php b/sources/app/Template/group_creation/show.php deleted file mode 100644 index b219bd7..0000000 --- a/sources/app/Template/group_creation/show.php +++ /dev/null @@ -1,15 +0,0 @@ - -
- form->csrf() ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="100"')) ?> - -
- - - url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/group_modification/show.php b/sources/app/Template/group_modification/show.php deleted file mode 100644 index ddf0736..0000000 --- a/sources/app/Template/group_modification/show.php +++ /dev/null @@ -1,18 +0,0 @@ - -
- form->csrf() ?> - - form->hidden('id', $values) ?> - form->hidden('external_id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="100"')) ?> - -
- - - url->link(t('cancel'), 'GroupListController', 'index', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/header.php b/sources/app/Template/header.php deleted file mode 100644 index 13521ae..0000000 --- a/sources/app/Template/header.php +++ /dev/null @@ -1,118 +0,0 @@ -
- -
diff --git a/sources/app/Template/layout.php b/sources/app/Template/layout.php deleted file mode 100644 index 411237c..0000000 --- a/sources/app/Template/layout.php +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - asset->colorCss() ?> - asset->css('assets/css/vendor.min.css') ?> - asset->css('assets/css/app.min.css') ?> - asset->css('assets/css/print.min.css', true, 'print') ?> - asset->customCss() ?> - - - asset->js('assets/js/vendor.min.js') ?> - asset->js('assets/js/app.min.js') ?> - - - hook->asset('css', 'template:layout:css') ?> - hook->asset('js', 'template:layout:js') ?> - - - - - - - - - <?php if (isset($page_title)): ?> - <?= $this->text->e($page_title) ?> - <?php elseif (isset($title)): ?> - <?= $this->text->e($title) ?> - <?php else: ?> - Kanboard - <?php endif ?> - - - hook->render('template:layout:head') ?> - - - - - - - hook->render('template:layout:top') ?> - render('header', array( - 'title' => $title, - 'description' => isset($description) ? $description : '', - 'board_selector' => isset($board_selector) ? $board_selector : array(), - 'project' => isset($project) ? $project : array(), - )) ?> -
- app->flashMessage() ?> - -
- hook->render('template:layout:bottom') ?> - - - diff --git a/sources/app/Template/link/create.php b/sources/app/Template/link/create.php deleted file mode 100644 index 2399060..0000000 --- a/sources/app/Template/link/create.php +++ /dev/null @@ -1,18 +0,0 @@ - - -
- - form->csrf() ?> - - form->label(t('Label'), 'label') ?> - form->text('label', $values, $errors, array('required')) ?> - - form->label(t('Opposite label'), 'opposite_label') ?> - form->text('opposite_label', $values, $errors) ?> - -
- -
-
diff --git a/sources/app/Template/link/edit.php b/sources/app/Template/link/edit.php deleted file mode 100644 index 0ad7327..0000000 --- a/sources/app/Template/link/edit.php +++ /dev/null @@ -1,21 +0,0 @@ - - -
- - form->csrf() ?> - form->hidden('id', $values) ?> - - form->label(t('Label'), 'label') ?> - form->text('label', $values, $errors, array('required')) ?> - - form->label(t('Opposite label'), 'opposite_id') ?> - form->select('opposite_id', $labels, $values, $errors) ?> - -
- - - url->link(t('cancel'), 'link', 'index') ?> -
-
diff --git a/sources/app/Template/link/index.php b/sources/app/Template/link/index.php deleted file mode 100644 index 7e32069..0000000 --- a/sources/app/Template/link/index.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - -
- - - - | - - -
    - url->link(t('Edit'), 'LinkController', 'edit', array('link_id' => $link['id'])) ?> - - url->link(t('Remove'), 'LinkController', 'confirm', array('link_id' => $link['id'])) ?> -
-
- - - - -render('link/create', array('values' => $values, 'errors' => $errors)) ?> diff --git a/sources/app/Template/link/remove.php b/sources/app/Template/link/remove.php deleted file mode 100644 index b7fbef5..0000000 --- a/sources/app/Template/link/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'LinkController', 'remove', array('link_id' => $link['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'LinkController', 'index') ?> -
-
diff --git a/sources/app/Template/notification/comment_create.php b/sources/app/Template/notification/comment_create.php deleted file mode 100644 index fefc8ba..0000000 --- a/sources/app/Template/notification/comment_create.php +++ /dev/null @@ -1,11 +0,0 @@ -

text->e($task['title']) ?> (#)

- - -

- -

- - -text->markdown($comment['comment']) ?> - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/comment_update.php b/sources/app/Template/notification/comment_update.php deleted file mode 100644 index 2477d8b..0000000 --- a/sources/app/Template/notification/comment_update.php +++ /dev/null @@ -1,7 +0,0 @@ -

text->e($task['title']) ?> (#)

- -

- -text->markdown($comment['comment']) ?> - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/comment_user_mention.php b/sources/app/Template/notification/comment_user_mention.php deleted file mode 100644 index 372183d..0000000 --- a/sources/app/Template/notification/comment_user_mention.php +++ /dev/null @@ -1,7 +0,0 @@ -

- -

text->e($task['title']) ?>

- -text->markdown($comment['comment']) ?> - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/footer.php b/sources/app/Template/notification/footer.php deleted file mode 100644 index 6ac260c..0000000 --- a/sources/app/Template/notification/footer.php +++ /dev/null @@ -1,7 +0,0 @@ -
-Kanboard - - - - - - - diff --git a/sources/app/Template/notification/subtask_create.php b/sources/app/Template/notification/subtask_create.php deleted file mode 100644 index f6f8ba1..0000000 --- a/sources/app/Template/notification/subtask_create.php +++ /dev/null @@ -1,17 +0,0 @@ -

text->e($task['title']) ?> (#)

- -

- - - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/subtask_update.php b/sources/app/Template/notification/subtask_update.php deleted file mode 100644 index e6785f2..0000000 --- a/sources/app/Template/notification/subtask_update.php +++ /dev/null @@ -1,21 +0,0 @@ -

text->e($task['title']) ?> (#)

- -

- - - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_assignee_change.php b/sources/app/Template/notification/task_assignee_change.php deleted file mode 100644 index 53f7c5c..0000000 --- a/sources/app/Template/notification/task_assignee_change.php +++ /dev/null @@ -1,20 +0,0 @@ -

text->e($task['title']) ?> (#)

- - - - -

- text->markdown($task['description']) ?: t('There is no description.') ?> - - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_close.php b/sources/app/Template/notification/task_close.php deleted file mode 100644 index 4202e09..0000000 --- a/sources/app/Template/notification/task_close.php +++ /dev/null @@ -1,5 +0,0 @@ -

text->e($task['title']) ?> (#)

- -

- -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_create.php b/sources/app/Template/notification/task_create.php deleted file mode 100644 index 3cd68ac..0000000 --- a/sources/app/Template/notification/task_create.php +++ /dev/null @@ -1,43 +0,0 @@ -

text->e($task['title']) ?> (#)

- - - - -

- text->markdown($task['description']) ?> - - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_file_create.php b/sources/app/Template/notification/task_file_create.php deleted file mode 100644 index feab8dd..0000000 --- a/sources/app/Template/notification/task_file_create.php +++ /dev/null @@ -1,5 +0,0 @@ -

text->e($task['title']) ?> (#)

- -

- -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_move_column.php b/sources/app/Template/notification/task_move_column.php deleted file mode 100644 index 263adeb..0000000 --- a/sources/app/Template/notification/task_move_column.php +++ /dev/null @@ -1,11 +0,0 @@ -

text->e($task['title']) ?> (#)

- - - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_move_position.php b/sources/app/Template/notification/task_move_position.php deleted file mode 100644 index 263adeb..0000000 --- a/sources/app/Template/notification/task_move_position.php +++ /dev/null @@ -1,11 +0,0 @@ -

text->e($task['title']) ?> (#)

- - - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_move_swimlane.php b/sources/app/Template/notification/task_move_swimlane.php deleted file mode 100644 index cbbd620..0000000 --- a/sources/app/Template/notification/task_move_swimlane.php +++ /dev/null @@ -1,19 +0,0 @@ -

text->e($task['title']) ?> (#)

- - - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_open.php b/sources/app/Template/notification/task_open.php deleted file mode 100644 index 6eb4ec0..0000000 --- a/sources/app/Template/notification/task_open.php +++ /dev/null @@ -1,5 +0,0 @@ -

text->e($task['title']) ?> (#)

- -

- -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_overdue.php b/sources/app/Template/notification/task_overdue.php deleted file mode 100644 index 406e41f..0000000 --- a/sources/app/Template/notification/task_overdue.php +++ /dev/null @@ -1,31 +0,0 @@ -

- - - - - - - - - - - - - - - - - - - -
# - - text->e($task['title']) ?> - - text->e($task['title']) ?> - - dt->date($task['date_due']) ?> - - text->e($task['assignee_name'] ?: $task['assignee_username']) ?> - -
diff --git a/sources/app/Template/notification/task_update.php b/sources/app/Template/notification/task_update.php deleted file mode 100644 index 8adb255..0000000 --- a/sources/app/Template/notification/task_update.php +++ /dev/null @@ -1,4 +0,0 @@ -

text->e($task['title']) ?> (#)

- -render('task/changes', array('changes' => $changes, 'task' => $task)) ?> -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/notification/task_user_mention.php b/sources/app/Template/notification/task_user_mention.php deleted file mode 100644 index 3d8c8e9..0000000 --- a/sources/app/Template/notification/task_user_mention.php +++ /dev/null @@ -1,7 +0,0 @@ -

-

text->e($task['title']) ?>

- -

-text->markdown($task['description']) ?> - -render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file diff --git a/sources/app/Template/password_reset/change.php b/sources/app/Template/password_reset/change.php deleted file mode 100644 index 80a035d..0000000 --- a/sources/app/Template/password_reset/change.php +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/sources/app/Template/password_reset/create.php b/sources/app/Template/password_reset/create.php deleted file mode 100644 index f43d95f..0000000 --- a/sources/app/Template/password_reset/create.php +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/sources/app/Template/password_reset/email.php b/sources/app/Template/password_reset/email.php deleted file mode 100644 index 63b08e4..0000000 --- a/sources/app/Template/password_reset/email.php +++ /dev/null @@ -1,6 +0,0 @@ -

- -

url->to('PasswordResetController', 'change', array('token' => $token), '', true) ?>

- -
-Kanboard diff --git a/sources/app/Template/plugin/directory.php b/sources/app/Template/plugin/directory.php deleted file mode 100644 index b6c6734..0000000 --- a/sources/app/Template/plugin/directory.php +++ /dev/null @@ -1,55 +0,0 @@ - - - -

- -

- - - -

- - - - - - - - - - - - - - -
- text->e($plugin['title']) ?> -
- text->e($plugin['author']) ?> - - text->e($plugin['version']) ?> - - - - - url->link(t('Install'), 'PluginController', 'install', array('archive_url' => urlencode($plugin['download'])), true) ?> - - - url->link(t('Update'), 'PluginController', 'update', array('archive_url' => urlencode($plugin['download'])), true) ?> - - - - - - - - -
-
- text->markdown($plugin['description']) ?> -
-
- - diff --git a/sources/app/Template/plugin/layout.php b/sources/app/Template/plugin/layout.php deleted file mode 100644 index 6eafa59..0000000 --- a/sources/app/Template/plugin/layout.php +++ /dev/null @@ -1,9 +0,0 @@ -
- -
diff --git a/sources/app/Template/plugin/remove.php b/sources/app/Template/plugin/remove.php deleted file mode 100644 index bd8f4eb..0000000 --- a/sources/app/Template/plugin/remove.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
-

getPluginName()) ?>

- -
- url->link(t('Yes'), 'PluginController', 'uninstall', array('pluginId' => $plugin_id), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'PluginController', 'show', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/plugin/show.php b/sources/app/Template/plugin/show.php deleted file mode 100644 index 9c3d6d2..0000000 --- a/sources/app/Template/plugin/show.php +++ /dev/null @@ -1,41 +0,0 @@ - - - -

- - - - - - - - - - - - $plugin): ?> - - - - - - - - - - - - -
- getPluginHomepage()): ?> - text->e($plugin->getPluginName()) ?> - - text->e($plugin->getPluginName()) ?> - - text->e($plugin->getPluginAuthor()) ?>text->e($plugin->getPluginVersion()) ?> - - url->link(t('Uninstall'), 'PluginController', 'confirm', array('pluginId' => $pluginFolder), false, 'popover') ?> -
text->e($plugin->getPluginDescription()) ?>
- diff --git a/sources/app/Template/plugin/sidebar.php b/sources/app/Template/plugin/sidebar.php deleted file mode 100644 index e1b4763..0000000 --- a/sources/app/Template/plugin/sidebar.php +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/sources/app/Template/project/dropdown.php b/sources/app/Template/project/dropdown.php deleted file mode 100644 index 90dccf2..0000000 --- a/sources/app/Template/project/dropdown.php +++ /dev/null @@ -1,44 +0,0 @@ - diff --git a/sources/app/Template/project/layout.php b/sources/app/Template/project/layout.php deleted file mode 100644 index ec03920..0000000 --- a/sources/app/Template/project/layout.php +++ /dev/null @@ -1,11 +0,0 @@ -
- projectHeader->render($project, 'TaskListController', 'show') ?> - -
diff --git a/sources/app/Template/project/sidebar.php b/sources/app/Template/project/sidebar.php deleted file mode 100644 index d0f5059..0000000 --- a/sources/app/Template/project/sidebar.php +++ /dev/null @@ -1,66 +0,0 @@ - diff --git a/sources/app/Template/project_action_duplication/show.php b/sources/app/Template/project_action_duplication/show.php deleted file mode 100644 index 2eebb26..0000000 --- a/sources/app/Template/project_action_duplication/show.php +++ /dev/null @@ -1,19 +0,0 @@ - - -

- -
- form->csrf() ?> - - form->label(t('Create from another project'), 'src_project_id') ?> - form->select('src_project_id', $projects_list) ?> - -
- - - url->link(t('cancel'), 'Action', 'index', array(), false, 'close-popover') ?> -
-
- diff --git a/sources/app/Template/project_creation/create.php b/sources/app/Template/project_creation/create.php deleted file mode 100644 index d00883b..0000000 --- a/sources/app/Template/project_creation/create.php +++ /dev/null @@ -1,43 +0,0 @@ -
- -
- - form->csrf() ?> - form->hidden('is_private', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?> - - 1): ?> - form->label(t('Create from another project'), 'src_project_id') ?> - form->select('src_project_id', $projects_list, $values) ?> - - -
0 ? '' : 'style="display: none"' ?>> -

- - - form->checkbox('projectPermission', t('Permissions'), 1, true) ?> - - - form->checkbox('categoryModel', t('Categories'), 1, true) ?> - form->checkbox('tagDuplicationModel', t('Tags'), 1, true) ?> - form->checkbox('actionModel', t('Actions'), 1, true) ?> - form->checkbox('swimlaneModel', t('Swimlanes'), 1, true) ?> - form->checkbox('projectTaskDuplicationModel', t('Tasks'), 1, false) ?> -
- -
- - - url->link(t('cancel'), 'ProjectListController', 'show', array(), false, 'close-popover') ?> -
-
- -
-

-
- -
diff --git a/sources/app/Template/project_edit/dates.php b/sources/app/Template/project_edit/dates.php deleted file mode 100644 index 48135dd..0000000 --- a/sources/app/Template/project_edit/dates.php +++ /dev/null @@ -1,26 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('name', $values) ?> - - form->label(t('Start date'), 'start_date') ?> - form->text('start_date', $values, $errors, array('maxlength="10"'), 'form-date') ?> - - form->label(t('End date'), 'end_date') ?> - form->text('end_date', $values, $errors, array('maxlength="10"'), 'form-date') ?> - -
- -
-
- -

diff --git a/sources/app/Template/project_edit/description.php b/sources/app/Template/project_edit/description.php deleted file mode 100644 index f7e7be4..0000000 --- a/sources/app/Template/project_edit/description.php +++ /dev/null @@ -1,19 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('name', $values) ?> - form->textarea('description', $values, $errors, array(), 'markdown-editor') ?> - -
- -
-
diff --git a/sources/app/Template/project_edit/general.php b/sources/app/Template/project_edit/general.php deleted file mode 100644 index c742147..0000000 --- a/sources/app/Template/project_edit/general.php +++ /dev/null @@ -1,36 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('required', 'maxlength="50"')) ?> - - form->label(t('Identifier'), 'identifier') ?> - form->text('identifier', $values, $errors, array('maxlength="50"')) ?> -

- -
-
- form->label(t('Project owner'), 'owner_id') ?> - form->select('owner_id', $owners, $values, $errors) ?> -
- - user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])): ?> -
- form->checkbox('is_private', t('Private project'), 1, $project['is_private'] == 1) ?> -

- - -
- -
-
diff --git a/sources/app/Template/project_edit/task_priority.php b/sources/app/Template/project_edit/task_priority.php deleted file mode 100644 index 3ef4b3c..0000000 --- a/sources/app/Template/project_edit/task_priority.php +++ /dev/null @@ -1,29 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('name', $values) ?> - - form->label(t('Default priority'), 'priority_default') ?> - form->number('priority_default', $values, $errors) ?> - - form->label(t('Lowest priority'), 'priority_start') ?> - form->number('priority_start', $values, $errors) ?> - - form->label(t('Highest priority'), 'priority_end') ?> - form->number('priority_end', $values, $errors) ?> - -
- -
-
- -

diff --git a/sources/app/Template/project_file/create.php b/sources/app/Template/project_file/create.php deleted file mode 100644 index e262799..0000000 --- a/sources/app/Template/project_file/create.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -
-
- -
-
- - - -
- - - url->link(t('cancel'), 'ProjectOverviewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?> -
diff --git a/sources/app/Template/project_file/remove.php b/sources/app/Template/project_file/remove.php deleted file mode 100644 index 0517a9e..0000000 --- a/sources/app/Template/project_file/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- text->e($file['name'])) ?> -

- -
- url->link(t('Yes'), 'ProjectFileController', 'remove', array('project_id' => $project['id'], 'file_id' => $file['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'ProjectOverviewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/project_gantt/show.php b/sources/app/Template/project_gantt/show.php deleted file mode 100644 index af22a6e..0000000 --- a/sources/app/Template/project_gantt/show.php +++ /dev/null @@ -1,30 +0,0 @@ -
- -
- -

- -
- -
-
diff --git a/sources/app/Template/project_header/dropdown.php b/sources/app/Template/project_header/dropdown.php deleted file mode 100644 index 79a1b38..0000000 --- a/sources/app/Template/project_header/dropdown.php +++ /dev/null @@ -1,94 +0,0 @@ - diff --git a/sources/app/Template/project_header/header.php b/sources/app/Template/project_header/header.php deleted file mode 100644 index aaa8137..0000000 --- a/sources/app/Template/project_header/header.php +++ /dev/null @@ -1,15 +0,0 @@ -
- hook->render('template:project:header:before', array('project' => $project)) ?> - - render('project_header/dropdown', array('project' => $project, 'board_view' => $board_view)) ?> - render('project_header/views', array('project' => $project, 'filters' => $filters)) ?> - render('project_header/search', array( - 'project' => $project, - 'filters' => $filters, - 'custom_filters_list' => isset($custom_filters_list) ? $custom_filters_list : array(), - 'users_list' => isset($users_list) ? $users_list : array(), - 'categories_list' => isset($categories_list) ? $categories_list : array(), - )) ?> - - hook->render('template:project:header:after', array('project' => $project)) ?> -
\ No newline at end of file diff --git a/sources/app/Template/project_header/search.php b/sources/app/Template/project_header/search.php deleted file mode 100644 index 8885d9c..0000000 --- a/sources/app/Template/project_header/search.php +++ /dev/null @@ -1,45 +0,0 @@ -
- -
diff --git a/sources/app/Template/project_header/views.php b/sources/app/Template/project_header/views.php deleted file mode 100644 index 3a41c91..0000000 --- a/sources/app/Template/project_header/views.php +++ /dev/null @@ -1,24 +0,0 @@ - diff --git a/sources/app/Template/project_list/show.php b/sources/app/Template/project_list/show.php deleted file mode 100644 index 8b9f139..0000000 --- a/sources/app/Template/project_list/show.php +++ /dev/null @@ -1,85 +0,0 @@ -
- - isEmpty()): ?> -

- - - - - - - - - - user->hasAccess('ProjectUserOverviewController', 'managers')): ?> - - - - - getCollection() as $project): ?> - - - - - - - - user->hasAccess('ProjectUserOverviewController', 'managers')): ?> - - - - - -
order(t('Id'), 'id') ?>order(t('Status'), 'is_active') ?>order(t('Project'), 'name') ?>order(t('Start date'), 'start_date') ?>order(t('End date'), 'end_date') ?>order(t('Owner'), 'owner_id') ?>
- render('project/dropdown', array('project' => $project)) ?> - - - - - - - - url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?> - - - - - - - - - - - - - - - dt->date($project['start_date']) ?> - - dt->date($project['end_date']) ?> - - 0): ?> - text->e($project['owner_name'] ?: $project['owner_username']) ?> - - - - - - - - text->e($column['title']) ?> - -
- - - -
diff --git a/sources/app/Template/project_overview/activity.php b/sources/app/Template/project_overview/activity.php deleted file mode 100644 index 2eb7a19..0000000 --- a/sources/app/Template/project_overview/activity.php +++ /dev/null @@ -1,8 +0,0 @@ -
-
-

-
-
- render('event/events', array('events' => $events)) ?> -
-
\ No newline at end of file diff --git a/sources/app/Template/project_overview/attachments.php b/sources/app/Template/project_overview/attachments.php deleted file mode 100644 index ab8cf2a..0000000 --- a/sources/app/Template/project_overview/attachments.php +++ /dev/null @@ -1,15 +0,0 @@ -
-
-

-
-
- user->hasProjectAccess('ProjectFileController', 'create', $project['id'])): ?> -
- url->button('fa-plus', t('Upload a file'), 'ProjectFileController', 'create', array('project_id' => $project['id']), 'popover') ?> -
- - - render('project_overview/images', array('project' => $project, 'images' => $images)) ?> - render('project_overview/files', array('project' => $project, 'files' => $files)) ?> -
-
diff --git a/sources/app/Template/project_overview/columns.php b/sources/app/Template/project_overview/columns.php deleted file mode 100644 index cc5782b..0000000 --- a/sources/app/Template/project_overview/columns.php +++ /dev/null @@ -1,8 +0,0 @@ -
- -
-
- text->e($column['title']) ?> -
- -
diff --git a/sources/app/Template/project_overview/description.php b/sources/app/Template/project_overview/description.php deleted file mode 100644 index 0c2027e..0000000 --- a/sources/app/Template/project_overview/description.php +++ /dev/null @@ -1,15 +0,0 @@ -
-
-

-
-
- user->hasProjectAccess('ProjectEditController', 'description', $project['id'])): ?> -
- url->button('fa-edit', t('Edit description'), 'ProjectEditController', 'description', array('project_id' => $project['id']), 'popover') ?> -
- -
- text->markdown($project['description']) ?> -
-
-
diff --git a/sources/app/Template/project_overview/files.php b/sources/app/Template/project_overview/files.php deleted file mode 100644 index fa87093..0000000 --- a/sources/app/Template/project_overview/files.php +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - -
- - - - text->e($file['user_name'] ?: $file['username']) ?> - - dt->date($file['date']) ?> - - text->bytes($file['size']) ?> -
- diff --git a/sources/app/Template/project_overview/images.php b/sources/app/Template/project_overview/images.php deleted file mode 100644 index 7f38e2b..0000000 --- a/sources/app/Template/project_overview/images.php +++ /dev/null @@ -1,35 +0,0 @@ - -
- -
- <?= $this->text->e($file['name']) ?> -
-
- -
-
- dt->datetime($file['date'])).'
'.t('Size: %s', $this->text->bytes($file['size'])) ?>'> - -
- -
-
-
- -
- - diff --git a/sources/app/Template/project_overview/information.php b/sources/app/Template/project_overview/information.php deleted file mode 100644 index fdf0f75..0000000 --- a/sources/app/Template/project_overview/information.php +++ /dev/null @@ -1,39 +0,0 @@ -
-
-

-
-
-
-
    - 0): ?> -
  • text->e($project['owner_name'] ?: $project['owner_username']) ?>
  • - - - - $role_name): ?> - -
  • - : - -
  • - - - - - -
  • dt->date($project['start_date']) ?>
  • - - - -
  • dt->date($project['end_date']) ?>
  • - - - -
  • url->link(t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?>
  • -
  • url->link(t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?>
  • -
  • url->link(t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token'])) ?>
  • - -
-
-
-
diff --git a/sources/app/Template/project_overview/show.php b/sources/app/Template/project_overview/show.php deleted file mode 100644 index 6b2bc2c..0000000 --- a/sources/app/Template/project_overview/show.php +++ /dev/null @@ -1,8 +0,0 @@ -
- projectHeader->render($project, 'ProjectOverviewController', 'show') ?> - render('project_overview/columns', array('project' => $project)) ?> - render('project_overview/description', array('project' => $project)) ?> - render('project_overview/attachments', array('project' => $project, 'images' => $images, 'files' => $files)) ?> - render('project_overview/information', array('project' => $project, 'users' => $users, 'roles' => $roles)) ?> - render('project_overview/activity', array('project' => $project, 'events' => $events)) ?> -
diff --git a/sources/app/Template/project_permission/index.php b/sources/app/Template/project_permission/index.php deleted file mode 100644 index d850ec5..0000000 --- a/sources/app/Template/project_permission/index.php +++ /dev/null @@ -1,141 +0,0 @@ - - - -
- - - -
- - - - - - - - - - - - - - - - -
text->e($user['name'] ?: $user['username']) ?> - 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' - ) ?> - - url->link(t('Remove'), 'ProjectPermissionController', 'removeUser', array('project_id' => $project['id'], 'user_id' => $user['id']), true) ?> -
- - - -
-
- form->csrf() ?> - form->hidden('project_id', array('project_id' => $project['id'])) ?> - form->hidden('user_id', $values) ?> - - form->label(t('Name'), 'name') ?> - 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') ?> - - form->select('role', $roles, $values, $errors) ?> - - -
-
- - - - - -
- - - - - - - - - - - - - - - - -
text->e($group['name']) ?> - 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' - ) ?> - - url->link(t('Remove'), 'ProjectPermissionController', 'removeGroup', array('project_id' => $project['id'], 'group_id' => $group['id']), true) ?> -
- - - -
-
- form->csrf() ?> - form->hidden('project_id', array('project_id' => $project['id'])) ?> - form->hidden('group_id', $values) ?> - form->hidden('external_id', $values) ?> - - form->label(t('Group Name'), 'name') ?> - 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') ?> - - form->select('role', $roles, $values, $errors) ?> - - -
-
- - - - - -
-
- form->csrf() ?> - - form->hidden('id', array('id' => $project['id'])) ?> - form->checkbox('is_everybody_allowed', t('Allow everybody to access to this project'), 1, $project['is_everybody_allowed']) ?> - -
- -
-
- diff --git a/sources/app/Template/project_status/disable.php b/sources/app/Template/project_status/disable.php deleted file mode 100644 index d8145d3..0000000 --- a/sources/app/Template/project_status/disable.php +++ /dev/null @@ -1,14 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'ProjectStatusController', 'disable', array('project_id' => $project['id']), true, 'btn btn-red') ?> - url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/project_status/enable.php b/sources/app/Template/project_status/enable.php deleted file mode 100644 index 1f76d09..0000000 --- a/sources/app/Template/project_status/enable.php +++ /dev/null @@ -1,14 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'ProjectStatusController', 'enable', array('project_id' => $project['id']), true, 'btn btn-red') ?> - url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/project_status/remove.php b/sources/app/Template/project_status/remove.php deleted file mode 100644 index 8959ef7..0000000 --- a/sources/app/Template/project_status/remove.php +++ /dev/null @@ -1,14 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'ProjectStatusController', 'remove', array('project_id' => $project['id']), true, 'btn btn-red') ?> - url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/project_tag/create.php b/sources/app/Template/project_tag/create.php deleted file mode 100644 index bfd1084..0000000 --- a/sources/app/Template/project_tag/create.php +++ /dev/null @@ -1,16 +0,0 @@ - -
- form->csrf() ?> - form->hidden('project_id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?> - -
- - - url->link(t('cancel'), 'ProjectTagController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/project_tag/edit.php b/sources/app/Template/project_tag/edit.php deleted file mode 100644 index 9bf261b..0000000 --- a/sources/app/Template/project_tag/edit.php +++ /dev/null @@ -1,17 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('project_id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?> - -
- - - url->link(t('cancel'), 'ProjectTagController', 'index', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/project_tag/index.php b/sources/app/Template/project_tag/index.php deleted file mode 100644 index 8e8dd96..0000000 --- a/sources/app/Template/project_tag/index.php +++ /dev/null @@ -1,31 +0,0 @@ - - - -

- - - - - - - - - - - - -
text->e($tag['name']) ?> - - url->link(t('Remove'), 'ProjectTagController', 'confirm', array('tag_id' => $tag['id'], 'project_id' => $project['id']), false, 'popover') ?> - - url->link(t('Edit'), 'ProjectTagController', 'edit', array('tag_id' => $tag['id'], 'project_id' => $project['id']), false, 'popover') ?> -
- diff --git a/sources/app/Template/project_tag/remove.php b/sources/app/Template/project_tag/remove.php deleted file mode 100644 index f4aadab..0000000 --- a/sources/app/Template/project_tag/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'ProjectTagController', 'remove', array('tag_id' => $tag['id'], 'project_id' => $project['id']), true, 'btn btn-red popover-link') ?> - - url->link(t('cancel'), 'ProjectTagController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/project_user_overview/layout.php b/sources/app/Template/project_user_overview/layout.php deleted file mode 100644 index 19b8343..0000000 --- a/sources/app/Template/project_user_overview/layout.php +++ /dev/null @@ -1,27 +0,0 @@ -
- - -
diff --git a/sources/app/Template/project_user_overview/roles.php b/sources/app/Template/project_user_overview/roles.php deleted file mode 100644 index 87c8df8..0000000 --- a/sources/app/Template/project_user_overview/roles.php +++ /dev/null @@ -1,33 +0,0 @@ -isEmpty()): ?> -

- - - - - - - - getCollection() as $project): ?> - - - - - - -
order(t('User'), 'users.username') ?>order(t('Project'), 'projects.name') ?>
- text->e($this->user->getFullname($project)) ?> - - url->link('', 'BoardViewController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Board')) ?> - url->link('', 'TaskGanttController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Gantt chart')) ?> - url->link('', 'ProjectViewController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Project settings')) ?> - - text->e($project['project_name']) ?> - - - - text->e($column['title']) ?> - -
- - - diff --git a/sources/app/Template/project_user_overview/sidebar.php b/sources/app/Template/project_user_overview/sidebar.php deleted file mode 100644 index 9a87d4e..0000000 --- a/sources/app/Template/project_user_overview/sidebar.php +++ /dev/null @@ -1,30 +0,0 @@ - diff --git a/sources/app/Template/project_user_overview/tasks.php b/sources/app/Template/project_user_overview/tasks.php deleted file mode 100644 index af0a3d9..0000000 --- a/sources/app/Template/project_user_overview/tasks.php +++ /dev/null @@ -1,46 +0,0 @@ -isEmpty()): ?> -

-isEmpty()): ?> - - - - - - - - - - - getCollection() as $task): ?> - - - - - - - - - - -
order(t('Id'), 'tasks.id') ?>order(t('Project'), 'projects.name') ?>order(t('Column'), 'tasks.column_id') ?>order(t('Title'), 'tasks.title') ?>order(t('Assignee'), 'users.username') ?>order(t('Start date'), 'tasks.date_started') ?>order(t('Due date'), 'tasks.date_due') ?>
- url->link('#'.$this->text->e($task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - - url->link($this->text->e($task['project_name']), 'BoardViewController', 'show', array('project_id' => $task['project_id'])) ?> - - text->e($task['column_name']) ?> - - url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - - - text->e($task['assignee_name'] ?: $task['assignee_username']) ?> - - - - - dt->date($task['date_started']) ?> - - dt->date($task['date_due']) ?> -
- - - diff --git a/sources/app/Template/project_user_overview/tooltip_users.php b/sources/app/Template/project_user_overview/tooltip_users.php deleted file mode 100644 index 7117a87..0000000 --- a/sources/app/Template/project_user_overview/tooltip_users.php +++ /dev/null @@ -1,16 +0,0 @@ - -

- - - $role_name): ?> - - - $user): ?> - - - - -
- url->link($this->text->e($user), 'ProjectUserOverviewController', 'opens', array('user_id' => $user_id)) ?> -
- diff --git a/sources/app/Template/project_view/duplicate.php b/sources/app/Template/project_view/duplicate.php deleted file mode 100644 index d66ff59..0000000 --- a/sources/app/Template/project_view/duplicate.php +++ /dev/null @@ -1,29 +0,0 @@ - - -
-

- -

-
- - form->csrf() ?> - - - form->checkbox('projectPermission', t('Permissions'), 1, true) ?> - - - form->checkbox('categoryModel', t('Categories'), 1, true) ?> - form->checkbox('tagDuplicationModel', t('Tags'), 1, true) ?> - form->checkbox('actionModel', t('Actions'), 1, true) ?> - form->checkbox('swimlaneModel', t('Swimlanes'), 1, false) ?> - form->checkbox('projectMetadataModel', t('Metadata'), 1, false) ?> - form->checkbox('projectTaskDuplicationModel', t('Tasks'), 1, false) ?> - -
- - url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id'])) ?> -
-
-
diff --git a/sources/app/Template/project_view/integrations.php b/sources/app/Template/project_view/integrations.php deleted file mode 100644 index f8bff7e..0000000 --- a/sources/app/Template/project_view/integrations.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
- form->csrf() ?> - - hook->render('template:project:integrations', array('project' => $project, 'values' => $values, 'webhook_token' => $webhook_token)) ?> - - -

- - - -
diff --git a/sources/app/Template/project_view/notifications.php b/sources/app/Template/project_view/notifications.php deleted file mode 100644 index 29cc088..0000000 --- a/sources/app/Template/project_view/notifications.php +++ /dev/null @@ -1,20 +0,0 @@ - - -

- -
- - form->csrf() ?> - -

- form->checkboxes('notification_types', $types, $notifications) ?> - -
- - - url->link(t('cancel'), 'ProjectViewController', 'show', array('project_id' => $project['id'])) ?> -
-
- diff --git a/sources/app/Template/project_view/share.php b/sources/app/Template/project_view/share.php deleted file mode 100644 index 409f37e..0000000 --- a/sources/app/Template/project_view/share.php +++ /dev/null @@ -1,18 +0,0 @@ - - - - -
-
    -
  • url->link(t('Public link'), 'BoardViewController', 'readonly', array('token' => $project['token']), false, '', '', true) ?>
  • -
  • url->link(t('RSS feed'), 'FeedController', 'project', array('token' => $project['token']), false, '', '', true) ?>
  • -
  • url->link(t('iCal feed'), 'ICalendarController', 'project', array('token' => $project['token']), false, '', '', true) ?>
  • -
-
- - url->link(t('Disable public access'), 'ProjectViewController', 'updateSharing', array('project_id' => $project['id'], 'switch' => 'disable'), true, 'btn btn-red') ?> - - url->link(t('Enable public access'), 'ProjectViewController', 'updateSharing', array('project_id' => $project['id'], 'switch' => 'enable'), true, 'btn btn-blue') ?> - diff --git a/sources/app/Template/project_view/show.php b/sources/app/Template/project_view/show.php deleted file mode 100644 index 5efe8ce..0000000 --- a/sources/app/Template/project_view/show.php +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - -
- text->e($column['title']) ?> - - - - - -
- - - - -
- text->markdown($project['description']) ?> -
- diff --git a/sources/app/Template/search/activity.php b/sources/app/Template/search/activity.php deleted file mode 100644 index 9abc7d7..0000000 --- a/sources/app/Template/search/activity.php +++ /dev/null @@ -1,39 +0,0 @@ -
- - -
- -
- - -
-

-

project:"My project" creator:me

-
    -
  • project:"My project"
  • -
  • creator:admin
  • -
  • created:today
  • -
  • status:open
  • -
  • title:"My task"
  • -
-

url->doc(t('View advanced search syntax'), 'search') ?>

-
- -

- - render('event/events', array('events' => $events)) ?> - - -
diff --git a/sources/app/Template/search/index.php b/sources/app/Template/search/index.php deleted file mode 100644 index bc528af..0000000 --- a/sources/app/Template/search/index.php +++ /dev/null @@ -1,43 +0,0 @@ -
- - -
- -
- - -
-

-

project:"My project" assignee:me due:tomorrow

-
    -
  • project:"My project"
  • -
  • column:"Work in progress"
  • -
  • assignee:nobody
  • -
  • color:Blue
  • -
  • category:"Feature Request"
  • -
  • description:"Something to find"
  • -
  • due:2015-07-01
  • -
-

url->doc(t('View advanced search syntax'), 'search') ?>

-
- isEmpty()): ?> -

- isEmpty()): ?> - render('search/results', array( - 'paginator' => $paginator, - )) ?> - - -
diff --git a/sources/app/Template/search/results.php b/sources/app/Template/search/results.php deleted file mode 100644 index 8376b9e..0000000 --- a/sources/app/Template/search/results.php +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - getCollection() as $task): ?> - - - - - - - - - - - - -
order(t('Project'), 'tasks.project_id') ?>order(t('Id'), 'tasks.id') ?>order(t('Swimlane'), 'tasks.swimlane_id') ?>order(t('Column'), 'tasks.column_id') ?>order(t('Category'), 'tasks.category_id') ?>order(t('Title'), 'tasks.title') ?>order(t('Assignee'), 'users.username') ?>order(t('Due date'), 'tasks.date_due') ?>order(t('Status'), 'tasks.is_active') ?>
- url->link($this->text->e($task['project_name']), 'BoardViewController', 'show', array('project_id' => $task['project_id'])) ?> - - url->link('#'.$this->text->e($task['id']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - - text->e($task['swimlane_name'] ?: $task['default_swimlane']) ?> - - text->e($task['column_name']) ?> - - text->e($task['category_name']) ?> - - url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - - - text->e($task['assignee_name'] ?: $task['assignee_username']) ?> - - - - - dt->date($task['date_due']) ?> - - - - - - -
- - diff --git a/sources/app/Template/subtask/create.php b/sources/app/Template/subtask/create.php deleted file mode 100644 index 3c080f7..0000000 --- a/sources/app/Template/subtask/create.php +++ /dev/null @@ -1,20 +0,0 @@ - - -
- - form->csrf() ?> - form->hidden('task_id', $values) ?> - subtask->selectTitle($values, $errors, array('autofocus')) ?> - subtask->selectAssignee($users_list, $values, $errors) ?> - subtask->selectTimeEstimated($values, $errors) ?> - - form->checkbox('another_subtask', t('Create another sub-task'), 1, isset($values['another_subtask']) && $values['another_subtask'] == 1) ?> - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/subtask/edit.php b/sources/app/Template/subtask/edit.php deleted file mode 100644 index 8f256ce..0000000 --- a/sources/app/Template/subtask/edit.php +++ /dev/null @@ -1,20 +0,0 @@ - - -
- - form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('task_id', $values) ?> - subtask->selectTitle($values, $errors, array('autofocus')) ?> - subtask->selectAssignee($users_list, $values, $errors) ?> - subtask->selectTimeEstimated($values, $errors) ?> - subtask->selectTimeSpent($values, $errors) ?> - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/subtask/menu.php b/sources/app/Template/subtask/menu.php deleted file mode 100644 index d5d1bf8..0000000 --- a/sources/app/Template/subtask/menu.php +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/sources/app/Template/subtask/remove.php b/sources/app/Template/subtask/remove.php deleted file mode 100644 index 426c1a9..0000000 --- a/sources/app/Template/subtask/remove.php +++ /dev/null @@ -1,20 +0,0 @@ - - -
-
- -
    -
  • - text->e($subtask['title']) ?> -
  • -
-
- -
- url->link(t('Yes'), 'SubtaskController', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/subtask/show.php b/sources/app/Template/subtask/show.php deleted file mode 100644 index fe436d5..0000000 --- a/sources/app/Template/subtask/show.php +++ /dev/null @@ -1,12 +0,0 @@ -
-
-

-
-
- render('subtask/table', array( - 'subtasks' => $subtasks, - 'task' => $task, - 'editable' => $editable - )) ?> -
-
diff --git a/sources/app/Template/subtask/table.php b/sources/app/Template/subtask/table.php deleted file mode 100644 index 4c6484e..0000000 --- a/sources/app/Template/subtask/table.php +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
- - - subtask->toggleStatus($subtask, $task['project_id'], true) ?> - - subtask->getTitle($subtask) ?> - - - - text->e($subtask['name'] ?: $subtask['username']) ?> - - -
    -
  • - - text->e($subtask['time_spent']).'h' ?> - - - - text->e($subtask['time_estimated']).'h' ?> - -
  • - user->getId()): ?> -
  • - - - 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') ?> - (dt->age($subtask['timer_start_date']) ?>) - - - 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') ?> - -
  • - -
-
- render('subtask/menu', array( - 'task' => $task, - 'subtask' => $subtask, - )) ?> -
- diff --git a/sources/app/Template/subtask_converter/show.php b/sources/app/Template/subtask_converter/show.php deleted file mode 100644 index 63f4548..0000000 --- a/sources/app/Template/subtask_converter/show.php +++ /dev/null @@ -1,20 +0,0 @@ - - -
-
- -
    -
  • - text->e($subtask['title']) ?> -
  • -
-
- -
- url->link(t('Yes'), 'SubtaskConverterController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/subtask_restriction/show.php b/sources/app/Template/subtask_restriction/show.php deleted file mode 100644 index ec8b8d5..0000000 --- a/sources/app/Template/subtask_restriction/show.php +++ /dev/null @@ -1,17 +0,0 @@ - -
- - form->csrf() ?> - -

- form->radios('status', $status_list) ?> - form->hidden('id', $subtask_inprogress) ?> - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/swimlane/create.php b/sources/app/Template/swimlane/create.php deleted file mode 100644 index f5aa159..0000000 --- a/sources/app/Template/swimlane/create.php +++ /dev/null @@ -1,20 +0,0 @@ - -
- - form->csrf() ?> - form->hidden('project_id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?> - - form->label(t('Description'), 'description') ?> - form->textarea('description', $values, $errors, array(), 'markdown-editor') ?> - -
- - - url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/swimlane/edit.php b/sources/app/Template/swimlane/edit.php deleted file mode 100644 index b10cdd5..0000000 --- a/sources/app/Template/swimlane/edit.php +++ /dev/null @@ -1,23 +0,0 @@ - - -
- - form->csrf() ?> - - form->hidden('id', $values) ?> - form->hidden('project_id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?> - - form->label(t('Description'), 'description') ?> - form->textarea('description', $values, $errors, array(), 'markdown-editor') ?> - -
- - - url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/swimlane/edit_default.php b/sources/app/Template/swimlane/edit_default.php deleted file mode 100644 index f271c51..0000000 --- a/sources/app/Template/swimlane/edit_default.php +++ /dev/null @@ -1,18 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - - form->label(t('Name'), 'default_swimlane') ?> - form->text('default_swimlane', $values, $errors, array('required', 'maxlength="50"')) ?> - - form->checkbox('show_default_swimlane', t('Show default swimlane'), 1, $values['show_default_swimlane'] == 1) ?> - -
- - - url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/swimlane/index.php b/sources/app/Template/swimlane/index.php deleted file mode 100644 index 4f78a40..0000000 --- a/sources/app/Template/swimlane/index.php +++ /dev/null @@ -1,28 +0,0 @@ - - - -

- render('swimlane/table', array( - 'swimlanes' => $active_swimlanes, - 'project' => $project, - 'default_swimlane' => $default_swimlane['show_default_swimlane'] == 1 ? $default_swimlane : array() - )) ?> - - - -

- render('swimlane/table', array( - 'swimlanes' => $inactive_swimlanes, - 'project' => $project, - 'default_swimlane' => $default_swimlane['show_default_swimlane'] == 0 ? $default_swimlane : array(), - 'disable_handler' => true - )) ?> - diff --git a/sources/app/Template/swimlane/remove.php b/sources/app/Template/swimlane/remove.php deleted file mode 100644 index f16b778..0000000 --- a/sources/app/Template/swimlane/remove.php +++ /dev/null @@ -1,17 +0,0 @@ -
- - -
-

- -

- -
- url->link(t('Yes'), 'SwimlaneController', 'remove', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'SwimlaneController', 'index', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
-
diff --git a/sources/app/Template/swimlane/table.php b/sources/app/Template/swimlane/table.php deleted file mode 100644 index be123b0..0000000 --- a/sources/app/Template/swimlane/table.php +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -
- text->e($default_swimlane['default_swimlane']) ?> - -  () - - -
- - - - - text->e($swimlane['name']) ?> - - - - - - - - -
diff --git a/sources/app/Template/tag/create.php b/sources/app/Template/tag/create.php deleted file mode 100644 index 9b32bc4..0000000 --- a/sources/app/Template/tag/create.php +++ /dev/null @@ -1,16 +0,0 @@ - -
- form->csrf() ?> - form->hidden('project_id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?> - -
- - - url->link(t('cancel'), 'TagController', 'index', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/tag/edit.php b/sources/app/Template/tag/edit.php deleted file mode 100644 index f751ff4..0000000 --- a/sources/app/Template/tag/edit.php +++ /dev/null @@ -1,17 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('project_id', $values) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="255"')) ?> - -
- - - url->link(t('cancel'), 'TagController', 'index', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/tag/index.php b/sources/app/Template/tag/index.php deleted file mode 100644 index 2a495eb..0000000 --- a/sources/app/Template/tag/index.php +++ /dev/null @@ -1,31 +0,0 @@ - - - -

- - - - - - - - - - - - -
text->e($tag['name']) ?> - - url->link(t('Remove'), 'TagController', 'confirm', array('tag_id' => $tag['id']), false, 'popover') ?> - - url->link(t('Edit'), 'TagController', 'edit', array('tag_id' => $tag['id']), false, 'popover') ?> -
- diff --git a/sources/app/Template/tag/remove.php b/sources/app/Template/tag/remove.php deleted file mode 100644 index 46ea3f9..0000000 --- a/sources/app/Template/tag/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'TagController', 'remove', array('tag_id' => $tag['id']), true, 'btn btn-red popover-link') ?> - - url->link(t('cancel'), 'TagController', 'index', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task/analytics.php b/sources/app/Template/task/analytics.php deleted file mode 100644 index db2d0ce..0000000 --- a/sources/app/Template/task/analytics.php +++ /dev/null @@ -1,36 +0,0 @@ -
-

text->e($task['title']) ?>

-
- - -
-
    -
  • '.$this->dt->duration($lead_time) ?>
  • -
  • '.$this->dt->duration($cycle_time) ?>
  • -
-
- -

-
- - - - - - - - - - - -
text->e($column['title']) ?>dt->duration($column['time_spent']) ?>
- -
-
    -
  • -
  • -
  • -
-
diff --git a/sources/app/Template/task/changes.php b/sources/app/Template/task/changes.php deleted file mode 100644 index 9d36f09..0000000 --- a/sources/app/Template/task/changes.php +++ /dev/null @@ -1,74 +0,0 @@ - - - - -

-
text->markdown($task['description']) ?>
- - \ No newline at end of file diff --git a/sources/app/Template/task/description.php b/sources/app/Template/task/description.php deleted file mode 100644 index f8e313d..0000000 --- a/sources/app/Template/task/description.php +++ /dev/null @@ -1,10 +0,0 @@ -
-
-

-
-
-
- text->markdown($task['description'], isset($is_public) && $is_public) ?> -
-
-
diff --git a/sources/app/Template/task/details.php b/sources/app/Template/task/details.php deleted file mode 100644 index 695957f..0000000 --- a/sources/app/Template/task/details.php +++ /dev/null @@ -1,167 +0,0 @@ -
-

text->e($task['title']) ?>

- - hook->render('template:task:details:top', array('task' => $task)) ?> - -
-
-
-
    -
  • - - - - - - - - -
  • -
  • - -
  • - -
  • - text->e($task['reference']) ?> -
  • - - -
  • - text->e($task['score']) ?> -
  • - - -
  • - - url->link(t('Public link'), 'TaskViewController', 'readonly', array('task_id' => $task['id'], 'token' => $project['token']), false, '', '', true) ?> -
  • - - -
  • - - url->link(t('Back to the board'), 'BoardViewController', 'readonly', array('token' => $project['token'])) ?> -
  • - -
  • - - hook->render('template:task:details:first-column', array('task' => $task)) ?> -
-
-
-
    - -
  • - - text->e($task['category_name']) ?> -
  • - - -
  • - - text->e($task['swimlane_name']) ?> -
  • - -
  • - - text->e($task['column_title']) ?> -
  • -
  • - - -
  • - - hook->render('template:task:details:second-column', array('task' => $task)) ?> -
-
-
-
    -
  • - - - - text->e($task['assignee_name'] ?: $task['assignee_username']) ?> - - - - -
  • - -
  • - - text->e($task['creator_name'] ?: $task['creator_username']) ?> -
  • - - -
  • - - dt->date($task['date_due']) ?> -
  • - - -
  • - - -
  • - - -
  • - - -
  • - - - hook->render('template:task:details:third-column', array('task' => $task)) ?> -
-
-
-
    -
  • - - dt->datetime($task['date_creation']) ?> -
  • -
  • - - dt->datetime($task['date_modification']) ?> -
  • - -
  • - - dt->datetime($task['date_completed']) ?> -
  • - - -
  • - - dt->datetime($task['date_started']) ?> -
  • - - -
  • - - dt->datetime($task['date_moved']) ?> -
  • - - - hook->render('template:task:details:fourth-column', array('task' => $task)) ?> -
-
-
- -
-
    - -
  • text->e($tag) ?>
  • - -
-
- -
- - -
- url->button('fa-play', t('Set start date'), 'TaskModificationController', 'start', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> -
- - - hook->render('template:task:details:bottom', array('task' => $task)) ?> -
diff --git a/sources/app/Template/task/dropdown.php b/sources/app/Template/task/dropdown.php deleted file mode 100644 index 95c7a88..0000000 --- a/sources/app/Template/task/dropdown.php +++ /dev/null @@ -1,66 +0,0 @@ - diff --git a/sources/app/Template/task/layout.php b/sources/app/Template/task/layout.php deleted file mode 100644 index 7f6c291..0000000 --- a/sources/app/Template/task/layout.php +++ /dev/null @@ -1,17 +0,0 @@ -
- projectHeader->render($project, 'TaskListController', 'show') ?> - hook->render('template:task:layout:top', array('task' => $task)) ?> - -
diff --git a/sources/app/Template/task/public.php b/sources/app/Template/task/public.php deleted file mode 100644 index b8405ff..0000000 --- a/sources/app/Template/task/public.php +++ /dev/null @@ -1,36 +0,0 @@ -
- render('task/details', array( - 'task' => $task, - 'tags' => $tags, - 'project' => $project, - 'editable' => false, - )) ?> - - render('task/description', array( - 'task' => $task, - 'project' => $project, - 'is_public' => true, - )) ?> - - render('subtask/show', array( - 'task' => $task, - 'subtasks' => $subtasks, - 'editable' => false - )) ?> - - render('task_internal_link/show', array( - 'task' => $task, - 'links' => $links, - 'project' => $project, - 'editable' => false, - 'is_public' => true, - )) ?> - - render('comments/show', array( - 'task' => $task, - 'comments' => $comments, - 'project' => $project, - 'editable' => false, - 'is_public' => true, - )) ?> -
diff --git a/sources/app/Template/task/show.php b/sources/app/Template/task/show.php deleted file mode 100644 index 8078671..0000000 --- a/sources/app/Template/task/show.php +++ /dev/null @@ -1,53 +0,0 @@ -hook->render('template:task:show:top', array('task' => $task, 'project' => $project)) ?> - -render('task/details', array( - 'task' => $task, - 'tags' => $tags, - 'project' => $project, - 'editable' => $this->user->hasProjectAccess('TaskModificationController', 'edit', $project['id']), -)) ?> - -hook->render('template:task:show:before-description', array('task' => $task, 'project' => $project)) ?> -render('task/description', array('task' => $task)) ?> - -hook->render('template:task:show:before-subtasks', array('task' => $task, 'project' => $project)) ?> -render('subtask/show', array( - 'task' => $task, - 'subtasks' => $subtasks, - 'project' => $project, - 'editable' => true, -)) ?> - -hook->render('template:task:show:before-internal-links', array('task' => $task, 'project' => $project)) ?> -render('task_internal_link/show', array( - 'task' => $task, - 'links' => $internal_links, - 'project' => $project, - 'link_label_list' => $link_label_list, - 'editable' => true, - 'is_public' => false, -)) ?> - -hook->render('template:task:show:before-external-links', array('task' => $task, 'project' => $project)) ?> -render('task_external_link/show', array( - 'task' => $task, - 'links' => $external_links, - 'project' => $project, -)) ?> - -hook->render('template:task:show:before-attachments', array('task' => $task, 'project' => $project)) ?> -render('task_file/show', array( - 'task' => $task, - 'files' => $files, - 'images' => $images -)) ?> - -hook->render('template:task:show:before-comments', array('task' => $task, 'project' => $project)) ?> -render('comments/show', array( - 'task' => $task, - 'comments' => $comments, - 'project' => $project, - 'editable' => $this->user->hasProjectAccess('CommentController', 'edit', $project['id']), -)) ?> - -hook->render('template:task:show:bottom', array('task' => $task, 'project' => $project)) ?> diff --git a/sources/app/Template/task/sidebar.php b/sources/app/Template/task/sidebar.php deleted file mode 100644 index b44e6f0..0000000 --- a/sources/app/Template/task/sidebar.php +++ /dev/null @@ -1,96 +0,0 @@ - diff --git a/sources/app/Template/task/time_tracking_details.php b/sources/app/Template/task/time_tracking_details.php deleted file mode 100644 index 1a17952..0000000 --- a/sources/app/Template/task/time_tracking_details.php +++ /dev/null @@ -1,31 +0,0 @@ -
-

text->e($task['title']) ?>

-
- -render('task/time_tracking_summary', array('task' => $task)) ?> - -

-isEmpty()): ?> -

- - - - - - - - - - getCollection() as $record): ?> - - - - - - - - -
order(t('User'), 'username') ?>order(t('Subtask'), 'subtask_title') ?>order(t('Start'), 'start') ?>order(t('End'), 'end') ?>order(t('Time spent'), \Kanboard\Model\SubtaskTimeTrackingModel::TABLE.'.time_spent') ?>
url->link($this->text->e($record['user_fullname'] ?: $record['username']), 'UserViewController', 'show', array('user_id' => $record['user_id'])) ?>dt->datetime($record['start']) ?>dt->datetime($record['end']) ?>
- - - diff --git a/sources/app/Template/task/time_tracking_summary.php b/sources/app/Template/task/time_tracking_summary.php deleted file mode 100644 index 9886ccf..0000000 --- a/sources/app/Template/task/time_tracking_summary.php +++ /dev/null @@ -1,13 +0,0 @@ - 0 || $task['time_spent'] > 0): ?> - - - - - - \ No newline at end of file diff --git a/sources/app/Template/task/transitions.php b/sources/app/Template/task/transitions.php deleted file mode 100644 index 9e04c4e..0000000 --- a/sources/app/Template/task/transitions.php +++ /dev/null @@ -1,30 +0,0 @@ -
-

text->e($task['title']) ?>

-
- - - - -

- - - - - - - - - - - - - - - - - - -
dt->datetime($transition['date']) ?>text->e($transition['src_column']) ?>text->e($transition['dst_column']) ?>url->link($this->text->e($transition['name'] ?: $transition['username']), 'UserViewController', 'show', array('user_id' => $transition['user_id'])) ?>dt->duration($transition['time_spent']) ?>
- diff --git a/sources/app/Template/task_bulk/show.php b/sources/app/Template/task_bulk/show.php deleted file mode 100644 index e9b138d..0000000 --- a/sources/app/Template/task_bulk/show.php +++ /dev/null @@ -1,24 +0,0 @@ - - -
- form->csrf() ?> - form->hidden('column_id', $values) ?> - form->hidden('swimlane_id', $values) ?> - form->hidden('project_id', $values) ?> - - task->selectColor($values) ?> - task->selectAssignee($users_list, $values, $errors) ?> - task->selectCategory($categories_list, $values, $errors) ?> - - form->label(t('Tasks'), 'tasks') ?> - form->textarea('tasks', $values, $errors, array('placeholder="'.t('My task title').'"')) ?> -

- -
- - url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?> -
-
- diff --git a/sources/app/Template/task_creation/show.php b/sources/app/Template/task_creation/show.php deleted file mode 100644 index 57e77f3..0000000 --- a/sources/app/Template/task_creation/show.php +++ /dev/null @@ -1,49 +0,0 @@ - - -
- form->csrf() ?> - -
-
- task->selectTitle($values, $errors) ?> - task->selectDescription($values, $errors) ?> - task->selectTags($project) ?> - - - form->checkbox('another_task', t('Create another task'), 1, isset($values['another_task']) && $values['another_task'] == 1) ?> - - - hook->render('template:task:form:first-column', array('values' => $values, 'errors' => $errors)) ?> -
- -
- form->hidden('project_id', $values) ?> - task->selectColor($values) ?> - task->selectAssignee($users_list, $values, $errors) ?> - task->selectCategory($categories_list, $values, $errors) ?> - task->selectSwimlane($swimlanes_list, $values, $errors) ?> - task->selectColumn($columns_list, $values, $errors) ?> - task->selectPriority($project, $values) ?> - task->selectScore($values, $errors) ?> - task->selectReference($values, $errors) ?> - - hook->render('template:task:form:second-column', array('values' => $values, 'errors' => $errors)) ?> -
- -
- task->selectTimeEstimated($values, $errors) ?> - task->selectTimeSpent($values, $errors) ?> - task->selectStartDate($values, $errors) ?> - task->selectDueDate($values, $errors) ?> - - hook->render('template:task:form:third-column', array('values' => $values, 'errors' => $errors)) ?> -
-
- -
- - url->link(t('cancel'), 'BoardViewController', 'show', array('project_id' => $values['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_duplication/copy.php b/sources/app/Template/task_duplication/copy.php deleted file mode 100644 index 58b4d83..0000000 --- a/sources/app/Template/task_duplication/copy.php +++ /dev/null @@ -1,48 +0,0 @@ - - - -

- - -
- - form->csrf() ?> - form->hidden('id', $values) ?> - - form->label(t('Project'), 'project_id') ?> - 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' - ) ?> - - - form->label(t('Swimlane'), 'swimlane_id') ?> - form->select('swimlane_id', $swimlanes_list, $values) ?> -

- - form->label(t('Column'), 'column_id') ?> - form->select('column_id', $columns_list, $values) ?> -

- - form->label(t('Category'), 'category_id') ?> - form->select('category_id', $categories_list, $values) ?> -

- - form->label(t('Assignee'), 'owner_id') ?> - form->select('owner_id', $users_list, $values) ?> -

- -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
- - diff --git a/sources/app/Template/task_duplication/duplicate.php b/sources/app/Template/task_duplication/duplicate.php deleted file mode 100644 index c0baf94..0000000 --- a/sources/app/Template/task_duplication/duplicate.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'TaskDuplicationController', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_duplication/move.php b/sources/app/Template/task_duplication/move.php deleted file mode 100644 index 8f01c4b..0000000 --- a/sources/app/Template/task_duplication/move.php +++ /dev/null @@ -1,48 +0,0 @@ - - - -

- - -
- - form->csrf() ?> - form->hidden('id', $values) ?> - - form->label(t('Project'), 'project_id') ?> - 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' - ) ?> - - - form->label(t('Swimlane'), 'swimlane_id') ?> - form->select('swimlane_id', $swimlanes_list, $values) ?> -

- - form->label(t('Column'), 'column_id') ?> - form->select('column_id', $columns_list, $values) ?> -

- - form->label(t('Category'), 'category_id') ?> - form->select('category_id', $categories_list, $values) ?> -

- - form->label(t('Assignee'), 'owner_id') ?> - form->select('owner_id', $users_list, $values) ?> -

- -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
- - diff --git a/sources/app/Template/task_external_link/create.php b/sources/app/Template/task_external_link/create.php deleted file mode 100644 index beddfc9..0000000 --- a/sources/app/Template/task_external_link/create.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
- render('task_external_link/form', array('task' => $task, 'dependencies' => $dependencies, 'values' => $values, 'errors' => $errors)) ?> - -
- - - url->link(t('cancel'), 'TaskExternalLinkController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_external_link/edit.php b/sources/app/Template/task_external_link/edit.php deleted file mode 100644 index 917a28b..0000000 --- a/sources/app/Template/task_external_link/edit.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
- render('task_external_link/form', array('task' => $task, 'dependencies' => $dependencies, 'values' => $values, 'errors' => $errors)) ?> - -
- - - url->link(t('cancel'), 'TaskExternalLinkController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_external_link/find.php b/sources/app/Template/task_external_link/find.php deleted file mode 100644 index a88b29c..0000000 --- a/sources/app/Template/task_external_link/find.php +++ /dev/null @@ -1,28 +0,0 @@ - - -
- form->csrf() ?> - form->hidden('task_id', array('task_id' => $task['id'])) ?> - - form->label(t('External link'), 'text') ?> - form->text( - 'text', - $values, - $errors, - array( - 'required', - 'autofocus', - 'placeholder="'.t('Copy and paste your link here...').'"', - )) ?> - - form->label(t('Link type'), 'type') ?> - form->select('type', $types, $values) ?> - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_external_link/form.php b/sources/app/Template/task_external_link/form.php deleted file mode 100644 index 932ca52..0000000 --- a/sources/app/Template/task_external_link/form.php +++ /dev/null @@ -1,13 +0,0 @@ -form->csrf() ?> -form->hidden('task_id', array('task_id' => $task['id'])) ?> -form->hidden('id', $values) ?> -form->hidden('link_type', $values) ?> - -form->label(t('URL'), 'url') ?> -form->text('url', $values, $errors, array('required')) ?> - -form->label(t('Title'), 'title') ?> -form->text('title', $values, $errors, array('required')) ?> - -form->label(t('Dependency'), 'dependency') ?> -form->select('dependency', $dependencies, $values, $errors) ?> diff --git a/sources/app/Template/task_external_link/remove.php b/sources/app/Template/task_external_link/remove.php deleted file mode 100644 index 2a888a6..0000000 --- a/sources/app/Template/task_external_link/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'TaskExternalLinkController', 'remove', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'TaskExternalLinkController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_external_link/show.php b/sources/app/Template/task_external_link/show.php deleted file mode 100644 index 8ed1180..0000000 --- a/sources/app/Template/task_external_link/show.php +++ /dev/null @@ -1,12 +0,0 @@ -
-
-

-
-
- render('task_external_link/table', array( - 'links' => $links, - 'task' => $task, - 'project' => $project, - )) ?> -
-
diff --git a/sources/app/Template/task_external_link/table.php b/sources/app/Template/task_external_link/table.php deleted file mode 100644 index 56ef036..0000000 --- a/sources/app/Template/task_external_link/table.php +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - user->hasProjectAccess('TaskExternalLinkController', 'edit', $task['project_id'])): ?> - - - - - - - - - - - user->hasProjectAccess('TaskExternalLinkController', 'edit', $task['project_id'])): ?> - - - - -
- - - text->e($link['title']) ?> - - text->e($link['dependency_label']) ?> - - text->e($link['creator_name'] ?: $link['creator_username']) ?> - - dt->date($link['date_creation']) ?> - - -
- diff --git a/sources/app/Template/task_file/create.php b/sources/app/Template/task_file/create.php deleted file mode 100644 index e05cf82..0000000 --- a/sources/app/Template/task_file/create.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -
-
- -
-
- - - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
diff --git a/sources/app/Template/task_file/files.php b/sources/app/Template/task_file/files.php deleted file mode 100644 index 7ca59b1..0000000 --- a/sources/app/Template/task_file/files.php +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - -
- - - - text->e($file['user_name'] ?: $file['username']) ?> - - dt->date($file['date']) ?> - - text->bytes($file['size']) ?> -
- diff --git a/sources/app/Template/task_file/images.php b/sources/app/Template/task_file/images.php deleted file mode 100644 index 81c3315..0000000 --- a/sources/app/Template/task_file/images.php +++ /dev/null @@ -1,34 +0,0 @@ - -
- -
- <?= $this->text->e($file['name']) ?> -
-
- -
-
- dt->datetime($file['date'])).'
'.t('Size: %s', $this->text->bytes($file['size'])) ?>'> - -
- -
-
-
- -
- diff --git a/sources/app/Template/task_file/remove.php b/sources/app/Template/task_file/remove.php deleted file mode 100644 index 42894f0..0000000 --- a/sources/app/Template/task_file/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- text->e($file['name'])) ?> -

- -
- url->link(t('Yes'), 'TaskFileController', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_file/screenshot.php b/sources/app/Template/task_file/screenshot.php deleted file mode 100644 index 6300159..0000000 --- a/sources/app/Template/task_file/screenshot.php +++ /dev/null @@ -1,19 +0,0 @@ - - -
-

-
- -
- - form->csrf() ?> -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
- -

diff --git a/sources/app/Template/task_file/show.php b/sources/app/Template/task_file/show.php deleted file mode 100644 index df69605..0000000 --- a/sources/app/Template/task_file/show.php +++ /dev/null @@ -1,9 +0,0 @@ -
-
-

-
-
- render('task_file/images', array('task' => $task, 'images' => $images)) ?> - render('task_file/files', array('task' => $task, 'files' => $files)) ?> -
-
diff --git a/sources/app/Template/task_gantt/show.php b/sources/app/Template/task_gantt/show.php deleted file mode 100644 index c5d338f..0000000 --- a/sources/app/Template/task_gantt/show.php +++ /dev/null @@ -1,34 +0,0 @@ -
- projectHeader->render($project, 'TaskGanttController', 'show') ?> - - - -
-

- -

- -
diff --git a/sources/app/Template/task_gantt_creation/show.php b/sources/app/Template/task_gantt_creation/show.php deleted file mode 100644 index 7521d80..0000000 --- a/sources/app/Template/task_gantt_creation/show.php +++ /dev/null @@ -1,46 +0,0 @@ - -
- form->csrf() ?> - form->hidden('project_id', $values) ?> - form->hidden('column_id', $values) ?> - form->hidden('position', $values) ?> - -
-
- task->selectTitle($values, $errors) ?> - task->selectDescription($values, $errors) ?> - task->selectTags($project) ?> - - hook->render('template:task:form:first-column', array('values' => $values, 'errors' => $errors)) ?> -
- -
- task->selectColor($values) ?> - task->selectAssignee($users_list, $values, $errors) ?> - task->selectCategory($categories_list, $values, $errors) ?> - task->selectSwimlane($swimlanes_list, $values, $errors) ?> - task->selectPriority($project, $values) ?> - task->selectScore($values, $errors) ?> - task->selectReference($values, $errors) ?> - - hook->render('template:task:form:second-column', array('values' => $values, 'errors' => $errors)) ?> -
- -
- task->selectTimeEstimated($values, $errors) ?> - task->selectTimeSpent($values, $errors) ?> - task->selectStartDate($values, $errors) ?> - task->selectDueDate($values, $errors) ?> - - hook->render('template:task:form:third-column', array('values' => $values, 'errors' => $errors)) ?> -
-
- -
- - - url->link(t('cancel'), 'TaskGanttController', 'show', array('project_id' => $values['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_import/show.php b/sources/app/Template/task_import/show.php deleted file mode 100644 index cc6a7b3..0000000 --- a/sources/app/Template/task_import/show.php +++ /dev/null @@ -1,34 +0,0 @@ - -
- form->csrf() ?> - - form->label(t('Delimiter'), 'delimiter') ?> - form->select('delimiter', $delimiters, $values) ?> - - form->label(t('Enclosure'), 'enclosure') ?> - form->select('enclosure', $enclosures, $values) ?> - - form->label(t('CSV File'), 'file') ?> - form->file('file', $errors) ?> - -

text->bytes($max_size) : $max_size ?>

- -
- -
-
- -
-
    -
  • -
  • -
  • -
  • -
  • -
-
-

url->link(t('Download CSV template'), 'TaskImportController', 'template', array('project_id' => $project['id'])) ?>

diff --git a/sources/app/Template/task_import/sidebar.php b/sources/app/Template/task_import/sidebar.php deleted file mode 100644 index 4cd92af..0000000 --- a/sources/app/Template/task_import/sidebar.php +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/sources/app/Template/task_internal_link/create.php b/sources/app/Template/task_internal_link/create.php deleted file mode 100644 index fed2960..0000000 --- a/sources/app/Template/task_internal_link/create.php +++ /dev/null @@ -1,33 +0,0 @@ - - -
- - form->csrf() ?> - form->hidden('task_id', array('task_id' => $task['id'])) ?> - form->hidden('opposite_task_id', $values) ?> - - form->label(t('Label'), 'link_id') ?> - form->select('link_id', $labels, $values, $errors) ?> - - form->label(t('Task'), 'title') ?> - form->text( - 'title', - $values, - $errors, - array( - 'required', - 'placeholder="'.t('Start to type task title...').'"', - 'title="'.t('Start to type task title...').'"', - 'data-dst-field="opposite_task_id"', - 'data-search-url="'.$this->url->href('TaskAjaxController', 'autocomplete', array('exclude_task_id' => $task['id'])).'"', - ), - 'autocomplete') ?> - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_internal_link/edit.php b/sources/app/Template/task_internal_link/edit.php deleted file mode 100644 index f4df57b..0000000 --- a/sources/app/Template/task_internal_link/edit.php +++ /dev/null @@ -1,34 +0,0 @@ - - -
- - form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('task_id', $values) ?> - form->hidden('opposite_task_id', $values) ?> - - form->label(t('Label'), 'link_id') ?> - form->select('link_id', $labels, $values, $errors) ?> - - form->label(t('Task'), 'title') ?> - form->text( - 'title', - $values, - $errors, - array( - 'required', - 'placeholder="'.t('Start to type task title...').'"', - 'title="'.t('Start to type task title...').'"', - 'data-dst-field="opposite_task_id"', - 'data-search-url="'.$this->url->href('TaskAjaxController', 'autocomplete', array('exclude_task_id' => $task['id'])).'"', - ), - 'autocomplete') ?> - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_internal_link/remove.php b/sources/app/Template/task_internal_link/remove.php deleted file mode 100644 index 966ad11..0000000 --- a/sources/app/Template/task_internal_link/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'TaskInternalLinkController', 'remove', array('link_id' => $link['id'], 'task_id' => $task['id'], 'project_id' => $task['project_id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_internal_link/show.php b/sources/app/Template/task_internal_link/show.php deleted file mode 100644 index cc05429..0000000 --- a/sources/app/Template/task_internal_link/show.php +++ /dev/null @@ -1,14 +0,0 @@ -
-
-

-
-
- render('task_internal_link/table', array( - 'links' => $links, - 'task' => $task, - 'project' => $project, - 'editable' => $editable, - 'is_public' => $is_public, - )) ?> -
-
diff --git a/sources/app/Template/task_internal_link/table.php b/sources/app/Template/task_internal_link/table.php deleted file mode 100644 index 424d479..0000000 --- a/sources/app/Template/task_internal_link/table.php +++ /dev/null @@ -1,85 +0,0 @@ - - - $grouped_links): ?> - - - - - - - - - - - - - - - - - - - - user->hasProjectAccess('Tasklink', 'edit', $task['project_id'])): ?> - - - - - - - diff --git a/sources/app/Template/task_list/show.php b/sources/app/Template/task_list/show.php deleted file mode 100644 index bb95b6a..0000000 --- a/sources/app/Template/task_list/show.php +++ /dev/null @@ -1,62 +0,0 @@ -
- projectHeader->render($project, 'TaskListController', 'show') ?> - - isEmpty()): ?> -

- isEmpty()): ?> - - - - - - - - - - - - getCollection() as $task): ?> - - - - - - - - - - - -
order(t('Id'), 'tasks.id') ?>order(t('Swimlane'), 'tasks.swimlane_id') ?>order(t('Column'), 'tasks.column_id') ?>order(t('Category'), 'tasks.category_id') ?>order(t('Title'), 'tasks.title') ?>order(t('Assignee'), 'users.username') ?>order(t('Due date'), 'tasks.date_due') ?>order(t('Status'), 'tasks.is_active') ?>
- user->hasProjectAccess('TaskModificationController', 'edit', $task['project_id'])): ?> - render('task/dropdown', array('task' => $task)) ?> - - # - - - text->e($task['swimlane_name'] ?: $task['default_swimlane']) ?> - - text->e($task['column_name']) ?> - - text->e($task['category_name']) ?> - - url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?> - - - text->e($task['assignee_name'] ?: $task['assignee_username']) ?> - - - - - dt->date($task['date_due']) ?> - - - - - - -
- - - -
diff --git a/sources/app/Template/task_modification/show.php b/sources/app/Template/task_modification/show.php deleted file mode 100644 index cc38582..0000000 --- a/sources/app/Template/task_modification/show.php +++ /dev/null @@ -1,44 +0,0 @@ - -
- form->csrf() ?> - form->hidden('id', $values) ?> - form->hidden('project_id', $values) ?> - -
-
- task->selectTitle($values, $errors) ?> - task->selectDescription($values, $errors) ?> - task->selectTags($project, $tags) ?> - - hook->render('template:task:form:first-column', array('values' => $values, 'errors' => $errors)) ?> -
- -
- task->selectColor($values) ?> - task->selectAssignee($users_list, $values, $errors) ?> - task->selectCategory($categories_list, $values, $errors) ?> - task->selectPriority($project, $values) ?> - task->selectScore($values, $errors) ?> - task->selectReference($values, $errors) ?> - - hook->render('template:task:form:second-column', array('values' => $values, 'errors' => $errors)) ?> -
- -
- task->selectTimeEstimated($values, $errors) ?> - task->selectTimeSpent($values, $errors) ?> - task->selectStartDate($values, $errors) ?> - task->selectDueDate($values, $errors) ?> - - hook->render('template:task:form:third-column', array('values' => $values, 'errors' => $errors)) ?> -
-
- -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_recurrence/edit.php b/sources/app/Template/task_recurrence/edit.php deleted file mode 100644 index 09d1482..0000000 --- a/sources/app/Template/task_recurrence/edit.php +++ /dev/null @@ -1,47 +0,0 @@ - - - -
- render('task_recurrence/info', array( - 'task' => $task, - 'recurrence_trigger_list' => $recurrence_trigger_list, - 'recurrence_timeframe_list' => $recurrence_timeframe_list, - 'recurrence_basedate_list' => $recurrence_basedate_list, - )) ?> -
- - - - -
- - form->csrf() ?> - - form->hidden('id', $values) ?> - form->hidden('project_id', $values) ?> - - form->label(t('Generate recurrent task'), 'recurrence_status') ?> - form->select('recurrence_status', $recurrence_status_list, $values, $errors) ?> - - form->label(t('Trigger to generate recurrent task'), 'recurrence_trigger') ?> - form->select('recurrence_trigger', $recurrence_trigger_list, $values, $errors) ?> - - form->label(t('Factor to calculate new due date'), 'recurrence_factor') ?> - form->number('recurrence_factor', $values, $errors) ?> - - form->label(t('Timeframe to calculate new due date'), 'recurrence_timeframe') ?> - form->select('recurrence_timeframe', $recurrence_timeframe_list, $values, $errors) ?> - - form->label(t('Base date to calculate new due date'), 'recurrence_basedate') ?> - form->select('recurrence_basedate', $recurrence_basedate_list, $values, $errors) ?> - -
- - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
- - diff --git a/sources/app/Template/task_recurrence/info.php b/sources/app/Template/task_recurrence/info.php deleted file mode 100644 index 04d58c7..0000000 --- a/sources/app/Template/task_recurrence/info.php +++ /dev/null @@ -1,37 +0,0 @@ - diff --git a/sources/app/Template/task_status/close.php b/sources/app/Template/task_status/close.php deleted file mode 100644 index 2d7b0ce..0000000 --- a/sources/app/Template/task_status/close.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'TaskStatusController', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red popover-link') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_status/open.php b/sources/app/Template/task_status/open.php deleted file mode 100644 index 242b5db..0000000 --- a/sources/app/Template/task_status/open.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red popover-link') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/task_suppression/remove.php b/sources/app/Template/task_suppression/remove.php deleted file mode 100644 index 5d0f772..0000000 --- a/sources/app/Template/task_suppression/remove.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-

- text->e($task['title'])) ?> -

- -
- url->link(t('Yes'), 'TaskSuppressionController', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => $redirect), true, 'btn btn-red popover-link') ?> - - url->link(t('cancel'), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/twofactor/check.php b/sources/app/Template/twofactor/check.php deleted file mode 100644 index 06801d5..0000000 --- a/sources/app/Template/twofactor/check.php +++ /dev/null @@ -1,10 +0,0 @@ -
- - form->csrf() ?> - form->label(t('Code'), 'code') ?> - form->text('code', array(), array(), array('placeholder="123456"', 'autofocus'), 'form-numeric') ?> - -
- -
-
diff --git a/sources/app/Template/twofactor/disable.php b/sources/app/Template/twofactor/disable.php deleted file mode 100644 index bc41918..0000000 --- a/sources/app/Template/twofactor/disable.php +++ /dev/null @@ -1,14 +0,0 @@ - - -
-

- -

- -
- url->link(t('Yes'), 'TwoFactorController', 'disable', array('user_id' => $user['id'], 'disable' => 'yes'), true, 'btn btn-red') ?> - url->link(t('cancel'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?> -
-
diff --git a/sources/app/Template/twofactor/index.php b/sources/app/Template/twofactor/index.php deleted file mode 100644 index 1ed414e..0000000 --- a/sources/app/Template/twofactor/index.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
- form->csrf() ?> -

text->e($provider) ?>

-
- - - - - -
-
diff --git a/sources/app/Template/twofactor/show.php b/sources/app/Template/twofactor/show.php deleted file mode 100644 index 0aeef42..0000000 --- a/sources/app/Template/twofactor/show.php +++ /dev/null @@ -1,31 +0,0 @@ - - - -
- -

text->e($secret) ?>

- - - -




- - - -

text->e($key_url) ?>

- -
- - -

-
- - form->csrf() ?> - form->label(t('Code'), 'code') ?> - form->text('code', array(), array(), array('placeholder="123456"', 'autofocus'), 'form-numeric') ?> - -
- -
-
diff --git a/sources/app/Template/user_creation/local.php b/sources/app/Template/user_creation/local.php deleted file mode 100644 index 059a011..0000000 --- a/sources/app/Template/user_creation/local.php +++ /dev/null @@ -1,47 +0,0 @@ - -
- form->csrf() ?> - -
-
- form->label(t('Username'), 'username') ?> - form->text('username', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors) ?> - - form->label(t('Email'), 'email') ?> - form->email('email', $values, $errors) ?> - - form->label(t('Password'), 'password') ?> - form->password('password', $values, $errors, array('required')) ?> - - form->label(t('Confirmation'), 'confirmation') ?> - form->password('confirmation', $values, $errors, array('required')) ?> -
- -
- form->label(t('Add project member'), 'project_id') ?> - form->select('project_id', $projects, $values, $errors) ?> - - form->label(t('Timezone'), 'timezone') ?> - form->select('timezone', $timezones, $values, $errors) ?> - - form->label(t('Language'), 'language') ?> - form->select('language', $languages, $values, $errors) ?> - - form->label(t('Role'), 'role') ?> - form->select('role', $roles, $values, $errors) ?> - - form->checkbox('notifications_enabled', t('Enable email notifications'), 1, isset($values['notifications_enabled']) && $values['notifications_enabled'] == 1 ? true : false) ?> -
-
- -
- - - url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/user_creation/remote.php b/sources/app/Template/user_creation/remote.php deleted file mode 100644 index 41d0d3c..0000000 --- a/sources/app/Template/user_creation/remote.php +++ /dev/null @@ -1,51 +0,0 @@ - -
- form->csrf() ?> - form->hidden('is_ldap_user', array('is_ldap_user' => 1)) ?> - -
-
- form->label(t('Username'), 'username') ?> - form->text('username', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors) ?> - - form->label(t('Email'), 'email') ?> - form->email('email', $values, $errors) ?> - - hook->render('template:user:create-remote:form', array('values' => $values, 'errors' => $errors)) ?> -
- -
- form->label(t('Add project member'), 'project_id') ?> - form->select('project_id', $projects, $values, $errors) ?> - - form->label(t('Timezone'), 'timezone') ?> - form->select('timezone', $timezones, $values, $errors) ?> - - form->label(t('Language'), 'language') ?> - form->select('language', $languages, $values, $errors) ?> - - form->label(t('Role'), 'role') ?> - form->select('role', $roles, $values, $errors) ?> - - form->checkbox('notifications_enabled', t('Enable email notifications'), 1, isset($values['notifications_enabled']) && $values['notifications_enabled'] == 1 ? true : false) ?> - form->checkbox('disable_login_form', t('Disallow login form'), 1, isset($values['disable_login_form']) && $values['disable_login_form'] == 1) ?> -
-
- -
- - - url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?> -
-
-
-
    -
  • -
  • -
-
diff --git a/sources/app/Template/user_credential/authentication.php b/sources/app/Template/user_credential/authentication.php deleted file mode 100644 index fbe2e91..0000000 --- a/sources/app/Template/user_credential/authentication.php +++ /dev/null @@ -1,27 +0,0 @@ - -
- form->csrf() ?> - - form->hidden('id', $values) ?> - form->hidden('username', $values) ?> - - hook->render('template:user:authentication:form', array('values' => $values, 'errors' => $errors, 'user' => $user)) ?> - - form->checkbox('is_ldap_user', t('Remote user'), 1, isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1) ?> - form->checkbox('disable_login_form', t('Disallow login form'), 1, isset($values['disable_login_form']) && $values['disable_login_form'] == 1) ?> - -
- - - url->link(t('cancel'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?> -
- -
-
    -
  • -
  • -
-
-
diff --git a/sources/app/Template/user_credential/password.php b/sources/app/Template/user_credential/password.php deleted file mode 100644 index 5a6e440..0000000 --- a/sources/app/Template/user_credential/password.php +++ /dev/null @@ -1,23 +0,0 @@ - - -
- form->hidden('id', $values) ?> - form->csrf() ?> - - form->label(t('Current password for the user "%s"', $this->user->getFullname()), 'current_password') ?> - form->password('current_password', $values, $errors) ?> - - form->label(t('New password for the user "%s"', $this->user->getFullname($user)), 'password') ?> - form->password('password', $values, $errors) ?> - - form->label(t('Confirmation'), 'confirmation') ?> - form->password('confirmation', $values, $errors) ?> - -
- - - url->link(t('cancel'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?> -
-
diff --git a/sources/app/Template/user_import/show.php b/sources/app/Template/user_import/show.php deleted file mode 100644 index 663f107..0000000 --- a/sources/app/Template/user_import/show.php +++ /dev/null @@ -1,41 +0,0 @@ - - -
-
    -
  • -
  • -
  • -
  • -
  • -
  • -
-
- -
- form->csrf() ?> - - form->label(t('Delimiter'), 'delimiter') ?> - form->select('delimiter', $delimiters, $values) ?> - - form->label(t('Enclosure'), 'enclosure') ?> - form->select('enclosure', $enclosures, $values) ?> - - form->label(t('CSV File'), 'file') ?> - form->file('file', $errors) ?> - -

text->bytes($max_size) : $max_size ?>

- -
- - - url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/user_list/dropdown.php b/sources/app/Template/user_list/dropdown.php deleted file mode 100644 index 9e90c23..0000000 --- a/sources/app/Template/user_list/dropdown.php +++ /dev/null @@ -1,27 +0,0 @@ - diff --git a/sources/app/Template/user_list/show.php b/sources/app/Template/user_list/show.php deleted file mode 100644 index b2bd937..0000000 --- a/sources/app/Template/user_list/show.php +++ /dev/null @@ -1,66 +0,0 @@ -
- - isEmpty()): ?> -

- - - - - - - - - - - - - - getCollection() as $user): ?> - - - - - - - - - - - - -
order(t('Id'), 'id') ?>order(t('Username'), 'username') ?>order(t('Name'), 'name') ?>order(t('Email'), 'email') ?>order(t('Role'), 'role') ?>order(t('Two Factor'), 'twofactor_activated') ?>order(t('Account type'), 'is_ldap_user') ?>order(t('Status'), 'is_active') ?>
- - - url->link($this->text->e($user['username']), 'UserViewController', 'show', array('user_id' => $user['id'])) ?> - - text->e($user['name']) ?> - - text->e($user['email']) ?> - - user->getRoleName($user['role']) ?> - - - - - - - - - - - - render('user_list/dropdown', array('user' => $user)) ?> -
- - - -
diff --git a/sources/app/Template/user_modification/show.php b/sources/app/Template/user_modification/show.php deleted file mode 100644 index 396d550..0000000 --- a/sources/app/Template/user_modification/show.php +++ /dev/null @@ -1,35 +0,0 @@ - -
- - form->csrf() ?> - - form->hidden('id', $values) ?> - - form->label(t('Username'), 'username') ?> - form->text('username', $values, $errors, array('required', isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1 ? 'readonly' : '', 'maxlength="50"')) ?> - - form->label(t('Name'), 'name') ?> - form->text('name', $values, $errors) ?> - - form->label(t('Email'), 'email') ?> - form->email('email', $values, $errors) ?> - - form->label(t('Timezone'), 'timezone') ?> - form->select('timezone', $timezones, $values, $errors) ?> - - form->label(t('Language'), 'language') ?> - form->select('language', $languages, $values, $errors) ?> - - user->isAdmin()): ?> - form->label(t('Role'), 'role') ?> - form->select('role', $roles, $values, $errors) ?> - - -
- - - url->link(t('cancel'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?> -
-
diff --git a/sources/app/Template/user_status/disable.php b/sources/app/Template/user_status/disable.php deleted file mode 100644 index d30b0c2..0000000 --- a/sources/app/Template/user_status/disable.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
-

- -
- url->link(t('Yes'), 'UserStatusController', 'disable', array('user_id' => $user['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/user_status/enable.php b/sources/app/Template/user_status/enable.php deleted file mode 100644 index 29d25ee..0000000 --- a/sources/app/Template/user_status/enable.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
-

- -
- url->link(t('Yes'), 'UserStatusController', 'enable', array('user_id' => $user['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/user_status/remove.php b/sources/app/Template/user_status/remove.php deleted file mode 100644 index 2b8f2df..0000000 --- a/sources/app/Template/user_status/remove.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
-

- -
- url->link(t('Yes'), 'UserStatusController', 'remove', array('user_id' => $user['id']), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'UserListController', 'show', array(), false, 'close-popover') ?> -
-
diff --git a/sources/app/Template/user_view/external.php b/sources/app/Template/user_view/external.php deleted file mode 100644 index 22c25af..0000000 --- a/sources/app/Template/user_view/external.php +++ /dev/null @@ -1,11 +0,0 @@ - - -hook->render('template:user:external', array('user' => $user)) ?> - - -

- - - diff --git a/sources/app/Template/user_view/integrations.php b/sources/app/Template/user_view/integrations.php deleted file mode 100644 index 4a23734..0000000 --- a/sources/app/Template/user_view/integrations.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
- form->csrf() ?> - hook->render('template:user:integrations', array('values' => $values)) ?> - - - -

- -
diff --git a/sources/app/Template/user_view/last.php b/sources/app/Template/user_view/last.php deleted file mode 100644 index 3de4d5e..0000000 --- a/sources/app/Template/user_view/last.php +++ /dev/null @@ -1,24 +0,0 @@ - - - -

- - - - - - - - - - - - - - - - -
dt->datetime($login['date_creation']) ?>text->e($login['auth_type']) ?>text->e($login['ip']) ?>text->e($login['user_agent']) ?>
- \ No newline at end of file diff --git a/sources/app/Template/user_view/layout.php b/sources/app/Template/user_view/layout.php deleted file mode 100644 index c3604b9..0000000 --- a/sources/app/Template/user_view/layout.php +++ /dev/null @@ -1,19 +0,0 @@ -
- - -
diff --git a/sources/app/Template/user_view/notifications.php b/sources/app/Template/user_view/notifications.php deleted file mode 100644 index 84ca128..0000000 --- a/sources/app/Template/user_view/notifications.php +++ /dev/null @@ -1,26 +0,0 @@ - - -
- form->csrf() ?> - -

- form->checkboxes('notification_types', $types, $notifications) ?> - -
-

- form->radios('notifications_filter', $filters, $notifications) ?> - -
- -

- form->checkboxes('notification_projects', $projects, $notifications) ?> - - -
- - - url->link(t('cancel'), 'UserViewController', 'show', array('user_id' => $user['id'])) ?> -
-
diff --git a/sources/app/Template/user_view/password_reset.php b/sources/app/Template/user_view/password_reset.php deleted file mode 100644 index 1371ce1..0000000 --- a/sources/app/Template/user_view/password_reset.php +++ /dev/null @@ -1,26 +0,0 @@ - - - -

- - - - - - - - - - - - - - - - - - -
dt->datetime($token['date_creation']) ?>dt->datetime($token['date_expiration']) ?>text->e($token['ip']) ?>text->e($token['user_agent']) ?>
- \ No newline at end of file diff --git a/sources/app/Template/user_view/profile.php b/sources/app/Template/user_view/profile.php deleted file mode 100644 index 9c9d328..0000000 --- a/sources/app/Template/user_view/profile.php +++ /dev/null @@ -1,9 +0,0 @@ -
-
- avatar->render($user['id'], $user['username'], $user['name'], $user['email'], $user['avatar_path']) ?> -
    -
  • text->e($user['username']) ?>
  • -
  • text->e($user['name']) ?: t('None') ?>
  • -
  • text->e($user['email']) ?: t('None') ?>
  • -
-
\ No newline at end of file diff --git a/sources/app/Template/user_view/sessions.php b/sources/app/Template/user_view/sessions.php deleted file mode 100644 index eda3ef7..0000000 --- a/sources/app/Template/user_view/sessions.php +++ /dev/null @@ -1,26 +0,0 @@ - - - -

- - - - - - - - - - - - - - - - - - -
dt->datetime($session['date_creation']) ?>dt->datetime($session['expiration']) ?>text->e($session['ip']) ?>text->e($session['user_agent']) ?>url->link(t('Remove'), 'UserViewController', 'removeSession', array('user_id' => $user['id'], 'id' => $session['id']), true) ?>
- diff --git a/sources/app/Template/user_view/share.php b/sources/app/Template/user_view/share.php deleted file mode 100644 index 570b766..0000000 --- a/sources/app/Template/user_view/share.php +++ /dev/null @@ -1,15 +0,0 @@ - - - -
-
    -
  • url->link(t('RSS feed'), 'FeedController', 'user', array('token' => $user['token']), false, '', '', true) ?>
  • -
  • url->link(t('iCal feed'), 'ICalendarController', 'user', array('token' => $user['token']), false, '', '', true) ?>
  • -
-
- url->link(t('Disable public access'), 'UserViewController', 'share', array('user_id' => $user['id'], 'switch' => 'disable'), true, 'btn btn-red') ?> - - url->link(t('Enable public access'), 'UserViewController', 'share', array('user_id' => $user['id'], 'switch' => 'enable'), true, 'btn btn-blue') ?> - diff --git a/sources/app/Template/user_view/show.php b/sources/app/Template/user_view/show.php deleted file mode 100644 index fc11f8a..0000000 --- a/sources/app/Template/user_view/show.php +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - -
-
    -
  • url->link(t('RSS feed'), 'FeedController', 'user', array('token' => $user['token']), false, '', '', true) ?>
  • -
  • url->link(t('iCal feed'), 'ICalendarController', 'user', array('token' => $user['token']), false, '', '', true) ?>
  • -
-
- diff --git a/sources/app/Template/user_view/sidebar.php b/sources/app/Template/user_view/sidebar.php deleted file mode 100644 index d200a7f..0000000 --- a/sources/app/Template/user_view/sidebar.php +++ /dev/null @@ -1,83 +0,0 @@ - diff --git a/sources/app/Template/user_view/timesheet.php b/sources/app/Template/user_view/timesheet.php deleted file mode 100644 index 3df5749..0000000 --- a/sources/app/Template/user_view/timesheet.php +++ /dev/null @@ -1,29 +0,0 @@ - - -

-isEmpty()): ?> -

- - - - - - - - - - getCollection() as $record): ?> - - - - - - - - -
order(t('Task'), 'task_title') ?>order(t('Subtask'), 'subtask_title') ?>order(t('Start'), 'start') ?>order(t('End'), 'end') ?>order(t('Time spent'), 'time_spent') ?>
url->link($this->text->e($record['task_title']), 'TaskViewController', 'show', array('project_id' => $record['project_id'], 'task_id' => $record['task_id'])) ?>url->link($this->text->e($record['subtask_title']), 'TaskViewController', 'show', array('project_id' => $record['project_id'], 'task_id' => $record['task_id'])) ?>dt->datetime($record['start']) ?>dt->datetime($record['end']) ?>
- - - diff --git a/sources/app/User/Avatar/AvatarFileProvider.php b/sources/app/User/Avatar/AvatarFileProvider.php deleted file mode 100644 index 790245a..0000000 --- a/sources/app/User/Avatar/AvatarFileProvider.php +++ /dev/null @@ -1,42 +0,0 @@ -helper->url->href('AvatarFileController', 'image', array('user_id' => $user['id'], 'size' => $size)); - $title = $this->helper->text->e($user['name'] ?: $user['username']); - return '' . $title . ''; - } - - /** - * Determine if the provider is active - * - * @access public - * @param array $user - * @return boolean - */ - public function isActive(array $user) - { - return !empty($user['avatar_path']); - } -} diff --git a/sources/app/User/Avatar/GravatarProvider.php b/sources/app/User/Avatar/GravatarProvider.php deleted file mode 100644 index e066d76..0000000 --- a/sources/app/User/Avatar/GravatarProvider.php +++ /dev/null @@ -1,42 +0,0 @@ -helper->text->e($user['name'] ?: $user['username']); - return ''.$title.''; - } - - /** - * Determine if the provider is active - * - * @access public - * @param array $user - * @return boolean - */ - public function isActive(array $user) - { - return !empty($user['email']) && $this->configModel->get('integration_gravatar') == 1; - } -} diff --git a/sources/app/User/Avatar/LetterAvatarProvider.php b/sources/app/User/Avatar/LetterAvatarProvider.php deleted file mode 100644 index 727f910..0000000 --- a/sources/app/User/Avatar/LetterAvatarProvider.php +++ /dev/null @@ -1,170 +0,0 @@ -helper->user->getInitials($user['name'] ?: $user['username']); - $rgb = $this->getBackgroundColor($user['name'] ?: $user['username']); - - return sprintf( - '
%s
', - $rgb[0], - $rgb[1], - $rgb[2], - $this->helper->text->e($user['name'] ?: $user['username']), - $initials - ); - } - - /** - * Determine if the provider is active - * - * @access public - * @param array $user - * @return boolean - */ - public function isActive(array $user) - { - return true; - } - - /** - * Get background color based on a string - * - * @param string $str - * @return array - */ - public function getBackgroundColor($str) - { - $hsl = $this->getHSL($str); - return $this->getRGB($hsl[0], $hsl[1], $hsl[2]); - } - - /** - * Convert HSL to RGB - * - * @access protected - * @param integer $hue Hue ∈ [0, 360) - * @param integer $saturation Saturation ∈ [0, 1] - * @param integer $lightness Lightness ∈ [0, 1] - * @return array - */ - protected function getRGB($hue, $saturation, $lightness) - { - $hue /= 360; - $q = $lightness < 0.5 ? $lightness * (1 + $saturation) : $lightness + $saturation - $lightness * $saturation; - $p = 2 * $lightness - $q; - - return array_map(function ($color) use ($q, $p) { - if ($color < 0) { - $color++; - } - - if ($color > 1) { - $color--; - } - - if ($color < 1/6) { - $color = $p + ($q - $p) * 6 * $color; - } else if ($color < 0.5) { - $color = $q; - } else if ($color < 2/3) { - $color = $p + ($q - $p) * 6 * (2/3 - $color); - } else { - $color = $p; - } - - return round($color * 255); - }, array($hue + 1/3, $hue, $hue - 1/3)); - } - - /** - * Returns the hash in [h, s, l]. - * Note that H ∈ [0, 360); S ∈ [0, 1]; L ∈ [0, 1]; - * - * @access protected - * @param string $str - * @return int[] - */ - protected function getHSL($str) - { - $hash = $this->hash($str); - $hue = $hash % 359; - - $hash = intval($hash / 360); - $saturation = $this->saturation[$hash % count($this->saturation)]; - - $hash = intval($hash / count($this->saturation)); - $lightness = $this->lightness[$hash % count($this->lightness)]; - - return array($hue, $saturation, $lightness); - } - - /** - * BKDR Hash (modified version) - * - * @access protected - * @param string $str - * @return integer - */ - protected function hash($str) - { - $seed = 131; - $seed2 = 137; - $hash = 0; - - // Make hash more sensitive for short string like 'a', 'b', 'c' - $str .= 'x'; - $max = intval(PHP_INT_MAX / $seed2); - - for ($i = 0, $ilen = mb_strlen($str, 'UTF-8'); $i < $ilen; $i++) { - if ($hash > $max) { - $hash = intval($hash / $seed2); - } - - $hash = $hash * $seed + $this->getCharCode(mb_substr($str, $i, 1, 'UTF-8')); - } - - return $hash; - } - - /** - * Backport of Javascript function charCodeAt() - * - * @access protected - * @param string $c - * @return integer - */ - protected function getCharCode($c) - { - list(, $ord) = unpack('N', mb_convert_encoding($c, 'UCS-4BE', 'UTF-8')); - return $ord; - } -} diff --git a/sources/app/User/DatabaseUserProvider.php b/sources/app/User/DatabaseUserProvider.php deleted file mode 100644 index fc62661..0000000 --- a/sources/app/User/DatabaseUserProvider.php +++ /dev/null @@ -1,143 +0,0 @@ -user = $user; - } - - /** - * Return true to allow automatic user creation - * - * @access public - * @return boolean - */ - public function isUserCreationAllowed() - { - return false; - } - - /** - * Get internal id - * - * @access public - * @return string - */ - public function getInternalId() - { - return $this->user['id']; - } - - /** - * Get external id column name - * - * @access public - * @return string - */ - public function getExternalIdColumn() - { - return ''; - } - - /** - * Get external id - * - * @access public - * @return string - */ - public function getExternalId() - { - return ''; - } - - /** - * Get user role - * - * @access public - * @return string - */ - public function getRole() - { - return ''; - } - - /** - * Get username - * - * @access public - * @return string - */ - public function getUsername() - { - return ''; - } - - /** - * Get full name - * - * @access public - * @return string - */ - public function getName() - { - return ''; - } - - /** - * Get user email - * - * @access public - * @return string - */ - public function getEmail() - { - return ''; - } - - /** - * Get external group ids - * - * @access public - * @return array - */ - public function getExternalGroupIds() - { - return array(); - } - - /** - * Get extra user attributes - * - * @access public - * @return array - */ - public function getExtraAttributes() - { - return array(); - } -} diff --git a/sources/app/User/LdapUserProvider.php b/sources/app/User/LdapUserProvider.php deleted file mode 100644 index 8ea8976..0000000 --- a/sources/app/User/LdapUserProvider.php +++ /dev/null @@ -1,242 +0,0 @@ -dn = $dn; - $this->username = $username; - $this->name = $name; - $this->email = $email; - $this->role = $role; - $this->groupIds = $groupIds; - $this->photo = $photo; - $this->language = $language; - } - - /** - * Return true to allow automatic user creation - * - * @access public - * @return boolean - */ - public function isUserCreationAllowed() - { - return LDAP_USER_CREATION; - } - - /** - * Get internal id - * - * @access public - * @return string - */ - public function getInternalId() - { - return ''; - } - - /** - * Get external id column name - * - * @access public - * @return string - */ - public function getExternalIdColumn() - { - return 'username'; - } - - /** - * Get external id - * - * @access public - * @return string - */ - public function getExternalId() - { - return $this->getUsername(); - } - - /** - * Get user role - * - * @access public - * @return string - */ - public function getRole() - { - return $this->role; - } - - /** - * Get username - * - * @access public - * @return string - */ - public function getUsername() - { - return LDAP_USERNAME_CASE_SENSITIVE ? $this->username : strtolower($this->username); - } - - /** - * Get full name - * - * @access public - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get user email - * - * @access public - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * Get groups DN - * - * @access public - * @return string[] - */ - public function getExternalGroupIds() - { - return $this->groupIds; - } - - /** - * Get extra user attributes - * - * @access public - * @return array - */ - public function getExtraAttributes() - { - $attributes = array('is_ldap_user' => 1); - - if (! empty($this->language)) { - $attributes['language'] = LanguageModel::findCode($this->language); - } - - return $attributes; - } - - /** - * Get User DN - * - * @access public - * @return string - */ - public function getDn() - { - return $this->dn; - } - - /** - * Get user photo - * - * @access public - * @return string - */ - public function getPhoto() - { - return $this->photo; - } -} diff --git a/sources/app/User/OAuthUserProvider.php b/sources/app/User/OAuthUserProvider.php deleted file mode 100644 index dec2625..0000000 --- a/sources/app/User/OAuthUserProvider.php +++ /dev/null @@ -1,140 +0,0 @@ -user = $user; - } - - /** - * Return true to allow automatic user creation - * - * @access public - * @return boolean - */ - public function isUserCreationAllowed() - { - return false; - } - - /** - * Get internal id - * - * @access public - * @return string - */ - public function getInternalId() - { - return ''; - } - - /** - * Get external id - * - * @access public - * @return string - */ - public function getExternalId() - { - return $this->user['id']; - } - - /** - * Get user role - * - * @access public - * @return string - */ - public function getRole() - { - return ''; - } - - /** - * Get username - * - * @access public - * @return string - */ - public function getUsername() - { - return ''; - } - - /** - * Get full name - * - * @access public - * @return string - */ - public function getName() - { - return $this->user['name']; - } - - /** - * Get user email - * - * @access public - * @return string - */ - public function getEmail() - { - return $this->user['email']; - } - - /** - * Get external group ids - * - * @access public - * @return array - */ - public function getExternalGroupIds() - { - return array(); - } - - /** - * Get extra user attributes - * - * @access public - * @return array - */ - public function getExtraAttributes() - { - return array(); - } -} diff --git a/sources/app/User/ReverseProxyUserProvider.php b/sources/app/User/ReverseProxyUserProvider.php deleted file mode 100644 index 34d2187..0000000 --- a/sources/app/User/ReverseProxyUserProvider.php +++ /dev/null @@ -1,164 +0,0 @@ -username = $username; - $this->userProfile = $userProfile; - } - - /** - * Return true to allow automatic user creation - * - * @access public - * @return boolean - */ - public function isUserCreationAllowed() - { - return true; - } - - /** - * Get internal id - * - * @access public - * @return string - */ - public function getInternalId() - { - return ''; - } - - /** - * Get external id column name - * - * @access public - * @return string - */ - public function getExternalIdColumn() - { - return 'username'; - } - - /** - * Get external id - * - * @access public - * @return string - */ - public function getExternalId() - { - return $this->username; - } - - /** - * Get user role - * - * @access public - * @return string - */ - public function getRole() - { - if (REVERSE_PROXY_DEFAULT_ADMIN === $this->username) { - return Role::APP_ADMIN; - } - - if (isset($this->userProfile['role'])) { - return $this->userProfile['role']; - } - - return Role::APP_USER; - } - - /** - * Get username - * - * @access public - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Get full name - * - * @access public - * @return string - */ - public function getName() - { - return ''; - } - - /** - * Get user email - * - * @access public - * @return string - */ - public function getEmail() - { - return REVERSE_PROXY_DEFAULT_DOMAIN !== '' ? $this->username.'@'.REVERSE_PROXY_DEFAULT_DOMAIN : ''; - } - - /** - * Get external group ids - * - * @access public - * @return array - */ - public function getExternalGroupIds() - { - return array(); - } - - /** - * Get extra user attributes - * - * @access public - * @return array - */ - public function getExtraAttributes() - { - return array( - 'is_ldap_user' => 1, - 'disable_login_form' => 1, - ); - } -} diff --git a/sources/app/Validator/ActionValidator.php b/sources/app/Validator/ActionValidator.php deleted file mode 100644 index 4ce5db4..0000000 --- a/sources/app/Validator/ActionValidator.php +++ /dev/null @@ -1,38 +0,0 @@ -execute(), - $v->getErrors() - ); - } -} diff --git a/sources/app/Validator/AuthValidator.php b/sources/app/Validator/AuthValidator.php deleted file mode 100644 index 03ff6f2..0000000 --- a/sources/app/Validator/AuthValidator.php +++ /dev/null @@ -1,119 +0,0 @@ -executeValidators(array('validateFields', 'validateLocking', 'validateCaptcha', 'validateCredentials'), $values); - } - - /** - * Validate credentials syntax - * - * @access protected - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - protected function validateFields(array $values) - { - $v = new Validator($values, array( - new Validators\Required('username', t('The username is required')), - new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50), - new Validators\Required('password', t('The password is required')), - )); - - return array( - $v->execute(), - $v->getErrors(), - ); - } - - /** - * Validate user locking - * - * @access protected - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - protected function validateLocking(array $values) - { - $result = true; - $errors = array(); - - if ($this->userLockingModel->isLocked($values['username'])) { - $result = false; - $errors['login'] = t('Your account is locked for %d minutes', BRUTEFORCE_LOCKDOWN_DURATION); - $this->logger->error('Account locked: '.$values['username']); - } - - return array($result, $errors); - } - - /** - * Validate password syntax - * - * @access protected - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - protected function validateCredentials(array $values) - { - $result = true; - $errors = array(); - - if (! $this->authenticationManager->passwordAuthentication($values['username'], $values['password'])) { - $result = false; - $errors['login'] = t('Bad username or password'); - } - - return array($result, $errors); - } - - /** - * Validate captcha - * - * @access protected - * @param array $values Form values - * @return boolean - */ - protected function validateCaptcha(array $values) - { - $result = true; - $errors = array(); - - if ($this->userLockingModel->hasCaptcha($values['username'])) { - if (! isset($this->sessionStorage->captcha)) { - $result = false; - } else { - $builder = new CaptchaBuilder; - $builder->setPhrase($this->sessionStorage->captcha); - $result = $builder->testPhrase(isset($values['captcha']) ? $values['captcha'] : ''); - - if (! $result) { - $errors['login'] = t('Invalid captcha'); - } - } - } - - return array($result, $errors); - } -} diff --git a/sources/app/Validator/BaseValidator.php b/sources/app/Validator/BaseValidator.php deleted file mode 100644 index 6088538..0000000 --- a/sources/app/Validator/BaseValidator.php +++ /dev/null @@ -1,55 +0,0 @@ -$method($values); - - if (! $result) { - break; - } - } - - return array($result, $errors); - } - - /** - * Common password validation rules - * - * @access protected - * @return array - */ - protected function commonPasswordValidationRules() - { - return array( - new Validators\Required('password', t('The password is required')), - new Validators\MinLength('password', t('The minimum length is %d characters', 6), 6), - new Validators\Required('confirmation', t('The confirmation is required')), - new Validators\Equals('password', 'confirmation', t('Passwords don\'t match')), - ); - } -} diff --git a/sources/app/Validator/CategoryValidator.php b/sources/app/Validator/CategoryValidator.php deleted file mode 100644 index fc42d2e..0000000 --- a/sources/app/Validator/CategoryValidator.php +++ /dev/null @@ -1,74 +0,0 @@ -commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate category modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - new Validators\Required('name', t('The name is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Integer('id', t('The id must be an integer')), - new Validators\Integer('project_id', t('The project id must be an integer')), - new Validators\MaxLength('name', t('The maximum length is %d characters', 50), 50) - ); - } -} diff --git a/sources/app/Validator/ColumnValidator.php b/sources/app/Validator/ColumnValidator.php deleted file mode 100644 index 25aa45d..0000000 --- a/sources/app/Validator/ColumnValidator.php +++ /dev/null @@ -1,75 +0,0 @@ -commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate column creation - * - * @access public - * @param array $values Required parameters to save an action - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $rules = array( - new Validators\Required('project_id', t('The project id is required')), - new Validators\Integer('project_id', t('This value must be an integer')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Integer('task_limit', t('This value must be an integer')), - new Validators\GreaterThan('task_limit', t('This value must be greater than %d', -1), -1), - new Validators\Required('title', t('The title is required')), - new Validators\MaxLength('title', t('The maximum length is %d characters', 50), 50), - ); - } -} diff --git a/sources/app/Validator/CommentValidator.php b/sources/app/Validator/CommentValidator.php deleted file mode 100644 index fc8e6da..0000000 --- a/sources/app/Validator/CommentValidator.php +++ /dev/null @@ -1,74 +0,0 @@ -commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate comment modification - * - * @access public - * @param array $values Required parameters to save an action - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('This value is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Integer('id', t('This value must be an integer')), - new Validators\Integer('task_id', t('This value must be an integer')), - new Validators\Integer('user_id', t('This value must be an integer')), - new Validators\MaxLength('reference', t('The maximum length is %d characters', 50), 50), - new Validators\Required('comment', t('Comment is required')) - ); - } -} diff --git a/sources/app/Validator/CurrencyValidator.php b/sources/app/Validator/CurrencyValidator.php deleted file mode 100644 index 4f375c5..0000000 --- a/sources/app/Validator/CurrencyValidator.php +++ /dev/null @@ -1,36 +0,0 @@ -execute(), - $v->getErrors() - ); - } -} diff --git a/sources/app/Validator/CustomFilterValidator.php b/sources/app/Validator/CustomFilterValidator.php deleted file mode 100644 index 1ab9303..0000000 --- a/sources/app/Validator/CustomFilterValidator.php +++ /dev/null @@ -1,74 +0,0 @@ -commonValidationRules()); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate filter modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('Field required')), - new Validators\Integer('id', t('This value must be an integer')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } -} diff --git a/sources/app/Validator/ExternalLinkValidator.php b/sources/app/Validator/ExternalLinkValidator.php deleted file mode 100644 index 9c01770..0000000 --- a/sources/app/Validator/ExternalLinkValidator.php +++ /dev/null @@ -1,76 +0,0 @@ -commonValidationRules()); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Required('url', t('Field required')), - new Validators\MaxLength('url', t('The maximum length is %d characters', 255), 255), - new Validators\Required('title', t('Field required')), - new Validators\MaxLength('title', t('The maximum length is %d characters', 255), 255), - new Validators\Required('link_type', t('Field required')), - new Validators\MaxLength('link_type', t('The maximum length is %d characters', 100), 100), - new Validators\Required('dependency', t('Field required')), - new Validators\MaxLength('dependency', t('The maximum length is %d characters', 100), 100), - new Validators\Integer('id', t('This value must be an integer')), - new Validators\Required('task_id', t('Field required')), - new Validators\Integer('task_id', t('This value must be an integer')), - ); - } -} diff --git a/sources/app/Validator/GroupValidator.php b/sources/app/Validator/GroupValidator.php deleted file mode 100644 index 8b21c69..0000000 --- a/sources/app/Validator/GroupValidator.php +++ /dev/null @@ -1,71 +0,0 @@ -commonValidationRules()); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Required('name', t('The name is required')), - new Validators\MaxLength('name', t('The maximum length is %d characters', 100), 100), - new Validators\Unique('name', t('The name must be unique'), $this->db->getConnection(), GroupModel::TABLE, 'id'), - new Validators\MaxLength('external_id', t('The maximum length is %d characters', 255), 255), - new Validators\Integer('id', t('This value must be an integer')), - ); - } -} diff --git a/sources/app/Validator/LinkValidator.php b/sources/app/Validator/LinkValidator.php deleted file mode 100644 index 8e1c878..0000000 --- a/sources/app/Validator/LinkValidator.php +++ /dev/null @@ -1,59 +0,0 @@ -db->getConnection(), LinkModel::TABLE), - new Validators\NotEquals('label', 'opposite_label', t('The labels must be different')), - )); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $v = new Validator($values, array( - new Validators\Required('id', t('Field required')), - new Validators\Required('opposite_id', t('Field required')), - new Validators\Required('label', t('Field required')), - new Validators\Unique('label', t('This label must be unique'), $this->db->getConnection(), LinkModel::TABLE), - )); - - return array( - $v->execute(), - $v->getErrors() - ); - } -} diff --git a/sources/app/Validator/PasswordResetValidator.php b/sources/app/Validator/PasswordResetValidator.php deleted file mode 100644 index e44e520..0000000 --- a/sources/app/Validator/PasswordResetValidator.php +++ /dev/null @@ -1,92 +0,0 @@ -executeValidators(array('validateFields', 'validateCaptcha'), $values); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $v = new Validator($values, $this->commonPasswordValidationRules()); - - return array( - $v->execute(), - $v->getErrors(), - ); - } - - /** - * Validate fields - * - * @access protected - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - protected function validateFields(array $values) - { - $v = new Validator($values, array( - new Validators\Required('captcha', t('This value is required')), - new Validators\Required('username', t('The username is required')), - new Validators\MaxLength('username', t('The maximum length is %d characters', 50), 50), - )); - - return array( - $v->execute(), - $v->getErrors(), - ); - } - - /** - * Validate captcha - * - * @access protected - * @param array $values Form values - * @return boolean - */ - protected function validateCaptcha(array $values) - { - $errors = array(); - - if (! isset($this->sessionStorage->captcha)) { - $result = false; - } else { - $builder = new CaptchaBuilder; - $builder->setPhrase($this->sessionStorage->captcha); - $result = $builder->testPhrase(isset($values['captcha']) ? $values['captcha'] : ''); - - if (! $result) { - $errors['captcha'] = array(t('Invalid captcha')); - } - } - - return array($result, $errors); - } -} diff --git a/sources/app/Validator/ProjectValidator.php b/sources/app/Validator/ProjectValidator.php deleted file mode 100644 index 8c6117a..0000000 --- a/sources/app/Validator/ProjectValidator.php +++ /dev/null @@ -1,90 +0,0 @@ -db->getConnection(), ProjectModel::TABLE), - ); - } - - /** - * Validate project creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - 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)); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate project modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - if (! empty($values['identifier'])) { - $values['identifier'] = strtoupper($values['identifier']); - } - - $rules = array( - new Validators\Required('id', t('This value is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } -} diff --git a/sources/app/Validator/SubtaskValidator.php b/sources/app/Validator/SubtaskValidator.php deleted file mode 100644 index b80de41..0000000 --- a/sources/app/Validator/SubtaskValidator.php +++ /dev/null @@ -1,101 +0,0 @@ -commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The subtask id is required')), - new Validators\Required('task_id', t('The task id is required')), - new Validators\Required('title', t('The title is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate API modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateApiModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The subtask id is required')), - new Validators\Required('task_id', t('The task id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Integer('id', t('The subtask id must be an integer')), - new Validators\Integer('task_id', t('The task id must be an integer')), - new Validators\MaxLength('title', t('The maximum length is %d characters', 255), 255), - new Validators\Integer('user_id', t('The user id must be an integer')), - new Validators\Integer('status', t('The status must be an integer')), - new Validators\Numeric('time_estimated', t('The time must be a numeric value')), - new Validators\Numeric('time_spent', t('The time must be a numeric value')), - ); - } -} diff --git a/sources/app/Validator/SwimlaneValidator.php b/sources/app/Validator/SwimlaneValidator.php deleted file mode 100644 index 16f8bfb..0000000 --- a/sources/app/Validator/SwimlaneValidator.php +++ /dev/null @@ -1,96 +0,0 @@ -commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - new Validators\Required('name', t('The name is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate default swimlane modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateDefaultModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - new Validators\Required('default_swimlane', t('The name is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Common validation rules - * - * @access private - * @return array - */ - private function commonValidationRules() - { - return array( - new Validators\Integer('id', t('The id must be an integer')), - new Validators\Integer('project_id', t('The project id must be an integer')), - new Validators\MaxLength('name', t('The maximum length is %d characters', 50), 50) - ); - } -} diff --git a/sources/app/Validator/TagValidator.php b/sources/app/Validator/TagValidator.php deleted file mode 100644 index 0567cf3..0000000 --- a/sources/app/Validator/TagValidator.php +++ /dev/null @@ -1,76 +0,0 @@ -commonValidationRules()); - $result = $v->execute(); - $errors = $v->getErrors(); - - if ($result && $this->tagModel->exists($values['project_id'], $values['name'])) { - $result = false; - $errors = array('name' => array(t('The name must be unique'))); - } - - return array($result, $errors); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('Field required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - $result = $v->execute(); - $errors = $v->getErrors(); - - if ($result && $this->tagModel->exists($values['project_id'], $values['name'], $values['id'])) { - $result = false; - $errors = array('name' => array(t('The name must be unique'))); - } - - return array($result, $errors); - } - - /** - * Common validation rules - * - * @access protected - * @return array - */ - protected function commonValidationRules() - { - return array( - new Validators\Required('project_id', t('Field required')), - new Validators\Required('name', t('Field required')), - new Validators\MaxLength('name', t('The maximum length is %d characters', 255), 255), - ); - } -} diff --git a/sources/app/Validator/TaskLinkValidator.php b/sources/app/Validator/TaskLinkValidator.php deleted file mode 100644 index 6da257b..0000000 --- a/sources/app/Validator/TaskLinkValidator.php +++ /dev/null @@ -1,71 +0,0 @@ -db->getConnection(), TaskModel::TABLE, 'id') - ); - } - - /** - * Validate creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $v = new Validator($values, $this->commonValidationRules()); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('Field required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } -} diff --git a/sources/app/Validator/TaskValidator.php b/sources/app/Validator/TaskValidator.php deleted file mode 100644 index 8aa5c44..0000000 --- a/sources/app/Validator/TaskValidator.php +++ /dev/null @@ -1,226 +0,0 @@ -dateParser->getParserFormats()), - new Validators\Date('date_started', t('Invalid date'), $this->dateParser->getParserFormats()), - new Validators\Numeric('time_spent', t('This value must be numeric')), - new Validators\Numeric('time_estimated', t('This value must be numeric')), - ); - } - - /** - * Validate task creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $rules = array( - new Validators\Required('project_id', t('The project is required')), - new Validators\Required('title', t('The title is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate task creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateBulkCreation(array $values) - { - $rules = array( - new Validators\Required('project_id', t('The project is required')), - new Validators\Required('tasks', t('Field required')), - new Validators\Required('column_id', t('Field required')), - new Validators\Required('swimlane_id', t('Field required')), - new Validators\Integer('category_id', t('This value must be an integer')), - new Validators\Integer('swimlane_id', t('This value must be an integer')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate description creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateDescriptionCreation(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate edit recurrence - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateEditRecurrence(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - - /** - * Validate task modification (form) - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - new Validators\Required('title', t('The title is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate task modification (Api) - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateApiModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate project modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateProjectModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - new Validators\Required('project_id', t('The project is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate time tracking modification (form) - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateTimeModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } -} diff --git a/sources/app/Validator/UserValidator.php b/sources/app/Validator/UserValidator.php deleted file mode 100644 index 9911de5..0000000 --- a/sources/app/Validator/UserValidator.php +++ /dev/null @@ -1,128 +0,0 @@ -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')), - ); - } - - /** - * Validate user creation - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateCreation(array $values) - { - $rules = array( - new Validators\Required('username', t('The username is required')), - ); - - if (isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1) { - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - } else { - $v = new Validator($values, array_merge($rules, $this->commonValidationRules(), $this->commonPasswordValidationRules())); - } - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate user modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The user id is required')), - new Validators\Required('username', t('The username is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate user API modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validateApiModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The user id is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonValidationRules())); - - return array( - $v->execute(), - $v->getErrors() - ); - } - - /** - * Validate password modification - * - * @access public - * @param array $values Form values - * @return array $valid, $errors [0] = Success or not, [1] = List of errors - */ - public function validatePasswordModification(array $values) - { - $rules = array( - new Validators\Required('id', t('The user id is required')), - new Validators\Required('current_password', t('The current password is required')), - ); - - $v = new Validator($values, array_merge($rules, $this->commonPasswordValidationRules())); - - if ($v->execute()) { - if ($this->authenticationManager->passwordAuthentication($this->userSession->getUsername(), $values['current_password'], false)) { - return array(true, array()); - } else { - return array(false, array('current_password' => array(t('Wrong password')))); - } - } - - return array(false, $v->getErrors()); - } -} diff --git a/sources/app/check_setup.php b/sources/app/check_setup.php deleted file mode 100644 index d962a6f..0000000 --- a/sources/app/check_setup.php +++ /dev/null @@ -1,45 +0,0 @@ -isEnvironmentVariableDefined()) { - $dbSettings = $dbUrlParser->getSettings(); - - define('DB_DRIVER', $dbSettings['driver']); - define('DB_USERNAME', $dbSettings['username']); - define('DB_PASSWORD', $dbSettings['password']); - define('DB_HOSTNAME', $dbSettings['hostname']); - define('DB_PORT', $dbSettings['port']); - define('DB_NAME', $dbSettings['database']); -} - -$config_file = implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'config.php')); - -if (file_exists($config_file)) { - require $config_file; -} - -$config_file = implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'data', 'config.php')); - -if (file_exists($config_file)) { - require $config_file; -} - -require __DIR__.'/constants.php'; -require __DIR__.'/check_setup.php'; - -$container = new Pimple\Container; -$container->register(new Kanboard\ServiceProvider\MailProvider()); -$container->register(new Kanboard\ServiceProvider\HelperProvider()); -$container->register(new Kanboard\ServiceProvider\SessionProvider()); -$container->register(new Kanboard\ServiceProvider\LoggingProvider()); -$container->register(new Kanboard\ServiceProvider\DatabaseProvider()); -$container->register(new Kanboard\ServiceProvider\AuthenticationProvider()); -$container->register(new Kanboard\ServiceProvider\NotificationProvider()); -$container->register(new Kanboard\ServiceProvider\ClassProvider()); -$container->register(new Kanboard\ServiceProvider\EventDispatcherProvider()); -$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\AvatarProvider()); -$container->register(new Kanboard\ServiceProvider\FilterProvider()); -$container->register(new Kanboard\ServiceProvider\QueueProvider()); -$container->register(new Kanboard\ServiceProvider\ApiProvider()); -$container->register(new Kanboard\ServiceProvider\CommandProvider()); -$container->register(new Kanboard\ServiceProvider\PluginProvider()); diff --git a/sources/app/constants.php b/sources/app/constants.php deleted file mode 100644 index 47e8689..0000000 --- a/sources/app/constants.php +++ /dev/null @@ -1,136 +0,0 @@ - 1, 'k2' => 2], ['k1' => 3, 'k2' => 4], ['k1' => 2, 'k2' => 5] - * ] - * - * array_column_index($input, 'k1') will returns: - * - * [ - * 1 => [['k1' => 1, 'k2' => 2], ['k1' => 2, 'k2' => 5]], - * 3 => [['k1' => 3, 'k2' => 4]], - * ] - * - * @param array $input - * @param string $column - * @return array - */ -function array_column_index(array &$input, $column) -{ - $result = array(); - - foreach ($input as &$row) { - if (isset($row[$column])) { - $result[$row[$column]][] = $row; - } - } - - return $result; -} - -/** - * Sum all values from a single column in the input array - * - * $input = [ - * ['column' => 2], ['column' => 3] - * ] - * - * array_column_sum($input, 'column') returns 5 - * - * @param array $input - * @param string $column - * @return double - */ -function array_column_sum(array &$input, $column) -{ - $sum = 0.0; - - foreach ($input as &$row) { - if (isset($row[$column])) { - $sum += (float) $row[$column]; - } - } - - return $sum; -} - -/** - * Build version number from git-archive output - * - * @param string $ref - * @param string $commit_hash - * @return string - */ -function build_app_version($ref, $commit_hash) -{ - $version = 'master'; - - if ($ref !== '$Format:%d$') { - $tag = preg_replace('/\s*\(.*tag:\sv([^,]+).*\)/i', '\1', $ref); - - if (!is_null($tag) && $tag !== $ref) { - return $tag; - } - } - - if ($commit_hash !== '$Format:%H$') { - $version .= '.'.$commit_hash; - } - - return $version; -} - -/** - * Translate a string - * - * @return string - */ -function t() -{ - return call_user_func_array(array(Translator::getInstance(), 'translate'), func_get_args()); -} - -/** - * Translate a string with no HTML escaping - * - * @return string - */ -function e() -{ - return call_user_func_array(array(Translator::getInstance(), 'translateNoEscaping'), func_get_args()); -} - -/** - * Translate a number - * - * @param mixed $value - * @return string - */ -function n($value) -{ - return Translator::getInstance()->number($value); -} diff --git a/sources/assets/css/app.min.css b/sources/assets/css/app.min.css deleted file mode 100644 index 88acd0a..0000000 --- a/sources/assets/css/app.min.css +++ /dev/null @@ -1 +0,0 @@ -a:focus,a:hover,th a{text-decoration:none}h3,label{margin-top:10px}.tooltip-arrow.bottom:after,.tooltip-arrow.top{top:-10px}.form-errors,.ui-tooltip li,ul.no-bullet li{list-style-type:none}.table-fixed td,.table-fixed th,.tooltip-arrow,header h1{overflow:hidden}#board td,td{vertical-align:top}.table-fixed td,.task-board-collapsed,div.ganttview-vtheader-series-name,header h1{text-overflow:ellipsis;white-space:nowrap}blockquote,body,li,ol,p,table,td,th,tr,ul{margin:0;padding:0;font-size:100%}form,table{margin-bottom:20px}body{margin-left:10px;margin-right:10px;padding-bottom:10px;color:#333;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;text-rendering:optimizeLegibility}.page{clear:both}ul.no-bullet li{margin-left:0}.pull-right{text-align:right}hr{border:0;height:0;border-top:1px solid rgba(0,0,0,.1);border-bottom:1px solid rgba(255,255,255,.3)}.chosen-select{min-height:27px}#ui-datepicker-div{font-size:.8em}#app-loading-icon{position:fixed;right:3px;bottom:3px}.web-notification-icon{color:#36C}.web-notification-icon:focus,.web-notification-icon:hover{color:#000}a:hover,h1,h2,h3,th a{color:#333}.smaller{font-size:.85em}a{color:#36C;border:none}a:focus{outline:0;color:#DF5353;border:1px dotted #aaa}h1,h2,h3{font-weight:400}h2{font-size:1.3em;margin-bottom:10px}h3{font-size:1.2em}table{width:100%;border-collapse:collapse;border-spacing:0;font-size:.95em}#calendar table{margin-bottom:0}td,th{border:1px solid #eee;padding:.5em 3px}th{background:#fbfbfb;text-align:left}td li{margin-left:20px}.table-small{font-size:.8em}th a:focus,th a:hover{text-decoration:underline}.page-header h2 a,a.btn,header a{text-decoration:none}.table-fixed{table-layout:fixed;white-space:nowrap}.table-stripped tr:nth-child(odd){background:#fefefe}.column-3{width:3%}.column-5{width:5%}.column-8{width:7.5%}.column-10{width:10%}.column-12{width:12%}.column-15{width:15%}.column-18{width:18%}.column-20{width:20%}.column-25{width:25%}.column-30{width:30%}.column-35{width:35%}.column-40{width:40%}.column-50{width:50%}.column-60{width:60%}.column-70,.column-80{width:70%}.draggable-row-handle{cursor:move;color:#dedede}.btn,.draggable-item,.task-board-change-assignee,label{cursor:pointer}.draggable-row-handle:hover{color:#333}tr.draggable-item-selected{background:#fff;border:2px solid #666;box-shadow:4px 2px 10px -4px rgba(0,0,0,.55)}tr.draggable-item-selected td{border-top:none;border-bottom:none}tr.draggable-item-selected td:first-child{border-left:none}tr.draggable-item-selected td:last-child{border-right:none}.table-stripped tr.draggable-item-hover,tr.draggable-item-hover{background:#FEFFF2}label{display:block}input[type=number],input[type=date],input[type=email],input[type=password],input[type=text]{color:#888;border:1px solid #ccc;width:300px;max-width:95%;font-size:100%;height:25px;padding-bottom:0;font-family:sans-serif;margin-top:10px;-webkit-appearance:none;appearance:none}input[type=number]:focus,input[type=date]:focus,input[type=email]:focus,input[type=password]:focus,input[type=text]:focus,textarea:focus{color:#000;border-color:rgba(82,168,236,.8);outline:0;box-shadow:0 0 8px rgba(82,168,236,.6)}input.form-numeric,input[type=number]{width:70px}.tag-autocomplete,textarea{width:400px}textarea{border:1px solid #ccc;max-width:99%;height:200px;font-size:100%;font-family:sans-serif}select{max-width:95%}select:focus{outline:0}span.select2-container{margin-top:2px}::-webkit-input-placeholder{color:#ddd;padding-top:2px}::-ms-input-placeholder{color:#ddd;padding-top:2px}::-moz-placeholder{color:#ddd;padding-top:2px}.form-actions{padding-top:20px;clear:both}input.form-error,textarea.form-error{border:2px solid #b94a48}input.form-error:focus,textarea.form-error:focus{box-shadow:none;border:2px solid #b94a48}.form-required{color:red;padding-left:5px;font-weight:700}.form-errors{color:#b94a48}ul.form-errors li{margin-left:0}.form-help{font-size:.8em;color:brown;margin-bottom:15px}.form-inline{padding:0;margin:0;border:none}.form-inline label{display:inline}.form-inline input,.form-inline select{margin:0 15px 0 0}.form-inline .form-required{display:none}.form-inline-group{display:inline}input.form-date,input.form-datetime{width:150px}input.form-input-large{width:400px}input.form-input-small{width:150px}.form-columns{display:-webkit-flex;display:flex;-webkit-flex-direction:row;flex-direction:row}.form-column{margin-right:25px}.form-login{width:350px;margin:8% auto 0}.form-login li{margin-left:25px;line-height:25px}.form-login h2{margin-bottom:30px;font-size:1.5em;font-weight:700}.popover-form{margin-bottom:0}.reset-password{margin-top:20px}.reset-password a{font-size:.8em;color:#999}.btn{font-size:1.1em;font-weight:400;-webkit-appearance:none;appearance:none;display:inline-block;color:#333;background:#f5f5f5;border:1px solid #ddd;border-radius:2px;padding:3px 10px;margin:0}.btn:hover{border:1px solid #bbb;color:#000;background:#fafafa}.btn-red{border-color:#b0281a;background:#d14836;color:#fff}.btn-red:focus,.btn-red:hover{color:#fff;background:#c53727}.btn-blue{border-color:#3079ed;background:#4d90fe;color:#fff}.btn-blue:focus,.btn-blue:hover{border-color:#2f5bb7;background:#357ae8;color:#fff}.btn:disabled{color:#ccc;border:1px solid #ccc;background:#f7f7f7}.buttons-header{font-size:.9em;margin-bottom:15px}.alert{padding:8px 35px 8px 14px;margin-top:5px;margin-bottom:5px;color:#c09853;background-color:#fcf8e3;border:1px solid #fbeed5;border-radius:4px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-normal{color:#333;background-color:#f0f0f0;border-color:#ddd}.alert ul{margin-top:10px;margin-bottom:10px}.alert-fade-out,.ui-tooltip-content .markdown p{margin-bottom:0}.alert li{margin-left:25px}.alert-fade-out{text-align:center;position:fixed;bottom:0;left:20%;width:60%;padding-top:5px;padding-bottom:5px;border-width:1px 0 0;border-radius:4px 4px 0 0;z-index:9999}.tooltip-arrow.bottom,.tooltip-arrow.top:after{bottom:-10px}div.ui-tooltip{min-width:200px;max-width:600px;font-size:.85em}.tooltip-arrow{width:20px;height:10px;position:absolute}.tooltip-arrow.align-left{left:10px}.tooltip-arrow.align-right{right:10px}.tooltip-arrow:after{background:#fff;border:1px solid #aaa;box-shadow:0 0 5px #aaa;content:"";position:absolute;width:14px;height:14px;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.textarea-dropdown,ul.dropdown-submenu-open{list-style:none;box-shadow:0 1px 3px rgba(0,0,0,.15)}.tooltip-arrow.align-left:after{left:0}.tooltip-arrow.align-right:after{right:0}.tooltip-large{width:600px}.tooltip .fa-info-circle{color:#999;font-size:.95em}header{margin-top:10px;padding-bottom:10px;border-bottom:1px solid #dedede}header h1{margin:0;padding:0;max-width:70%;float:left}header ul{text-align:right;font-size:.9em}header li{display:inline;padding-left:30px}header a{color:#333}header a:hover{color:#666}nav .active a{color:#333;font-weight:700}.logo a{opacity:.5;color:#d40000}.logo span{color:#333}.logo a:hover{opacity:.8;color:#333}.logo a:focus span,.logo a:hover span{color:#d40000}header .user-links .dropdown{margin-left:15px}header h1 .tooltip{opacity:.3;font-size:.6em}.page-header{margin-bottom:20px}.page-header h2{margin:0;padding:0;font-size:1.4em;font-weight:700;border-bottom:1px dotted #ccc}.page-header h2 a{color:#333}.page-header h2 a:focus,.page-header h2 a:hover{color:#aaa}.page-header ul{text-align:left;margin-top:5px;display:inline-block}.menu-inline li,.page-header li{display:inline;padding-right:15px;font-size:.95em}.page-header li.active a{color:#333;text-decoration:none;font-weight:700}.page-header li.active a:focus,.page-header li.active a:hover{text-decoration:underline}.menu-inline{margin-bottom:5px}.public-board{margin-top:5px}.public-task{max-width:800px;margin:5px auto 0}#board-container{overflow-x:auto}#board{table-layout:fixed;margin-bottom:0}#board th.board-column-header{width:240px}.board-container-compact{overflow-x:initial}@media all and (-ms-high-contrast:active),(-ms-high-contrast:none){.board-container-compact #board{table-layout:auto}}#board th.board-column-header.board-column-compact{width:initial}.board-column-collapsed{display:none}td.board-column-task-collapsed{font-weight:700;background-color:#fbfbfb}#board th.board-column-header-collapsed{width:28px;min-width:28px;text-align:center;overflow:hidden}.board-rotation-wrapper{position:relative;padding:8px 4px;min-height:150px;overflow:hidden}.board-rotation{white-space:nowrap;-webkit-backface-visibility:hidden;-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:0 100%;-moz-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%}.board-column-title .dropdown-menu{text-decoration:none}.board-add-icon{float:left;padding:0 5px}.board-add-icon a{text-decoration:none;color:#36C;font-size:150%;line-height:70%}.board-add-icon a:focus,.board-add-icon a:hover{text-decoration:none;color:red}.board-column-header-task-count{color:#999;font-weight:400}th.board-column-header-collapsed .board-column-header-task-count{font-size:.85em}a.board-swimlane-toggle{font-size:.95em;text-decoration:none}a.board-swimlane-toggle:focus,a.board-swimlane-toggle:hover{color:#000;text-decoration:none;border:none}.board-task-list{overflow:auto;min-height:60px}.board-task-list-limit{background-color:#DF5353}.draggable-item{user-select:none;-webkit-user-select:none;-moz-user-select:none}.draggable-placeholder{border:2px dashed #000;background:#fafafa;height:70px;margin-bottom:10px}.task-board,div.draggable-item-selected{border:1px solid #000}.task-board-sort-handle{float:left;padding-right:5px}.task-table .dropdown-menu{color:#000;text-decoration:none;font-weight:700}.task-table .dropdown-menu:focus,.task-table .dropdown-menu:hover{text-decoration:underline}td.task-table a{color:#000;text-decoration:none}td.task-table a:hover{text-decoration:underline}.task-board{position:relative;margin-bottom:4px;padding:2px;font-size:.85em;word-wrap:break-word}div.task-board-recent{border-width:2px}div.task-board-status-closed{user-select:none;border:1px dotted #555}.task-board a{color:#000;text-decoration:none}.task-board .dropdown-menu{font-weight:700}.task-board-collapsed{overflow:hidden}.task-board-saving-state{opacity:.3}.task-board-category:hover,.task-board-change-assignee:hover{opacity:.6}.task-board-saving-icon{position:absolute;margin:auto;width:100%;text-align:center;color:#000}.task-board-title{font-size:1.15em;margin-top:5px;margin-bottom:8px}.task-board-title a:hover{text-decoration:underline}.task-board-category-container{text-align:right;margin-top:8px;margin-bottom:8px}.task-board-category{font-weight:500;color:#000;border:1px solid #555;padding:1px 2px;border-radius:4px}.task-tags li{display:inline;margin:0 4px 0 0;padding:2px;color:#666;border:1px solid #666;border-radius:2px}.task-summary-container .task-tags{margin-top:10px}.task-board-avatars{text-align:right;float:right}.file-thumbnail img:hover,.task-board-icons a{opacity:.5}.task-board-icons{text-align:right;margin-top:4px;margin-bottom:2px}.task-board-icons span{opacity:.5;margin-left:2px}.task-board-icons a:hover,.task-board-icons span:hover{opacity:1}.task-board-date{font-weight:700;color:#000}span.task-board-date-today{color:#0000D9;opacity:1}span.task-board-date-overdue{color:#D90000;opacity:1}.task-board .task-score{font-weight:700}.task-board-age{display:inline-block;font-size:.9em}.project-overview-columns,.task-summary-columns{display:-webkit-flex;-webkit-flex-direction:row}span.task-board-age-total{border:1px solid #666;padding:1px 3px;border-top-left-radius:3px;border-bottom-left-radius:3px}span.task-board-age-column{border:1px solid #666;border-left:none;margin-left:-5px;padding:1px 3px;border-top-right-radius:3px;border-bottom-right-radius:3px}#task-summary{margin-bottom:15px}#task-summary h2{color:#666;font-size:2.5em;margin-top:0;padding-top:0}.task-summary-buttons{margin-top:10px;font-size:.85em}.task-summary-container{border:2px solid #000;border-radius:8px;padding:15px}.task-summary-columns{display:flex;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between}.task-summary-column{font-size:.9em;color:#666}.task-summary-column span{color:#555}.task-summary-column li{line-height:23px}.task-show-title{border:2px solid #000;border-radius:8px;margin-bottom:20px}.task-show-title h2{color:#555;font-size:1.8em;margin:0;padding:8px}.comment-actions,.comment-content,.comment-title{margin-left:55px}.task-link-closed{text-decoration:line-through}.flag-milestone{color:green}.color-picker{width:180px}.color-picker-option{height:25px}.color-picker-square{display:inline-block;width:18px;height:18px;margin-right:5px;border:1px solid #000}.color-picker-label{display:inline-block;vertical-align:bottom;padding-bottom:3px}#select2-form-color_id-results li.select2-results__option{padding:3px}.assign-me{font-size:.8em;vertical-align:bottom}.subtasks-table td,.task-links-table td{vertical-align:middle}.comment-sorting{text-align:right;font-size:.5em}.avatar-letter,.pagination,.project-overview-column,div.ganttview-hzheader-day,div.ganttview-hzheader-month{text-align:center}.comment-sorting a{color:#555;font-weight:400;text-decoration:none}.comment-sorting a:hover{color:#aaa}.comment{padding:5px;margin-bottom:15px}.comment-title,.form-column div.CodeMirror,.markdown blockquote,.markdown h1,.markdown p{margin-bottom:10px}.comment:hover{background:#fafafa}.comment-title{border-bottom:1px dotted #eee}.comment-username{font-weight:700;font-size:1.1em}.comment-date{color:#999;font-size:.7em;font-weight:200}.comment-actions{font-size:.8em;margin-top:8px}.subtasks-table,.task-links-table{font-size:.85em}.comment-actions li{display:inline}.comment-actions a{color:#999;text-decoration:none}.markdown h1,.markdown h2,.markdown h3,.markdown h4{text-decoration:underline}.comment-actions a:focus,.comment-actions a:hover{color:#333;text-decoration:underline}.task-links-task-count{color:#999}div.CodeMirror,div.CodeMirror-scroll{max-height:250px;min-height:200px}.markdown-editor-small div.CodeMirror,.markdown-editor-small div.CodeMirror-scroll{min-height:100px;max-height:180px}.markdown{line-height:1.4em}.markdown h1{margin-top:5px;font-size:1.5em;font-weight:700}.markdown h2{font-size:1.2em;font-weight:700}.markdown h3,.markdown h4{font-size:1.1em}.markdown ol,.markdown ul{margin-left:25px;margin-top:10px;margin-bottom:10px}.markdown pre{background:#fbfbfb;padding:10px;border-radius:5px;border:1px solid #ddd;overflow:auto;color:#444}.markdown blockquote{font-style:italic;border-left:3px solid #ddd;padding-left:10px;margin-left:20px}.markdown img{display:block;max-width:80%;margin-top:10px}.documentation{margin:0 auto;padding:20px;max-width:850px;background:#fefefe;border:1px solid #ccc;border-radius:5px;font-size:1.1em;color:#555}.documentation img{border:1px solid #333}.documentation h1{text-decoration:none;font-size:1.8em;margin-bottom:30px}.documentation h2{font-size:1.3em;text-decoration:none;border-bottom:1px solid #ccc;margin-bottom:25px}.documentation li{line-height:30px}.user-mention-link{font-weight:700;color:#000;text-decoration:none}.user-mention-link:hover{color:#555}.listing{border-radius:4px;padding:8px 35px 8px 14px;margin-bottom:20px;border:1px solid #ddd;color:#333;background-color:#fcfcfc;overflow:auto}.activity-title,.sidebar>ul li{border-bottom:1px dotted #efefef}.listing li{list-style-type:square;margin-left:20px;margin-bottom:3px}.activity-event,.listing ul,.sidebar>ul li:last-child{margin-bottom:15px}.listing ul{margin-top:15px}.activity-event{padding:10px}.activity-event:hover{background:#fafafa}.activity-date{margin-left:10px;font-weight:400;color:#999;font-size:.8em}.activity-content{margin-left:55px}.activity-title{font-weight:700;color:#000}.activity-description{font-size:.95em;color:#555;margin-top:10px}.activity-description li{list-style-type:circle}.activity-description ul{margin-top:10px;margin-left:20px}.dashboard-project-stats span{font-size:.75em;margin-right:10px;color:#999}.dashboard-project-stats strong{font-size:1.2em}.dashboard-table-link{font-weight:700;color:#444;text-decoration:none}.dashboard-table-link:focus,.dashboard-table-link:hover{color:#999}.pagination-next{margin-left:5px}.pagination-previous{margin-right:5px}#popover-container{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.8);overflow:auto;z-index:100}#popover-content{position:absolute;width:70%;left:15%;top:1%;padding:15px;background:#fff;overflow:auto;max-height:90%}#main .confirm{max-width:700px;font-size:1.1em}.sidebar-container{margin-top:10px;height:100%;width:100%;display:-ms-flexbox;display:-webkit-box;display:-moz-box;display:-ms-box;display:box;-ms-flex-direction:row;-webkit-box-orient:horizontal;-moz-box-orient:horizontal;-ms-box-orient:horizontal;box-orient:horizontal}.sidebar-content{padding-left:10px;-ms-flex:1;-webkit-box-flex:1;-moz-box-flex:1;-ms-box-flex:1;box-flex:1}.sidebar{padding-right:10px;border-right:1px dotted #eee;font-size:.95em;max-width:240px;min-width:190px;width:18%;-ms-flex:0 100px;-webkit-box-flex:0;-moz-box-flex:0;-ms-box-flex:0;box-flex:0}.sidebar h2{margin-top:0}.sidebar>ul a{text-decoration:none;color:#999;font-weight:300}.sidebar>ul a:hover{color:#333}.sidebar>ul li{list-style-type:none;line-height:35px;padding-left:13px}.sidebar>ul li:hover{border-left:5px solid #555;padding-left:8px}.sidebar>ul li.active{border-left:5px solid #333;padding-left:8px}.sidebar>ul li.active a{color:#333;font-weight:700}.sidebar-icons>ul li{padding-left:0}.sidebar-icons>ul li.active,.sidebar-icons>ul li:hover{padding-left:0;border-left:none}.sidebar>ul li.active a:focus,.sidebar>ul li.active a:hover{color:#555}@media only screen and (max-width:1024px){body{font-size:.85em}.form-tab{max-width:404px}.form-inline-group input[type=submit],.form-inline-group label{display:block}.form-inline-group input[type=submit]{margin-top:20px}td>input[type=text]{max-width:150px}.page-header .form-input-large{width:300px}}@media only screen and (max-width:1024px) and (orientation:landscape){header{padding-bottom:4px}div.chosen-container{font-size:.9em}input[type=number],input[type=date],input[type=email],input[type=password],input[type=text]{height:18px}.page-header .form-input-large{width:300px}}@media only screen and (max-width:640px){.hide-mobile{display:none}}.dropdown{display:inline;position:relative}.dropdown ul{display:none}ul.dropdown-submenu-open{display:block;position:absolute;z-index:1000;min-width:285px;margin:3px 0 0 1px;padding:6px 0;background-color:#fff;border:1px solid #b2b2b2;border-radius:3px}.dropdown-submenu-open li,.textarea-dropdown li{display:block;margin:0;padding:8px 10px;font-size:.85em;border-bottom:1px solid #f8f8f8;cursor:pointer}.dropdown-submenu-open li.no-hover{cursor:default}.dropdown-submenu-open li:last-child,.textarea-dropdown li:last-child{border:none}.dropdown-submenu-open li:not(.no-hover):hover,.textarea-dropdown .active,.textarea-dropdown li:hover{background:#4078C0;color:#fff}.dropdown-submenu-open li:hover a,.textarea-dropdown .active a,.textarea-dropdown li:hover a{color:#fff}.dropdown-submenu-open a,.textarea-dropdown a{text-decoration:none;color:#333}.dropdown-submenu-open a:focus{text-decoration:underline}.page-header .dropdown{padding-right:10px}.dropdown-menu-link-icon,.dropdown-menu-link-text{color:#333;text-decoration:none}.dropdown-menu-link-text:hover{text-decoration:underline}.textarea-dropdown{margin:3px 0 0 1px;padding:6px 0;background-color:#fff;border:1px solid #b2b2b2;border-radius:3px}#file-dropzone,#screenshot-zone{position:relative;border:2px dashed #ccc;width:99%;height:250px;overflow:auto}#file-dropzone-inner,#screenshot-inner{position:absolute;left:0;bottom:48%;width:100%;text-align:center;color:#aaa}#screenshot-zone.screenshot-pasted{border:2px solid #333}#file-list{margin:20px}#file-list li{list-style-type:none;padding-top:8px;padding-bottom:8px;border-bottom:1px dotted #ddd;width:95%}#file-list li.file-error{font-weight:700;color:#b94a48}.project-header{margin-top:8px;margin-bottom:20px}.action-menu{color:#333;text-decoration:none}.action-menu:focus,.action-menu:hover{text-decoration:underline}.filter-box{display:inline-block;position:relative;font-size:0;margin-bottom:20px}.filter-box form,.project-header .filter-box{margin:0}.filter-box input[type=text]{margin:0;font-size:16px;height:26px;border-color:#ddd;border-top-left-radius:5px;border-bottom-left-radius:5px;vertical-align:top}.filter-box input[type=text]:focus{color:#000;border-color:rgba(82,168,236,.8);outline:0;box-shadow:0 0 8px rgba(82,168,236,.6)}.filter-box div.dropdown{background:#fafafa;display:inline-block;font-size:16px;border:1px solid #ddd;border-left:none;margin:0;padding:0 8px 0 5px;height:27px}.filter-box div.dropdown:last-child{border-top-right-radius:5px;border-bottom-right-radius:5px}.filter-box div.dropdown a{line-height:27px}div.ganttview-grid,div.ganttview-grid-row-cell,div.ganttview-hzheader-day,div.ganttview-hzheader-month,div.ganttview-vtheader,div.ganttview-vtheader-item-name,div.ganttview-vtheader-series{float:left}div.ganttview-grid-row-cell.last,div.ganttview-hzheader-day.last,div.ganttview-hzheader-month.last{border-right:none}div.ganttview{border:1px solid #999}div.ganttview-hzheader-month{width:60px;height:20px;border-right:1px solid #d0d0d0;line-height:20px;overflow:hidden}div.ganttview-hzheader-day{width:20px;height:20px;border-right:1px solid #f0f0f0;border-top:1px solid #d0d0d0;line-height:20px;color:#777}div.ganttview-vtheader{margin-top:41px;width:400px;overflow:hidden;background-color:#fff}div.ganttview-vtheader-item{color:#666}div.ganttview-vtheader-series-name{width:400px;height:31px;line-height:31px;padding-left:3px;border-top:1px solid #d0d0d0;font-size:.9em;overflow:hidden}div.ganttview-vtheader-series-name a{color:#666;text-decoration:none}div.ganttview-vtheader-series-name a:hover{color:#333;text-decoration:underline}div.ganttview-vtheader-series-name a i{color:#000}div.ganttview-vtheader-series-name a:hover i{color:#666}div.ganttview-slide-container{overflow:auto;border-left:1px solid #999}div.ganttview-grid-row-cell{width:20px;height:31px;border-right:1px solid #f0f0f0;border-top:1px solid #f0f0f0}div.ganttview-grid-row-cell.ganttview-weekend{background-color:#fafafa}div.ganttview-blocks{margin-top:40px}div.ganttview-block-container{height:28px;padding-top:4px}div.ganttview-block{position:relative;height:25px;background-color:#E5ECF9;border:1px solid silver;border-radius:3px}.ganttview-block-movable{cursor:move}div.ganttview-block-not-defined{border-color:#000;background-color:#000}div.ganttview-block-text{position:absolute;height:12px;font-size:.7em;color:#999;padding:2px 3px}div.ganttview-block div.ui-resizable-handle.ui-resizable-s{bottom:0}.project-creation-options{max-width:500px;border-left:3px dotted #efefef;margin-top:20px;padding-left:15px;padding-bottom:5px;padding-top:5px}.project-overview-columns{display:flex;flex-direction:row;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;margin-bottom:20px;font-size:1.4em}.project-overview-column{margin-right:80px;padding:3px 15px;border:1px dashed #ddd;border-radius:8px}.project-overview-column strong{font-size:1.3em;color:#444}.project-overview-column span{font-size:.8em;color:#777}.file-thumbnails{display:-webkit-flex;display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:flex-start;justify-content:flex-start}.file-thumbnail{width:250px;border:1px solid #efefef;border-radius:5px;margin-bottom:20px;box-shadow:4px 2px 10px -6px rgba(0,0,0,.55);margin-right:15px}.file-thumbnail img{border-top-left-radius:5px;border-top-right-radius:5px}.file-thumbnail-content{padding-left:8px;padding-right:8px}.file-thumbnail-title{font-weight:700;font-size:.9em;color:#555}.file-thumbnail-description{font-size:.8em;color:#aaa;margin-top:8px;margin-bottom:5px}.accordion-collapsed,.accordion-content{margin-bottom:25px}.file-viewer{position:relative}.file-viewer img{max-width:95%;max-height:85%;margin-top:10px}.views{display:inline-block;margin-left:10px;margin-right:10px;font-size:.9em}.views li{background:#fafafa;border-left:1px solid #ddd;border-top:1px solid #ddd;border-bottom:1px solid #ddd;display:inline;padding:5px 8px}.views a{color:#555;text-decoration:none}.views a:hover{color:#333;text-decoration:underline}.menu-inline li.active a,.views li.active a{font-weight:700;color:#000;text-decoration:none}.views li:first-child{border-top-left-radius:5px;border-bottom-left-radius:5px}.views li:last-child{border-right:1px solid #ddd;border-top-right-radius:5px;border-bottom-right-radius:5px}.accordion-title{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NEQ5RDgxQzc2RjQ5MTFFMjhEMUNENzFGRUMwRjhBRTciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NEQ5RDgxQzg2RjQ5MTFFMjhEMUNENzFGRUMwRjhBRTciPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0RDlEODFDNTZGNDkxMUUyOEQxQ0Q3MUZFQzBGOEFFNyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0RDlEODFDNjZGNDkxMUUyOEQxQ0Q3MUZFQzBGOEFFNyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvXFWFAAAAAYSURBVHjaYvj//z8D0/Pnz/8zgFgAAQYAS5UJscReGMIAAAAASUVORK5CYII=) 0 10px repeat-x}.accordion-title h3{display:inline;padding-right:5px;background:#fff}.accordion-content{margin-top:15px}.accordion-toggle{color:#333;text-decoration:none}.accordion-toggle:focus,.accordion-toggle:hover{color:#999}.accordion-toggle:before{content:"\f0d7"}.accordion-collapsed .accordion-toggle:before{content:"\f0da"}.accordion-collapsed .accordion-content{display:none}.avatar img{vertical-align:bottom}.avatar-left{float:left;margin-right:10px}.avatar-inline{display:inline-block;margin-right:3px}.avatar-48 div,.avatar-48 img{border-radius:30px}.avatar-48 .avatar-letter{line-height:48px;width:48px;font-size:25px}.avatar-20 div,.avatar-20 img{border-radius:10px}.avatar-20 .avatar-letter{line-height:20px;width:20px;font-size:11px}.avatar-letter{color:#fff} \ No newline at end of file diff --git a/sources/assets/css/chosen-sprite.png b/sources/assets/css/chosen-sprite.png deleted file mode 100644 index c57da70b4b5b1e08a6977ddde182677af0e5e1b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 538 zcmV+#0_FXQP)cz2)-WJLkv8J@4bb5L`rsE?Kc|FrXHkKz)ov z76MHYM&Apx%05P7orE!>9=yZ~6O0^V?1%{=1UASqa<2Pgnk7fs!OIs9gh{NCN+@=) z>Gfttd5uq;oeR{%NHjtqV~jEQeY?tDff=(jqx>~SZ_e+iN26HR*`0Q!Re)~HD85p> zbL()Mw}bI^#`7wp0+cv&7*LhrtOmR)?PK>(-BeLm#jL5Jfogv-QS(TBnUb;))Krqm zD}uDDeVLNhm1G*pFB`O?iA=dnWBEpqHk8Yh%Qu45EIG=&F-dDmt|;|nN@|3lOkVZ7>z*~a1?_t?U)c+&|JFJke1`&0-a z#PjhRlg?=$KTo4|rU@NyV_fzDy@>h!lVyKShsO8>V>$xyIXRbHK%H~^Aaz=s$Jz^V zlb?KfaKdZqu3^#m$mintvgJ15@j`sb2Zr%69Sn=xN01Tm5r)NQanT=jhwm7zqj2>O cEB}D~0$b-QdD7|v=>Px#07*qoM6N<$g6AXnUH||9 diff --git a/sources/assets/css/chosen-sprite@2x.png b/sources/assets/css/chosen-sprite@2x.png deleted file mode 100644 index 6b50545202cb4770039362c55025b0b9824663ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 738 zcmV<80v-K{P)oJoIWh{eAG@xkM<0ryd(K3(} zP8JV&;uuIJ4nL%g8!wSG9E$P+3QVMGgj><+00}M5I5kMzaT<~M;uJ`UhLfbp9Ahdsrux5(g+(>Q*+9wU{AuYPH0}W_u4`|q(9c->{ zt>Jn|lbhH<_x5jU6prFi#S}&XMZ=~Y5VyC3+ZN%hXciz8 zPcLpJgbIK#a49e31-%wf2zh2F&&(Nq;AL%4zA(=QJRGq`sx3y3#0_cg9Fim739XTOu1NKKjlWs`52Q+3 Uja*K~(*OVf07*qoM6N<$g3mu-GXMYp diff --git a/sources/assets/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/sources/assets/css/images/ui-bg_flat_0_aaaaaa_40x100.png deleted file mode 100644 index 5b5dab2ab7b1c50dea9cfe73dc5a269a92d2d4b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FscKIb$B>N1x91EQ4=4yQ7#`R^ z$vje}bP0l+XkK DSH>_4 diff --git a/sources/assets/css/images/ui-bg_flat_75_ffffff_40x100.png b/sources/assets/css/images/ui-bg_flat_75_ffffff_40x100.png deleted file mode 100644 index ac8b229af950c29356abf64a6c4aa894575445f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQYz+E8 zPo9&<{J;c_6SHRil>2s{Zw^OT)6@jj2u|u!(plXsM>LJD`vD!n;OXk;vd$@?2>^GI BH@yG= diff --git a/sources/assets/css/images/ui-bg_glass_55_fbf9ee_1x400.png b/sources/assets/css/images/ui-bg_glass_55_fbf9ee_1x400.png deleted file mode 100644 index ad3d6346e00f246102f72f2e026ed0491988b394..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour0hLi978O6-<~(*I$*%ybaDOn z{W;e!B}_MSUQoPXhYd^Y6RUoS1yepnPx`2Kz)7OXQG!!=-jY=F+d2OOy?#DnJ32>z UEim$g7SJdLPgg&ebxsLQ09~*s;{X5v diff --git a/sources/assets/css/images/ui-bg_glass_65_ffffff_1x400.png b/sources/assets/css/images/ui-bg_glass_65_ffffff_1x400.png deleted file mode 100644 index 42ccba269b6e91bef12ad0fa18be651b5ef0ee68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouqzpV=978O6-=0?FV^9z|eBtf= z|7WztIJ;WT>{+tN>ySr~=F{k$>;_x^_y?afmf9pRKH0)6?eSP?3s5hEr>mdKI;Vst E0O;M1& diff --git a/sources/assets/css/images/ui-bg_glass_75_dadada_1x400.png b/sources/assets/css/images/ui-bg_glass_75_dadada_1x400.png deleted file mode 100644 index 5a46b47cb16631068aee9e0bd61269fc4e95e5cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouq|7{B978O6lPf+wIa#m9#>Unb zm^4K~wN3Zq+uP{vDV26o)#~38k_!`W=^oo1w6ixmPC4R1b Tyd6G3lNdZ*{an^LB{Ts5`idse diff --git a/sources/assets/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/sources/assets/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png deleted file mode 100644 index 7c9fa6c6edcfcdd3e5b77e6f547b719e6fc66e30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101 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 diff --git a/sources/assets/css/images/ui-icons_2e83ff_256x240.png b/sources/assets/css/images/ui-icons_2e83ff_256x240.png deleted file mode 100644 index 45e8928e5284adacea3f9ec07b9b50667d2ac65f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4369 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 diff --git a/sources/assets/css/images/ui-icons_444444_256x240.png b/sources/assets/css/images/ui-icons_444444_256x240.png deleted file mode 100644 index 1df074598ad32a172dc9c0ae96dffa13358e75e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6992 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 Ju2i%R{Vx&%ER_HN diff --git a/sources/assets/css/images/ui-icons_454545_256x240.png b/sources/assets/css/images/ui-icons_454545_256x240.png deleted file mode 100644 index 7ec70d11bfb2f77374dfd00ef61ba0c3647b5a0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4369 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 k*Kv;w;*%(i9W@fAqs5i2wiq diff --git a/sources/assets/css/images/ui-icons_555555_256x240.png b/sources/assets/css/images/ui-icons_555555_256x240.png deleted file mode 100644 index 0b559385536cedb4c14a2cdad4c49a05b3d99d36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6988 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 U(6`q`=`0AKgEG*pQpY~}KNtZxZvX%Q diff --git a/sources/assets/css/images/ui-icons_777777_256x240.png b/sources/assets/css/images/ui-icons_777777_256x240.png deleted file mode 100644 index b5f6ac803878c57d1df89e3675d911f6254a582c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6999 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 VN4`BSDyKmJU6i4Ag(mj#{{h3EBPRd= diff --git a/sources/assets/css/images/ui-icons_cd0a0a_256x240.png b/sources/assets/css/images/ui-icons_cd0a0a_256x240.png deleted file mode 100644 index 7930a558099bc8d92b4264eb67a0f040460f4a4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4369 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 diff --git a/sources/assets/css/images/ui-icons_ffffff_256x240.png b/sources/assets/css/images/ui-icons_ffffff_256x240.png deleted file mode 100644 index c964d9a9bf49a0ea5210af5a054bdfe03705703b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6299 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 B!s-A3 diff --git a/sources/assets/css/print.min.css b/sources/assets/css/print.min.css deleted file mode 100644 index 9bc2d61..0000000 --- a/sources/assets/css/print.min.css +++ /dev/null @@ -1 +0,0 @@ -a:hover,th a{text-decoration:none;color:#333}.table-fixed td,.table-fixed th{overflow:hidden}#board td,td{vertical-align:top}#comments form,.board-column-collapsed,.page-header,.sidebar,header{display:none}.table-fixed td,.task-board-collapsed{white-space:nowrap;text-overflow:ellipsis}a{color:#36C;border:none}a:focus{outline:0;color:#DF5353;text-decoration:none;border:1px dotted #aaa}table{width:100%;border-collapse:collapse;border-spacing:0;margin-bottom:20px;font-size:.95em}#calendar table{margin-bottom:0}td,th{border:1px solid #eee;padding:.5em 3px}th{background:#fbfbfb;text-align:left}td li{margin-left:20px}.table-small{font-size:.8em}th a:focus,th a:hover{text-decoration:underline}.table-fixed{table-layout:fixed;white-space:nowrap}.table-stripped tr:nth-child(odd){background:#fefefe}.column-3{width:3%}.column-5{width:5%}.column-8{width:7.5%}.column-10{width:10%}.column-12{width:12%}.column-15{width:15%}.column-18{width:18%}.column-20{width:20%}.column-25{width:25%}.column-30{width:30%}.column-35{width:35%}.column-40{width:40%}.column-50{width:50%}.column-60{width:60%}.column-70,.column-80{width:70%}.draggable-row-handle{cursor:move;color:#dedede}.draggable-row-handle:hover{color:#333}tr.draggable-item-selected{background:#fff;border:2px solid #666;box-shadow:4px 2px 10px -4px rgba(0,0,0,.55)}tr.draggable-item-selected td{border-top:none;border-bottom:none}tr.draggable-item-selected td:first-child{border-left:none}tr.draggable-item-selected td:last-child{border-right:none}.table-stripped tr.draggable-item-hover,tr.draggable-item-hover{background:#FEFFF2}.public-board{margin-top:5px}.public-task{max-width:800px;margin:5px auto 0}#board-container{overflow-x:auto}#board{table-layout:fixed;margin-bottom:0}#board th.board-column-header{width:240px}.board-container-compact{overflow-x:initial}@media all and (-ms-high-contrast:active),(-ms-high-contrast:none){.board-container-compact #board{table-layout:auto}}#board th.board-column-header.board-column-compact{width:initial}td.board-column-task-collapsed{font-weight:700;background-color:#fbfbfb}#board th.board-column-header-collapsed{width:28px;min-width:28px;text-align:center;overflow:hidden}.board-rotation-wrapper{position:relative;padding:8px 4px;min-height:150px;overflow:hidden}.board-rotation{white-space:nowrap;-webkit-backface-visibility:hidden;-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:0 100%;-moz-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%}.board-column-title .dropdown-menu{text-decoration:none}.board-add-icon{float:left;padding:0 5px}.board-add-icon a{text-decoration:none;color:#36C;font-size:150%;line-height:70%}.board-add-icon a:focus,.board-add-icon a:hover{text-decoration:none;color:red}.board-column-header-task-count{color:#999;font-weight:400}th.board-column-header-collapsed .board-column-header-task-count{font-size:.85em}a.board-swimlane-toggle{font-size:.95em;text-decoration:none}a.board-swimlane-toggle:focus,a.board-swimlane-toggle:hover{color:#000;text-decoration:none;border:none}.board-task-list{overflow:auto;min-height:60px}.board-task-list-limit{background-color:#DF5353}.draggable-item{cursor:pointer;user-select:none;-webkit-user-select:none;-moz-user-select:none}.draggable-placeholder{border:2px dashed #000;background:#fafafa;height:70px;margin-bottom:10px}.task-board,div.draggable-item-selected{border:1px solid #000}.task-board-sort-handle{float:left;padding-right:5px}.task-table .dropdown-menu{color:#000;text-decoration:none;font-weight:700}.task-table .dropdown-menu:focus,.task-table .dropdown-menu:hover{text-decoration:underline}td.task-table a{color:#000;text-decoration:none}td.task-table a:hover{text-decoration:underline}.task-board{position:relative;margin-bottom:4px;padding:2px;font-size:.85em;word-wrap:break-word}div.task-board-recent{border-width:2px}div.task-board-status-closed{user-select:none;border:1px dotted #555}.task-board a{color:#000;text-decoration:none}.task-board .dropdown-menu{font-weight:700}.task-board-collapsed{overflow:hidden}.task-board-saving-state{opacity:.3}.task-board-category:hover,.task-board-change-assignee:hover{opacity:.6}.task-board-saving-icon{position:absolute;margin:auto;width:100%;text-align:center;color:#000}.task-board-title{font-size:1.15em;margin-top:5px;margin-bottom:8px}.task-board-title a:hover{text-decoration:underline}.task-board-category-container{text-align:right;margin-top:8px;margin-bottom:8px}.task-board-category{font-weight:500;color:#000;border:1px solid #555;padding:1px 2px;border-radius:4px}.task-tags li{display:inline;margin:0 4px 0 0;padding:2px;color:#666;border:1px solid #666;border-radius:2px}.task-summary-container .task-tags{margin-top:10px}.task-board-avatars{text-align:right;float:right}.task-board-change-assignee{cursor:pointer}.task-board-icons{text-align:right;margin-top:4px;margin-bottom:2px}.task-board-icons a{opacity:.5}.task-board-icons span{opacity:.5;margin-left:2px}.task-board-icons a:hover,.task-board-icons span:hover{opacity:1}.task-board-date{font-weight:700;color:#000}span.task-board-date-today{color:#0000D9;opacity:1}span.task-board-date-overdue{color:#D90000;opacity:1}.task-board .task-score{font-weight:700}.task-board-age{display:inline-block;font-size:.9em}span.task-board-age-total{border:1px solid #666;padding:1px 3px;border-top-left-radius:3px;border-bottom-left-radius:3px}span.task-board-age-column{border:1px solid #666;border-left:none;margin-left:-5px;padding:1px 3px;border-top-right-radius:3px;border-bottom-right-radius:3px}#task-summary{margin-bottom:15px}#task-summary h2{color:#666;font-size:2.5em;margin-top:0;padding-top:0}.task-summary-buttons{margin-top:10px;font-size:.85em}.task-summary-container{border:2px solid #000;border-radius:8px;padding:15px}.task-summary-columns{display:-webkit-flex;display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-justify-content:space-between;justify-content:space-between}.task-summary-column{font-size:.9em;color:#666}.task-summary-column span{color:#555}.task-summary-column li{line-height:23px}.task-show-title{border:2px solid #000;border-radius:8px;margin-bottom:20px}.task-show-title h2{color:#555;font-size:1.8em;margin:0;padding:8px}.comment-actions,.comment-content,.comment-title{margin-left:55px}.task-link-closed{text-decoration:line-through}.flag-milestone{color:green}.color-picker{width:180px}.color-picker-option{height:25px}.color-picker-square{display:inline-block;width:18px;height:18px;margin-right:5px;border:1px solid #000}.color-picker-label{display:inline-block;vertical-align:bottom;padding-bottom:3px}#select2-form-color_id-results li.select2-results__option{padding:3px}.assign-me{font-size:.8em;vertical-align:bottom}.subtasks-table td,.task-links-table td{vertical-align:middle}.comment-sorting{text-align:right;font-size:.5em}.comment-sorting a{color:#555;font-weight:400;text-decoration:none}.comment-sorting a:hover{color:#aaa}.comment{padding:5px;margin-bottom:15px}.comment-title,.form-column div.CodeMirror,.markdown blockquote,.markdown h1,.markdown p{margin-bottom:10px}.comment:hover{background:#fafafa}.comment-title{border-bottom:1px dotted #eee}.comment-username{font-weight:700;font-size:1.1em}.comment-date{color:#999;font-size:.7em;font-weight:200}.comment-actions{font-size:.8em;margin-top:8px}.subtasks-table,.task-links-table{font-size:.85em}.comment-actions li{display:inline}.comment-actions a{color:#999;text-decoration:none}.markdown h1,.markdown h2,.markdown h3,.markdown h4{text-decoration:underline}.comment-actions a:focus,.comment-actions a:hover{color:#333;text-decoration:underline}.task-links-task-count{color:#999}div.CodeMirror,div.CodeMirror-scroll{max-height:250px;min-height:200px}.markdown-editor-small div.CodeMirror,.markdown-editor-small div.CodeMirror-scroll{min-height:100px;max-height:180px}.markdown{line-height:1.4em}.markdown h1{margin-top:5px;font-size:1.5em;font-weight:700}.markdown h2{font-size:1.2em;font-weight:700}.markdown h3,.markdown h4{font-size:1.1em}.markdown ol,.markdown ul{margin-left:25px;margin-top:10px;margin-bottom:10px}.markdown pre{background:#fbfbfb;padding:10px;border-radius:5px;border:1px solid #ddd;overflow:auto;color:#444}.markdown blockquote{font-style:italic;border-left:3px solid #ddd;padding-left:10px;margin-left:20px}.markdown img{display:block;max-width:80%;margin-top:10px}.documentation{margin:0 auto;padding:20px;max-width:850px;background:#fefefe;border:1px solid #ccc;border-radius:5px;font-size:1.1em;color:#555}.documentation img{border:1px solid #333}.documentation h1{text-decoration:none;font-size:1.8em;margin-bottom:30px}.documentation h2{font-size:1.3em;text-decoration:none;border-bottom:1px solid #ccc;margin-bottom:25px}.documentation li{line-height:30px}.user-mention-link{font-weight:700;color:#000;text-decoration:none}.user-mention-link:hover{color:#555} \ No newline at end of file diff --git a/sources/assets/css/src/accordion.css b/sources/assets/css/src/accordion.css deleted file mode 100644 index 313592b..0000000 --- a/sources/assets/css/src/accordion.css +++ /dev/null @@ -1,40 +0,0 @@ -.accordion-title { - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NEQ5RDgxQzc2RjQ5MTFFMjhEMUNENzFGRUMwRjhBRTciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NEQ5RDgxQzg2RjQ5MTFFMjhEMUNENzFGRUMwRjhBRTciPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0RDlEODFDNTZGNDkxMUUyOEQxQ0Q3MUZFQzBGOEFFNyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0RDlEODFDNjZGNDkxMUUyOEQxQ0Q3MUZFQzBGOEFFNyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvXFWFAAAAAYSURBVHjaYvj//z8D0/Pnz/8zgFgAAQYAS5UJscReGMIAAAAASUVORK5CYII=) repeat-x scroll 0 10px; -} - -.accordion-title h3 { - display: inline; - padding-right: 5px; - background: #fff; -} - -.accordion-content { - margin-top: 15px; - margin-bottom: 25px; -} - -.accordion-toggle { - color: #333; - text-decoration: none; -} - -.accordion-toggle:focus, -.accordion-toggle:hover { - color: #999; -} - -.accordion-toggle:before { - content: "\f0d7"; -} - -.accordion-collapsed .accordion-toggle:before { - content: "\f0da"; -} - -.accordion-collapsed { - margin-bottom: 25px; -} - -.accordion-collapsed .accordion-content { - display: none; -} diff --git a/sources/assets/css/src/activity.css b/sources/assets/css/src/activity.css deleted file mode 100644 index 36ede4a..0000000 --- a/sources/assets/css/src/activity.css +++ /dev/null @@ -1,41 +0,0 @@ -/* activity */ -.activity-event { - margin-bottom: 15px; - padding: 10px; -} - -.activity-event:hover { - background: #fafafa; -} - -.activity-date { - margin-left: 10px; - font-weight: normal; - color: #999; - font-size: 0.8em; -} - -.activity-content { - margin-left: 55px; -} - -.activity-title { - font-weight: bold; - color: #000; - border-bottom: 1px dotted #efefef; -} - -.activity-description { - font-size: 0.95em; - color: #555; - margin-top: 10px; -} - -.activity-description li { - list-style-type: circle; -} - -.activity-description ul { - margin-top: 10px; - margin-left: 20px; -} diff --git a/sources/assets/css/src/alert.css b/sources/assets/css/src/alert.css deleted file mode 100644 index 99a8d25..0000000 --- a/sources/assets/css/src/alert.css +++ /dev/null @@ -1,59 +0,0 @@ -/* alerts */ -.alert { - padding: 8px 35px 8px 14px; - margin-top: 5px; - margin-bottom: 5px; - color: #c09853; - background-color: #fcf8e3; - border: 1px solid #fbeed5; - border-radius: 4px; -} - -.alert-success { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.alert-error { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.alert-info { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.alert-normal { - color: #333; - background-color: #f0f0f0; - border-color: #ddd; -} - -.alert ul { - margin-top: 10px; - margin-bottom: 10px; -} - -.alert li { - margin-left: 25px; -} - -.alert-fade-out { - text-align: center; - position: fixed; - bottom: 0; - left: 20%; - width: 60%; - padding-top: 5px; - padding-bottom: 5px; - margin-bottom: 0; - border-width: 1px 0 0; - border-radius: 0; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - z-index: 9999; -} diff --git a/sources/assets/css/src/avatar.css b/sources/assets/css/src/avatar.css deleted file mode 100644 index de674b8..0000000 --- a/sources/assets/css/src/avatar.css +++ /dev/null @@ -1,40 +0,0 @@ -.avatar img { - vertical-align: bottom; -} - -.avatar-left { - float: left; - margin-right: 10px; -} - -.avatar-inline { - display: inline-block; - margin-right: 3px; -} - -.avatar-48 img, -.avatar-48 div { - border-radius: 30px; -} - -.avatar-48 .avatar-letter { - line-height: 48px; - width: 48px; - font-size: 25px; -} - -.avatar-20 img, -.avatar-20 div { - border-radius: 10px; -} - -.avatar-20 .avatar-letter { - line-height: 20px; - width: 20px; - font-size: 11px; -} - -.avatar-letter { - color: #fff; - text-align: center; -} diff --git a/sources/assets/css/src/base.css b/sources/assets/css/src/base.css deleted file mode 100644 index 591af72..0000000 --- a/sources/assets/css/src/base.css +++ /dev/null @@ -1,71 +0,0 @@ -/* reset */ -li, -ul, -ol, -table, -tr, -td, -th, -p, -blockquote, -body { - margin: 0; - padding: 0; - font-size: 100%; -} - -body { - margin-left: 10px; - margin-right: 10px; - padding-bottom: 10px; - color: #333; - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; - text-rendering: optimizeLegibility; -} - -.page { - clear: both; -} - -ul.no-bullet li { - list-style-type: none; - margin-left: 0; -} - -.pull-right { - text-align: right; -} - -hr { - border: 0; - height: 0; - border-top: 1px solid rgba(0, 0, 0, 0.1); - border-bottom: 1px solid rgba(255, 255, 255, 0.3); -} - -.chosen-select { - min-height: 27px; /* Reserve some space to avoid re-layout due to chosen */ -} - -#ui-datepicker-div { - font-size: 0.8em; -} - -#app-loading-icon { - position: fixed; - right: 3px; - bottom: 3px; -} - -.web-notification-icon { - color: #3366CC; -} - -.web-notification-icon:focus, -.web-notification-icon:hover { - color: #000; -} - -.smaller { - font-size: 0.85em; -} diff --git a/sources/assets/css/src/board.css b/sources/assets/css/src/board.css deleted file mode 100644 index 95e0410..0000000 --- a/sources/assets/css/src/board.css +++ /dev/null @@ -1,159 +0,0 @@ -/* public board */ -.public-board { - margin-top: 5px; -} - -.public-task { - max-width: 800px; - margin: 0 auto; - margin-top: 5px; -} - -/* board table */ -#board-container { - overflow-x: auto; -} - -#board { - table-layout: fixed; - margin-bottom: 0; -} - -#board th.board-column-header { - width: 240px; -} - -#board td { - vertical-align: top; -} - -/* compact mode/horizontal scrolling */ -.board-container-compact { - overflow-x: initial; -} - -@media all and (-ms-high-contrast: active), (-ms-high-contrast: none) { - .board-container-compact #board { - table-layout: auto; - } -} - -#board th.board-column-header.board-column-compact { - width: initial; /* Do not force the width of the columns in compact view mode */ -} - -/* show/hide column */ -.board-column-collapsed { - display: none; -} - -td.board-column-task-collapsed { - font-weight: bold; - background-color: #fbfbfb; -} - -#board th.board-column-header-collapsed { - width: 28px; - min-width: 28px; - text-align: center; - overflow: hidden; -} - -.board-rotation-wrapper { - position: relative; - padding: 8px 4px; - min-height: 150px; - overflow: hidden; -} - -.board-rotation { - white-space: nowrap; - -webkit-backface-visibility: hidden; - -webkit-transform: rotate(90deg); - -moz-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); - -webkit-transform-origin: 0 100%; - -moz-transform-origin: 0 100%; - -ms-transform-origin: 0 100%; - transform-origin: 0 100%; -} - -/* column header */ -.board-column-title .dropdown-menu { - text-decoration: none; -} - -.board-add-icon { - float: left; - padding: 0 5px; -} - -.board-add-icon a { - text-decoration: none; - color: #3366CC; - font-size: 150%; - line-height: 70%; -} - -.board-add-icon a:focus, -.board-add-icon a:hover { - text-decoration: none; - color: red; -} - -.board-column-header-task-count { - color: #999; - font-weight: normal; -} - -th.board-column-header-collapsed .board-column-header-task-count { - font-size: 0.85em; -} - -/* swimlanes */ -a.board-swimlane-toggle { - font-size: 0.95em; - text-decoration: none; -} - -a.board-swimlane-toggle:hover, -a.board-swimlane-toggle:focus { - color: #000; - text-decoration: none; - border: none; -} - -/* board task list */ -.board-task-list { - overflow: auto; - min-height: 60px; -} - -.board-task-list-limit { - background-color: #DF5353; -} - -/* drag and drop */ -.draggable-item { - cursor: pointer; - user-select: none; - -webkit-user-select: none; - -moz-user-select: none; -} - -.draggable-placeholder { - border: 2px dashed #000; - background: #fafafa; - height: 70px; - margin-bottom: 10px; -} - -div.draggable-item-selected { - border: 1px solid #000; -} - -.task-board-sort-handle { - float: left; - padding-right: 5px; -} diff --git a/sources/assets/css/src/button.css b/sources/assets/css/src/button.css deleted file mode 100644 index bcc374c..0000000 --- a/sources/assets/css/src/button.css +++ /dev/null @@ -1,61 +0,0 @@ -/* buttons */ -.btn { - font-size: 1.1em; - font-weight: normal; - cursor: pointer; - -webkit-appearance: none; - appearance: none; - display: inline-block; - color: #333; - background: #f5f5f5; - border: 1px solid #ddd; - border-radius: 2px; - padding: 3px 10px; - margin: 0; -} - -a.btn { - text-decoration: none; -} - -.btn:hover { - border: 1px solid #bbb; - color: #000; - background: #fafafa; -} - -.btn-red { - border-color: #b0281a;; - background: #d14836; - color: #fff; -} - -.btn-red:hover, -.btn-red:focus { - color: #fff; - background: #c53727; -} - -.btn-blue { - border-color: #3079ed; - background: #4d90fe; - color: #fff; -} - -.btn-blue:hover, -.btn-blue:focus { - border-color: #2f5bb7; - background: #357ae8; - color: #fff; -} - -.btn:disabled { - color: #ccc; - border: 1px solid #ccc; - background: #f7f7f7; -} - -.buttons-header { - font-size: 0.9em; - margin-bottom: 15px; -} diff --git a/sources/assets/css/src/comment.css b/sources/assets/css/src/comment.css deleted file mode 100644 index 91dfd10..0000000 --- a/sources/assets/css/src/comment.css +++ /dev/null @@ -1,70 +0,0 @@ -/* sorting */ -.comment-sorting { - text-align: right; - font-size: 0.5em; -} - -.comment-sorting a { - color: #555; - font-weight: normal; - text-decoration: none; -} - -.comment-sorting a:hover { - color: #aaa; -} - -/* comment container */ -.comment { - padding: 5px; - margin-bottom: 15px; -} - -.comment:hover { - background: #fafafa; -} - -/* comment title */ -.comment-title { - border-bottom: 1px dotted #eee; - margin-left: 55px; - margin-bottom: 10px; -} - -.comment-username { - font-weight: bold; - font-size: 1.1em; -} - -.comment-date { - color: #999; - font-size: 0.7em; - font-weight: 200; -} - -/* comment actions */ -.comment-actions { - font-size: 0.8em; - margin-left: 55px; - margin-top: 8px; -} - -.comment-actions li { - display: inline; -} - -.comment-actions a { - color: #999; - text-decoration: none; -} - -.comment-actions a:focus, -.comment-actions a:hover { - color: #333; - text-decoration: underline; -} - -/* comment content */ -.comment-content { - margin-left: 55px; -} diff --git a/sources/assets/css/src/confirm.css b/sources/assets/css/src/confirm.css deleted file mode 100644 index 0d78625..0000000 --- a/sources/assets/css/src/confirm.css +++ /dev/null @@ -1,5 +0,0 @@ -/* confirmation box */ -#main .confirm { - max-width: 700px; - font-size: 1.1em; -} diff --git a/sources/assets/css/src/dashboard.css b/sources/assets/css/src/dashboard.css deleted file mode 100644 index 4cd4d4d..0000000 --- a/sources/assets/css/src/dashboard.css +++ /dev/null @@ -1,21 +0,0 @@ -/* dashboard */ -.dashboard-project-stats span { - font-size: 0.75em; - margin-right: 10px; - color: #999; -} - -.dashboard-project-stats strong { - font-size: 1.2em; -} - -.dashboard-table-link { - font-weight: bold; - color: #444; - text-decoration: none; -} - -.dashboard-table-link:focus, -.dashboard-table-link:hover { - color: #999; -} diff --git a/sources/assets/css/src/dropdown.css b/sources/assets/css/src/dropdown.css deleted file mode 100644 index 7d967b0..0000000 --- a/sources/assets/css/src/dropdown.css +++ /dev/null @@ -1,93 +0,0 @@ -.dropdown { - display: inline; - position: relative; -} - -.dropdown ul { - display: none; -} - -ul.dropdown-submenu-open { - display: block; - position: absolute; - z-index: 1000; - min-width: 285px; - list-style: none; - margin: 3px 0 0 1px; - padding: 6px 0; - background-color: #fff; - border: 1px solid #b2b2b2; - border-radius: 3px; - box-shadow: 0px 1px 3px rgba(0,0,0,0.15); -} - -.textarea-dropdown li, -.dropdown-submenu-open li { - display: block; - margin: 0; - padding: 0; - padding-left: 10px; - padding-right: 10px; - padding-top: 8px; - padding-bottom: 8px; - font-size: 0.85em; - border-bottom: 1px solid #f8f8f8; - cursor: pointer; -} - -.dropdown-submenu-open li.no-hover { - cursor: default; -} - -.textarea-dropdown li:last-child, -.dropdown-submenu-open li:last-child { - border: none; -} - -.textarea-dropdown .active, -.textarea-dropdown li:hover, -.dropdown-submenu-open li:not(.no-hover):hover { - background: #4078C0; - color: #fff; -} - -.textarea-dropdown .active a, -.textarea-dropdown li:hover a, -.dropdown-submenu-open li:hover a { - color: #fff; -} - -.textarea-dropdown a, -.dropdown-submenu-open a { - text-decoration: none; - color: #333; -} - -.dropdown-submenu-open a:focus { - text-decoration: underline; -} - -.page-header .dropdown { - padding-right: 10px; -} - -.dropdown-menu-link-text, -.dropdown-menu-link-icon { - color: #333; - text-decoration: none; -} - -.dropdown-menu-link-text:hover { - text-decoration: underline; -} - -/* textarea dropdown */ -.textarea-dropdown { - list-style: none; - margin: 3px 0 0 1px; - padding: 6px 0; - background-color: #fff; - border: 1px solid #b2b2b2; - border-radius: 3px; - box-shadow: 0px 1px 3px rgba(0,0,0,0.15); -} diff --git a/sources/assets/css/src/files.css b/sources/assets/css/src/files.css deleted file mode 100644 index a81b387..0000000 --- a/sources/assets/css/src/files.css +++ /dev/null @@ -1,56 +0,0 @@ -.file-thumbnails { - display: -webkit-flex; - display: flex; - -webkit-flex-direction: row; - flex-direction: row; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - -webkit-justify-content: flex-start; - justify-content: flex-start; -} - -.file-thumbnail { - width: 250px; - border: 1px solid #efefef; - border-radius: 5px; - margin-bottom: 20px; - box-shadow: 4px 2px 10px -6px rgba(0,0,0,0.55); - margin-right: 15px; -} - -.file-thumbnail img { - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - -.file-thumbnail img:hover { - opacity: 0.5; -} - -.file-thumbnail-content { - padding-left: 8px; - padding-right: 8px; -} - -.file-thumbnail-title { - font-weight: 700; - font-size: 0.9em; - color: #555; -} - -.file-thumbnail-description { - font-size: 0.8em; - color: #aaa; - margin-top: 8px; - margin-bottom: 5px; -} - -.file-viewer { - position: relative; -} - -.file-viewer img { - max-width: 95%; - max-height: 85%; - margin-top: 10px; -} diff --git a/sources/assets/css/src/filters.css b/sources/assets/css/src/filters.css deleted file mode 100644 index 3e36286..0000000 --- a/sources/assets/css/src/filters.css +++ /dev/null @@ -1,70 +0,0 @@ -/* project header */ -.project-header { - margin-top: 8px; - margin-bottom: 20px; -} - -.action-menu { - color: #333; - text-decoration: none; -} - -.action-menu:hover, -.action-menu:focus { - text-decoration: underline; -} - -/* search box */ -.filter-box { - display: inline-block; - position: relative; - font-size: 0; - margin-bottom: 20px; -} - -.project-header .filter-box { - margin: 0; -} - -.filter-box form { - margin: 0; -} - -.filter-box input[type="text"] { - margin: 0; - font-size: 16px; - height: 26px; - border-color: #ddd; - border-top-left-radius: 5px; - border-bottom-left-radius: 5px; - vertical-align: top; -} - -.filter-box input[type="text"]:focus { - color: #000; - border-color: rgba(82, 168, 236, 0.8); - outline: 0; - box-shadow: 0 0 8px rgba(82, 168, 236, 0.6); -} - -.filter-box div.dropdown { - background: #fafafa; - display: inline-block; - font-size: 16px; - border: 1px solid #ddd; - border-left: none; - margin: 0; - padding: 0; - padding-left: 5px; - padding-right: 8px; - height: 27px; -} - -.filter-box div.dropdown:last-child { - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; -} - -.filter-box div.dropdown a { - line-height: 27px; -} diff --git a/sources/assets/css/src/form.css b/sources/assets/css/src/form.css deleted file mode 100644 index 2c81707..0000000 --- a/sources/assets/css/src/form.css +++ /dev/null @@ -1,200 +0,0 @@ -/* forms */ -form { - margin-bottom: 20px; -} - -label { - cursor: pointer; - display: block; - margin-top: 10px; -} - -input[type="number"], -input[type="date"], -input[type="email"], -input[type="password"], -input[type="text"] { - color: #888; - border: 1px solid #ccc; - width: 300px; - max-width: 95%; - font-size: 100%; - height: 25px; - padding-bottom: 0; - font-family: sans-serif; - margin-top: 10px; - -webkit-appearance: none; - appearance: none; -} - -input[type="number"]:focus, -input[type="date"]:focus, -input[type="email"]:focus, -input[type="password"]:focus, -input[type="text"]:focus, -textarea:focus { - color: #000; - border-color: rgba(82, 168, 236, 0.8); - outline: 0; - box-shadow: 0 0 8px rgba(82, 168, 236, 0.6); -} - -input.form-numeric, -input[type="number"] { - width: 70px; -} - -textarea { - border: 1px solid #ccc; - width: 400px; - max-width: 99%; - height: 200px; - font-size: 100%; - font-family: sans-serif; -} - -select { - max-width: 95%; -} - -select:focus { - outline: 0; -} - -.tag-autocomplete { - width: 400px; -} - -span.select2-container { - margin-top: 2px; -} - -::-webkit-input-placeholder { - color: #ddd; - padding-top: 2px; -} - -::-ms-input-placeholder { - color: #ddd; - padding-top: 2px; -} - -::-moz-placeholder { - color: #ddd; - padding-top: 2px; -} - -.form-actions { - padding-top: 20px; - clear: both; -} - -input.form-error, -textarea.form-error { - border: 2px solid #b94a48; -} - -input.form-error:focus, -textarea.form-error:focus { - box-shadow: none; - border: 2px solid #b94a48; -} - -.form-required { - color: red; - padding-left: 5px; - font-weight: bold; -} - -.form-errors { - color: #b94a48; - list-style-type: none; -} - -ul.form-errors li { - margin-left: 0; -} - -.form-help { - font-size: 0.8em; - color: brown; - margin-bottom: 15px; -} - -.form-inline { - padding: 0; - margin: 0; - border: none; -} - -.form-inline label { - display: inline; -} - -.form-inline input, -.form-inline select { - margin: 0; - margin-right: 15px; -} - -.form-inline .form-required { - display: none; -} - -.form-inline-group { - display: inline; -} - -input.form-datetime, -input.form-date { - width: 150px; -} - -input.form-input-large { - width: 400px; -} - -input.form-input-small { - width: 150px; -} - -.form-columns { - display: -webkit-flex; - display: flex; - -webkit-flex-direction: row; - flex-direction: row; -} - -.form-column { - margin-right: 25px; -} - -.form-login { - width: 350px; - margin: 0 auto; - margin-top: 8%; -} - -.form-login li { - margin-left: 25px; - line-height: 25px; -} - -.form-login h2 { - margin-bottom: 30px; - font-size: 1.5em; - font-weight: bold; -} - -.popover-form { - margin-bottom: 0; -} - -.reset-password { - margin-top: 20px; -} - -.reset-password a { - font-size: 0.8em; - color: #999; -} diff --git a/sources/assets/css/src/gantt.css b/sources/assets/css/src/gantt.css deleted file mode 100644 index def5bf3..0000000 --- a/sources/assets/css/src/gantt.css +++ /dev/null @@ -1,143 +0,0 @@ -/* Based on jQuery.ganttView v.0.8.0 Copyright (c) 2010 JC Grubbs - jc.grubbs@devmynd.com - MIT License */ -div.ganttview-hzheader-month, -div.ganttview-hzheader-day, -div.ganttview-vtheader, -div.ganttview-vtheader-item-name, -div.ganttview-vtheader-series, -div.ganttview-grid, -div.ganttview-grid-row-cell { - float: left; -} - -div.ganttview-hzheader-month, -div.ganttview-hzheader-day { - text-align: center; -} - -div.ganttview-grid-row-cell.last, -div.ganttview-hzheader-day.last, -div.ganttview-hzheader-month.last { - border-right: none; -} - -div.ganttview { - border: 1px solid #999; -} - -/* Horizontal Header */ -div.ganttview-hzheader-month { - width: 60px; - height: 20px; - border-right: 1px solid #d0d0d0; - line-height: 20px; - overflow: hidden; -} - -div.ganttview-hzheader-day { - width: 20px; - height: 20px; - border-right: 1px solid #f0f0f0; - border-top: 1px solid #d0d0d0; - line-height: 20px; - color: #777; -} - -/* Vertical Header */ -div.ganttview-vtheader { - margin-top: 41px; - width: 400px; - overflow: hidden; - background-color: #fff; -} - -div.ganttview-vtheader-item { - color: #666; -} - -div.ganttview-vtheader-series-name { - width: 400px; - height: 31px; - line-height: 31px; - padding-left: 3px; - border-top: 1px solid #d0d0d0; - font-size: 0.9em; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -div.ganttview-vtheader-series-name a { - color: #666; - text-decoration: none; -} - -div.ganttview-vtheader-series-name a:hover { - color: #333; - text-decoration: underline; -} - -div.ganttview-vtheader-series-name a i { - color: #000; -} - -div.ganttview-vtheader-series-name a:hover i { - color: #666; -} - -/* Slider */ -div.ganttview-slide-container { - overflow: auto; - border-left: 1px solid #999; -} - -/* Grid */ -div.ganttview-grid-row-cell { - width: 20px; - height: 31px; - border-right: 1px solid #f0f0f0; - border-top: 1px solid #f0f0f0; -} - -div.ganttview-grid-row-cell.ganttview-weekend { - background-color: #fafafa; -} - -/* Blocks */ -div.ganttview-blocks { - margin-top: 40px; -} - -div.ganttview-block-container { - height: 28px; - padding-top: 4px; -} - -div.ganttview-block { - position: relative; - height: 25px; - background-color: #E5ECF9; - border: 1px solid #c0c0c0; - border-radius: 3px; -} - -.ganttview-block-movable { - cursor: move; -} - -div.ganttview-block-not-defined { - border-color: #000; - background-color: #000; -} - -div.ganttview-block-text { - position: absolute; - height: 12px; - font-size: 0.7em; - color: #999; - padding: 2px 3px; -} - -/* Adjustments for jQuery UI Styling */ -div.ganttview-block div.ui-resizable-handle.ui-resizable-s { - bottom: -0; -} diff --git a/sources/assets/css/src/header.css b/sources/assets/css/src/header.css deleted file mode 100644 index 0d68f3e..0000000 --- a/sources/assets/css/src/header.css +++ /dev/null @@ -1,122 +0,0 @@ -/* header */ -header { - margin-top: 10px; - padding-bottom: 10px; - border-bottom: 1px solid #dedede; -} - -header h1 { - margin: 0; - padding: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 70%; - float: left; -} - -header ul { - text-align: right; - font-size: 0.9em; -} - -header li { - display: inline; - padding-left: 30px; -} - -header a { - color: #333; - text-decoration: none; -} - -header a:hover { - color: #666; -} - -nav .active a { - color: #333; - font-weight: bold; -} - -/* logo */ -.logo a { - opacity: 0.5; - color: #d40000; -} - -.logo span { - color: #333; -} - -.logo a:hover { - opacity: 0.8; - color: #333; -} - -.logo a:focus span, -.logo a:hover span { - color: #d40000; -} - -/* user links on the left */ -header .user-links .dropdown { - margin-left: 15px; -} - -/* title tooltip */ -header h1 .tooltip { - opacity: 0.3; - font-size: 0.6em; -} - -/* page header */ -.page-header { - margin-bottom: 20px; -} - -.page-header h2 { - margin: 0; - padding: 0; - font-size: 1.4em; - font-weight: bold; - border-bottom: 1px dotted #ccc; -} - -.page-header h2 a { - color: #333; - text-decoration: none; -} - -.page-header h2 a:focus, -.page-header h2 a:hover { - color: #aaa; -} - -.page-header ul { - text-align: left; - margin-top: 5px; - display: inline-block; -} - -.menu-inline li, -.page-header li { - display: inline; - padding-right: 15px; - font-size: 0.95em; -} - -.page-header li.active a { - color: #333; - text-decoration: none; - font-weight: bold; -} - -.page-header li.active a:hover, -.page-header li.active a:focus { - text-decoration: underline; -} - -.menu-inline { - margin-bottom: 5px; -} diff --git a/sources/assets/css/src/links.css b/sources/assets/css/src/links.css deleted file mode 100644 index f9d0c05..0000000 --- a/sources/assets/css/src/links.css +++ /dev/null @@ -1,17 +0,0 @@ -/* links */ -a { - color: #3366CC; - border: none; -} - -a:focus { - outline: 0; - color: #DF5353; - text-decoration: none; - border: 1px dotted #aaa; -} - -a:hover { - color: #333; - text-decoration: none; -} \ No newline at end of file diff --git a/sources/assets/css/src/listing.css b/sources/assets/css/src/listing.css deleted file mode 100644 index e96197e..0000000 --- a/sources/assets/css/src/listing.css +++ /dev/null @@ -1,21 +0,0 @@ -/* listing block */ -.listing { - border-radius: 4px; - padding: 8px 35px 8px 14px; - margin-bottom: 20px; - border: 1px solid #ddd; - color: #333; - background-color: #fcfcfc; - overflow: auto; -} - -.listing li { - list-style-type: square; - margin-left: 20px; - margin-bottom: 3px; -} - -.listing ul { - margin-top: 15px; - margin-bottom: 15px; -} \ No newline at end of file diff --git a/sources/assets/css/src/markdown.css b/sources/assets/css/src/markdown.css deleted file mode 100644 index 90fd48e..0000000 --- a/sources/assets/css/src/markdown.css +++ /dev/null @@ -1,121 +0,0 @@ -/* markdown editor */ -div.CodeMirror, -div.CodeMirror-scroll { - max-height: 250px; - min-height: 200px; -} - -.markdown-editor-small div.CodeMirror, -.markdown-editor-small div.CodeMirror-scroll { - min-height: 100px; - max-height: 180px; -} - -.form-column div.CodeMirror { - margin-bottom: 10px; -} - -/* markdown content */ -.markdown { - line-height: 1.4em; -} - -.markdown h1 { - margin-top: 5px; - margin-bottom: 10px; - font-size: 1.5em; - font-weight: bold; - text-decoration: underline; -} - -.markdown h2 { - font-size: 1.2em; - font-weight: bold; - text-decoration: underline; -} - -.markdown h3 { - font-size: 1.1em; - text-decoration: underline; -} - -.markdown h4 { - font-size: 1.1em; - text-decoration: underline; -} - -.markdown p { - margin-bottom: 10px; -} - -.markdown ol, -.markdown ul { - margin-left: 25px; - margin-top: 10px; - margin-bottom: 10px; -} - -.markdown pre { - background: #fbfbfb; - padding: 10px; - border-radius: 5px; - border: 1px solid #ddd; - overflow: auto; - color: #444; -} - -.markdown blockquote { - font-style: italic; - border-left: 3px solid #ddd; - padding-left: 10px; - margin-bottom: 10px; - margin-left: 20px; -} - -.markdown img { - display: block; - max-width: 80%; - margin-top: 10px; -} - -.documentation { - margin: 0 auto; - padding: 20px; - max-width: 850px; - background: #fefefe; - border: 1px solid #ccc; - border-radius: 5px; - font-size: 1.1em; - color: #555; -} - -.documentation img { - border: 1px solid #333; -} - -.documentation h1 { - text-decoration: none; - font-size: 1.8em; - margin-bottom: 30px; -} - -.documentation h2 { - font-size: 1.3em; - text-decoration: none; - border-bottom: 1px solid #ccc; - margin-bottom: 25px; -} - -.documentation li { - line-height: 30px; -} - -.user-mention-link { - font-weight: bold; - color: #000; - text-decoration: none; -} - -.user-mention-link:hover { - color: #555; -} diff --git a/sources/assets/css/src/pagination.css b/sources/assets/css/src/pagination.css deleted file mode 100644 index 7995287..0000000 --- a/sources/assets/css/src/pagination.css +++ /dev/null @@ -1,12 +0,0 @@ -/* pagination */ -.pagination { - text-align: center; -} - -.pagination-next { - margin-left: 5px; -} - -.pagination-previous { - margin-right: 5px; -} \ No newline at end of file diff --git a/sources/assets/css/src/popover.css b/sources/assets/css/src/popover.css deleted file mode 100644 index c08d97c..0000000 --- a/sources/assets/css/src/popover.css +++ /dev/null @@ -1,22 +0,0 @@ -/* popover */ -#popover-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.8); - overflow: auto; - z-index: 100; -} - -#popover-content { - position: absolute; - width: 70%; - left: 15%; - top: 1%; - padding: 15px; - background: #fff; - overflow: auto; - max-height: 90%; -} diff --git a/sources/assets/css/src/print.css b/sources/assets/css/src/print.css deleted file mode 100644 index b955f32..0000000 --- a/sources/assets/css/src/print.css +++ /dev/null @@ -1,6 +0,0 @@ -header, -.sidebar, -#comments form, -.page-header { - display: none; -} \ No newline at end of file diff --git a/sources/assets/css/src/project.css b/sources/assets/css/src/project.css deleted file mode 100644 index 98c9442..0000000 --- a/sources/assets/css/src/project.css +++ /dev/null @@ -1,45 +0,0 @@ -.project-creation-options { - max-width: 500px; - border-left: 3px dotted #efefef; - margin-top: 20px; - padding-left: 15px; - padding-bottom: 5px; - padding-top: 5px; -} - -.project-overview-columns { - display: -webkit-flex; - display: flex; - -webkit-flex-direction: row; - flex-direction: row; - - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - - -webkit-align-items: center; - align-items: center; - - -webkit-justify-content: center; - justify-content: center; - - margin-bottom: 20px; - font-size: 1.4em; -} - -.project-overview-column { - text-align: center; - margin-right: 80px; - padding: 3px 15px 3px 15px; - border: 1px dashed #ddd; - border-radius: 8px; -} - -.project-overview-column strong { - font-size: 1.3em; - color: #444; -} - -.project-overview-column span { - font-size: 0.8em; - color: #777; -} diff --git a/sources/assets/css/src/responsive.css b/sources/assets/css/src/responsive.css deleted file mode 100644 index c94be16..0000000 --- a/sources/assets/css/src/responsive.css +++ /dev/null @@ -1,58 +0,0 @@ -@media only screen and (max-width: 1024px) { - - body { - font-size: 0.85em; - } - - .form-tab { - max-width: 404px; - } - - .form-inline-group input[type="submit"], - .form-inline-group label { - display: block; - } - - .form-inline-group input[type="submit"] { - margin-top: 20px; - } - - td > input[type="text"] { - max-width: 150px; - } - - .page-header .form-input-large { - width: 300px; - } -} - -@media only screen and (max-width: 1024px) and (orientation: landscape) { - - header { - padding-bottom: 4px; - } - - div.chosen-container { - font-size: 0.9em; - } - - input[type="number"], - input[type="date"], - input[type="email"], - input[type="password"], - input[type="text"] { - height: 18px; - } - - .page-header .form-input-large { - width: 300px; - } -} - -@media only screen and (max-width: 640px) { - - .hide-mobile { - display: none; - } -} - diff --git a/sources/assets/css/src/sidebar.css b/sources/assets/css/src/sidebar.css deleted file mode 100644 index 791d0e0..0000000 --- a/sources/assets/css/src/sidebar.css +++ /dev/null @@ -1,93 +0,0 @@ -.sidebar-container { - margin-top: 10px; - height: 100%; - width: 100%; - display: -ms-flexbox; - display: -webkit-box; - display: -moz-box; - display: -ms-box; - display: box; - -ms-flex-direction: row; - -webkit-box-orient: horizontal; - -moz-box-orient: horizontal; - -ms-box-orient: horizontal; - box-orient: horizontal; -} - -.sidebar-content { - padding-left: 10px; - -ms-flex: 1; - -webkit-box-flex: 1; - -moz-box-flex: 1; - -ms-box-flex: 1; - box-flex: 1; -} - -.sidebar { - padding-right: 10px; - border-right: 1px dotted #eee; - font-size: 0.95em; - max-width: 240px; - min-width: 190px; - width: 18%; - -ms-flex: 0 100px; - -webkit-box-flex: 0; - -moz-box-flex: 0; - -ms-box-flex: 0; - box-flex: 0; -} - -.sidebar h2 { - margin-top: 0; -} - -.sidebar > ul a { - text-decoration: none; - color: #999; - font-weight: 300; -} - -.sidebar > ul a:hover { - color: #333; -} - -.sidebar > ul li { - list-style-type: none; - line-height: 35px; - border-bottom: 1px dotted #efefef; - padding-left: 13px; -} - -.sidebar > ul li:hover { - border-left: 5px solid #555; - padding-left: 8px; -} - -.sidebar > ul li.active { - border-left: 5px solid #333; - padding-left: 8px; -} - -.sidebar > ul li.active a { - color: #333; - font-weight: bold; -} - -.sidebar-icons > ul li { - padding-left: 0; -} - -.sidebar-icons > ul li:hover, -.sidebar-icons > ul li.active { - padding-left: 0; - border-left: none; -} - -.sidebar > ul li.active a:focus, -.sidebar > ul li.active a:hover { - color: #555; -} - -.sidebar > ul li:last-child { - margin-bottom: 15px; -} diff --git a/sources/assets/css/src/subtask.css b/sources/assets/css/src/subtask.css deleted file mode 100644 index 44194d8..0000000 --- a/sources/assets/css/src/subtask.css +++ /dev/null @@ -1,8 +0,0 @@ -/* subtasks */ -.subtasks-table { - font-size: 0.85em; -} - -.subtasks-table td { - vertical-align: middle; -} \ No newline at end of file diff --git a/sources/assets/css/src/table.css b/sources/assets/css/src/table.css deleted file mode 100644 index 4b776f4..0000000 --- a/sources/assets/css/src/table.css +++ /dev/null @@ -1,165 +0,0 @@ -/* tables */ -table { - width: 100%; - border-collapse: collapse; - border-spacing: 0; - margin-bottom: 20px; - font-size: 0.95em; -} - -#calendar table { - margin-bottom: 0; -} - -th, -td { - border: 1px solid #eee; - padding-top: 0.5em; - padding-bottom: 0.5em; - padding-left: 3px; - padding-right: 3px; -} - -td { - vertical-align: top; -} - -th { - background: #fbfbfb; - text-align: left; -} - -td li { - margin-left: 20px; -} - -.table-small { - font-size: 0.8em; -} - -th a { - text-decoration: none; - color: #333; -} - -th a:focus, -th a:hover { - text-decoration: underline; -} - -.table-fixed { - table-layout: fixed; - white-space: nowrap; -} - -.table-fixed th { - overflow: hidden; -} - -.table-fixed td { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.table-stripped tr:nth-child(odd) { - background: #fefefe; -} - -.column-3 { - width: 3%; -} - -.column-5 { - width: 5%; -} - -.column-8 { - width: 7.5%; -} - -.column-10 { - width: 10%; -} - -.column-12 { - width: 12%; -} - -.column-15 { - width: 15%; -} - -.column-18 { - width: 18%; -} - -.column-20 { - width: 20%; -} - -.column-25 { - width: 25%; -} - -.column-30 { - width: 30%; -} - -.column-35 { - width: 35%; -} - -.column-40 { - width: 40%; -} - -.column-50 { - width: 50%; -} - -.column-60 { - width: 60%; -} - -.column-70 { - width: 70%; -} - -.column-80 { - width: 70%; -} - -.draggable-row-handle { - cursor: move; - color: #dedede; -} - -.draggable-row-handle:hover { - color: #333; -} - -tr.draggable-item-selected { - background: #fff; - border: 2px solid #666; - box-shadow: 4px 2px 10px -4px rgba(0,0,0,0.55); -} - -tr.draggable-item-selected td { - border-top: none; - border-bottom: none; -} - -tr.draggable-item-selected td:first-child { - border-left: none; -} - -tr.draggable-item-selected td:last-child { - border-right: none; -} - -.table-stripped tr.draggable-item-hover, -tr.draggable-item-hover { - background: #FEFFF2; -} - diff --git a/sources/assets/css/src/task.css b/sources/assets/css/src/task.css deleted file mode 100644 index dc04d93..0000000 --- a/sources/assets/css/src/task.css +++ /dev/null @@ -1,288 +0,0 @@ -/* task listing table */ -.task-table .dropdown-menu { - color: #000; - text-decoration: none; - font-weight: bold; -} - -.task-table .dropdown-menu:focus, -.task-table .dropdown-menu:hover { - text-decoration: underline; -} - -td.task-table a { - color: #000; - text-decoration: none; -} - -td.task-table a:hover { - text-decoration: underline; -} - -/* task inside the board */ -.task-board { - position: relative; - margin-bottom: 4px; - border: 1px solid #000; - padding: 2px; - font-size: 0.85em; - word-wrap: break-word; -} - -div.task-board-recent { - border-width: 2px; -} - -div.task-board-status-closed { - user-select: none; - border: 1px dotted #555; -} - -.task-board a { - color: #000; - text-decoration: none; -} - -.task-board .dropdown-menu { - font-weight: bold; -} - -.task-board-collapsed { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -/* board saving state */ -.task-board-saving-state { - opacity: 0.3; -} - -.task-board-saving-icon { - position: absolute; - margin: auto; - width: 100%; - text-align: center; - color: #000; -} - -/* title one the card */ -.task-board-title { - font-size: 1.15em; - margin-top: 5px; - margin-bottom: 8px; -} - -.task-board-title a:hover { - text-decoration: underline; -} - -/* category label */ -.task-board-category-container { - text-align: right; - margin-top: 8px; - margin-bottom: 8px; -} - -.task-board-category { - font-weight: 500; - color: #000; - border: 1px solid #555; - padding: 1px 2px 1px 2px; - border-radius: 4px; -} - -.task-board-category:hover { - opacity: 0.6; -} - -/* tags list */ -.task-tags li { - display: inline; - margin: 0; - margin-right: 4px; - padding: 2px; - color: #666; - border: 1px solid #666; - border-radius: 2px; -} - -.task-summary-container .task-tags { - margin-top: 10px; -} - -/* avatars on the card */ -.task-board-avatars { - text-align: right; - float: right; -} - -.task-board-change-assignee:hover { - opacity: 0.6; -} - -.task-board-change-assignee { - cursor: pointer; -} - -/* task icons footer */ -.task-board-icons { - text-align: right; - margin-top: 4px; - margin-bottom: 2px; -} - -.task-board-icons a { - opacity: 0.5; -} - -.task-board-icons span { - opacity: 0.5; - margin-left: 2px; -} - -.task-board-icons a:hover, -.task-board-icons span:hover { - opacity: 1.0; -} - -.task-board-date { - font-weight: bold; - color: #000; -} - -span.task-board-date-today { - color: #0000D9; - opacity: 1.0; -} - -span.task-board-date-overdue { - color: #D90000; - opacity: 1.0; -} - -/* task score */ -.task-board .task-score { - font-weight: bold; -} - -/* task age */ -.task-board-age { - display: inline-block; - font-size: 0.9em; -} - -span.task-board-age-total { - border: #666 1px solid; - padding: 1px 3px 1px 3px; - border-top-left-radius: 3px; - border-bottom-left-radius: 3px; -} - -span.task-board-age-column { - border: #666 1px solid; - border-left: none; - margin-left: -5px; - padding: 1px 3px 1px 3px; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -/* task summary */ -#task-summary { - margin-bottom: 15px; -} - -#task-summary h2 { - color: #666; - font-size: 2.5em; - margin-top: 0; - padding-top: 0; -} - -.task-summary-buttons { - margin-top: 10px; - font-size: 0.85em; -} - -.task-summary-container { - border: 2px solid #000; - border-radius: 8px; - padding: 15px; -} - -.task-summary-columns { - display: -webkit-flex; - display: flex; - -webkit-flex-direction: row; - flex-direction: row; - -webkit-justify-content: space-between; - justify-content: space-between; -} - -.task-summary-column { - font-size: 0.9em; - color: #666; -} - -.task-summary-column span { - color: #555; -} - -.task-summary-column li { - line-height: 23px; -} - -.task-show-title { - border: 2px solid #000; - border-radius: 8px; - margin-bottom: 20px; -} - -.task-show-title h2 { - color: #555; - font-size: 1.8em; - margin: 0; - padding: 8px; -} - -.task-link-closed { - text-decoration: line-through; -} - -.flag-milestone { - color: green; -} - -/* color picker */ -.color-picker { - width: 180px; -} - -.color-picker-option { - height: 25px; -} - -.color-picker-square { - display: inline-block; - width: 18px; - height: 18px; - margin-right: 5px; - border: 1px solid #000; -} - -.color-picker-label { - display: inline-block; - vertical-align: bottom; - padding-bottom: 3px; -} - -#select2-form-color_id-results li.select2-results__option { - padding: 3px; -} - -/* Assign to me */ -.assign-me { - font-size: 0.8em; - vertical-align: bottom; -} diff --git a/sources/assets/css/src/tasklink.css b/sources/assets/css/src/tasklink.css deleted file mode 100644 index 826792c..0000000 --- a/sources/assets/css/src/tasklink.css +++ /dev/null @@ -1,12 +0,0 @@ -/* tasklinks */ -.task-links-table { - font-size: 0.85em; -} - -.task-links-table td { - vertical-align: middle; -} - -.task-links-task-count { - color: #999; -} diff --git a/sources/assets/css/src/title.css b/sources/assets/css/src/title.css deleted file mode 100644 index 980d78e..0000000 --- a/sources/assets/css/src/title.css +++ /dev/null @@ -1,15 +0,0 @@ -/* titles */ -h1, h2, h3 { - font-weight: normal; - color: #333; -} - -h2 { - font-size: 1.3em; - margin-bottom: 10px; -} - -h3 { - margin-top: 10px; - font-size: 1.2em; -} \ No newline at end of file diff --git a/sources/assets/css/src/tooltip.css b/sources/assets/css/src/tooltip.css deleted file mode 100644 index 8b6551f..0000000 --- a/sources/assets/css/src/tooltip.css +++ /dev/null @@ -1,78 +0,0 @@ -/* tooltip */ -.tooltip-arrow:after { - background: #fff; - border: 1px solid #aaaaaa; - box-shadow: 0 0 5px #aaa; -} - -div.ui-tooltip { - min-width: 200px; - max-width: 600px; - font-size: 0.85em; -} - -.tooltip-arrow { - width: 20px; - height: 10px; - overflow: hidden; - position: absolute; -} - -.tooltip-arrow.top { - top: -10px; -} - -.tooltip-arrow.bottom { - bottom: -10px; -} - -.tooltip-arrow.align-left { - left: 10px; -} - -.tooltip-arrow.align-right { - right: 10px; -} - -.tooltip-arrow:after { - content: ""; - position: absolute; - width: 14px; - height: 14px; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} - -.tooltip-arrow.bottom:after { - top: -10px; -} - -.tooltip-arrow.top:after { - bottom: -10px; -} - -.tooltip-arrow.align-left:after { - left: 0px; -} - -.tooltip-arrow.align-right:after { - right: 0px; -} - -.tooltip-large { - width: 600px; -} - -.ui-tooltip-content .markdown p { - margin-bottom: 0px; -} - -.ui-tooltip li { - list-style-type: none; -} - -.tooltip .fa-info-circle { - color: #999; - font-size: 0.95em; -} diff --git a/sources/assets/css/src/upload.css b/sources/assets/css/src/upload.css deleted file mode 100644 index aa46bc7..0000000 --- a/sources/assets/css/src/upload.css +++ /dev/null @@ -1,39 +0,0 @@ -#file-dropzone, -#screenshot-zone { - position: relative; - border: 2px dashed #ccc; - width: 99%; - height: 250px; - overflow: auto; -} - -#file-dropzone-inner, -#screenshot-inner { - position: absolute; - left: 0; - bottom: 48%; - width: 100%; - text-align: center; - color: #aaa; -} - -#screenshot-zone.screenshot-pasted { - border: 2px solid #333; -} - -#file-list { - margin: 20px; -} - -#file-list li { - list-style-type: none; - padding-top: 8px; - padding-bottom: 8px; - border-bottom: 1px dotted #ddd; - width: 95%; -} - -#file-list li.file-error { - font-weight: bold; - color: #b94a48; -} diff --git a/sources/assets/css/src/views.css b/sources/assets/css/src/views.css deleted file mode 100644 index d923c23..0000000 --- a/sources/assets/css/src/views.css +++ /dev/null @@ -1,46 +0,0 @@ -.views { - display: inline-block; - margin-left: 10px; - margin-right: 10px; - font-size: 0.9em; -} - -.views li { - background: #fafafa; - border-left: 1px solid #ddd; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - padding-left: 8px; - padding-right: 8px; - padding-top: 5px; - padding-bottom: 5px; - display: inline; -} - -.views a { - color: #555; - text-decoration: none; -} - -.views a:hover { - color: #333; - text-decoration: underline; -} - -.menu-inline li.active a, -.views li.active a { - font-weight: bold; - color: #000; - text-decoration: none; -} - -.views li:first-child { - border-top-left-radius: 5px; - border-bottom-left-radius: 5px; -} - -.views li:last-child { - border-right: 1px solid #ddd; - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; -} diff --git a/sources/assets/css/vendor.min.css b/sources/assets/css/vendor.min.css deleted file mode 100644 index 9d81051..0000000 --- a/sources/assets/css/vendor.min.css +++ /dev/null @@ -1,481 +0,0 @@ -/*! jQuery UI - v1.11.3 - 2015-02-12 -* http://jqueryui.com -* Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#2b2b2b;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:0 0 0 0;padding:5px;background:#666;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px} -/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20 -* http://trentrichardson.com/examples/timepicker -* Copyright (c) 2016 Trent Richardson; Licensed MIT */ - -.ui-timepicker-div .ui-widget-header{margin-bottom:8px}.ui-timepicker-div dl{text-align:left}.ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.ui-timepicker-div dl dd{margin:0 10px 10px 40%}.ui-timepicker-div td{font-size:90%}.ui-tpicker-grid-label{background:0 0;border:0;margin:0;padding:0}.ui-timepicker-div .ui_tpicker_unit_hide{display:none}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input{background:0 0;color:inherit;border:0;outline:0;border-bottom:solid 1px #555;width:95%}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus{border-bottom-color:#aaa}.ui-timepicker-rtl{direction:rtl}.ui-timepicker-rtl dl{text-align:right;padding:0 5px 0 0}.ui-timepicker-rtl dl dt{float:right;clear:right}.ui-timepicker-rtl dl dd{margin:0 40% 10px 10px}.ui-timepicker-div.ui-timepicker-oneLine{padding-right:2px}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,.ui-timepicker-div.ui-timepicker-oneLine dt{display:none}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label{display:block;padding-top:2px}.ui-timepicker-div.ui-timepicker-oneLine dl{text-align:right}.ui-timepicker-div.ui-timepicker-oneLine dl dd,.ui-timepicker-div.ui-timepicker-oneLine dl dd>div{display:inline-block;margin:0}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before{content:':';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before{content:'.';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{display:none} -/*! -Chosen, a Select Box Enhancer for jQuery and Prototype -by Patrick Filler for Harvest, http://getharvest.com - -Version 1.5.0 -Full source at https://github.com/harvesthq/chosen -Copyright (c) 2011-2016 Harvest http://getharvest.com - -MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md -This file is generated by `grunt build`, do not edit it by hand. -*/ - -/* @group Base */ -.chosen-container { - position: relative; - display: inline-block; - vertical-align: middle; - font-size: 13px; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -} -.chosen-container * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.chosen-container .chosen-drop { - position: absolute; - top: 100%; - left: -9999px; - z-index: 1010; - width: 100%; - border: 1px solid #aaa; - border-top: 0; - background: #fff; - box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -} -.chosen-container.chosen-with-drop .chosen-drop { - left: 0; -} -.chosen-container a { - cursor: pointer; -} -.chosen-container .search-choice .group-name, .chosen-container .chosen-single .group-name { - margin-right: 4px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - font-weight: normal; - color: #999999; -} -.chosen-container .search-choice .group-name:after, .chosen-container .chosen-single .group-name:after { - content: ":"; - padding-left: 2px; - vertical-align: top; -} - -/* @end */ -/* @group Single Chosen */ -.chosen-container-single .chosen-single { - position: relative; - display: block; - overflow: hidden; - padding: 0 0 0 8px; - height: 25px; - border: 1px solid #aaa; - border-radius: 5px; - background-color: #fff; - background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4)); - background: -webkit-linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); - background: -moz-linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); - background: -o-linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); - background: linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); - background-clip: padding-box; - box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1); - color: #444; - text-decoration: none; - white-space: nowrap; - line-height: 24px; -} -.chosen-container-single .chosen-default { - color: #999; -} -.chosen-container-single .chosen-single span { - display: block; - overflow: hidden; - margin-right: 26px; - text-overflow: ellipsis; - white-space: nowrap; -} -.chosen-container-single .chosen-single-with-deselect span { - margin-right: 38px; -} -.chosen-container-single .chosen-single abbr { - position: absolute; - top: 6px; - right: 26px; - display: block; - width: 12px; - height: 12px; - background: url('chosen-sprite.png') -42px 1px no-repeat; - font-size: 1px; -} -.chosen-container-single .chosen-single abbr:hover { - background-position: -42px -10px; -} -.chosen-container-single.chosen-disabled .chosen-single abbr:hover { - background-position: -42px -10px; -} -.chosen-container-single .chosen-single div { - position: absolute; - top: 0; - right: 0; - display: block; - width: 18px; - height: 100%; -} -.chosen-container-single .chosen-single div b { - display: block; - width: 100%; - height: 100%; - background: url('chosen-sprite.png') no-repeat 0px 2px; -} -.chosen-container-single .chosen-search { - position: relative; - z-index: 1010; - margin: 0; - padding: 3px 4px; - white-space: nowrap; -} -.chosen-container-single .chosen-search input[type="text"] { - margin: 1px 0; - padding: 4px 20px 4px 5px; - width: 100%; - height: auto; - outline: 0; - border: 1px solid #aaa; - background: white url('chosen-sprite.png') no-repeat 100% -20px; - background: url('chosen-sprite.png') no-repeat 100% -20px; - font-size: 1em; - font-family: sans-serif; - line-height: normal; - border-radius: 0; -} -.chosen-container-single .chosen-drop { - margin-top: -1px; - border-radius: 0 0 4px 4px; - background-clip: padding-box; -} -.chosen-container-single.chosen-container-single-nosearch .chosen-search { - position: absolute; - left: -9999px; -} - -/* @end */ -/* @group Results */ -.chosen-container .chosen-results { - color: #444; - position: relative; - overflow-x: hidden; - overflow-y: auto; - margin: 0 4px 4px 0; - padding: 0 0 0 4px; - max-height: 240px; - -webkit-overflow-scrolling: touch; -} -.chosen-container .chosen-results li { - display: none; - margin: 0; - padding: 5px 6px; - list-style: none; - line-height: 15px; - word-wrap: break-word; - -webkit-touch-callout: none; -} -.chosen-container .chosen-results li.active-result { - display: list-item; - cursor: pointer; -} -.chosen-container .chosen-results li.disabled-result { - display: list-item; - color: #ccc; - cursor: default; -} -.chosen-container .chosen-results li.highlighted { - background-color: #3875d7; - background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc)); - background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%); - background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%); - background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%); - background-image: linear-gradient(#3875d7 20%, #2a62bc 90%); - color: #fff; -} -.chosen-container .chosen-results li.no-results { - color: #777; - display: list-item; - background: #f4f4f4; -} -.chosen-container .chosen-results li.group-result { - display: list-item; - font-weight: bold; - cursor: default; -} -.chosen-container .chosen-results li.group-option { - padding-left: 15px; -} -.chosen-container .chosen-results li em { - font-style: normal; - text-decoration: underline; -} - -/* @end */ -/* @group Multi Chosen */ -.chosen-container-multi .chosen-choices { - position: relative; - overflow: hidden; - margin: 0; - padding: 0 5px; - width: 100%; - height: auto !important; - height: 1%; - border: 1px solid #aaa; - background-color: #fff; - background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); - background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%); - background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%); - background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%); - background-image: linear-gradient(#eeeeee 1%, #ffffff 15%); - cursor: text; -} -.chosen-container-multi .chosen-choices li { - float: left; - list-style: none; -} -.chosen-container-multi .chosen-choices li.search-field { - margin: 0; - padding: 0; - white-space: nowrap; -} -.chosen-container-multi .chosen-choices li.search-field input[type="text"] { - margin: 1px 0; - padding: 0; - height: 25px; - outline: 0; - border: 0 !important; - background: transparent !important; - box-shadow: none; - color: #999; - font-size: 100%; - font-family: sans-serif; - line-height: normal; - border-radius: 0; -} -.chosen-container-multi .chosen-choices li.search-choice { - position: relative; - margin: 3px 5px 3px 0; - padding: 3px 20px 3px 5px; - border: 1px solid #aaa; - max-width: 100%; - border-radius: 3px; - background-color: #eeeeee; - background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); - background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-size: 100% 19px; - background-repeat: repeat-x; - background-clip: padding-box; - box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05); - color: #333; - line-height: 13px; - cursor: default; -} -.chosen-container-multi .chosen-choices li.search-choice span { - word-wrap: break-word; -} -.chosen-container-multi .chosen-choices li.search-choice .search-choice-close { - position: absolute; - top: 4px; - right: 3px; - display: block; - width: 12px; - height: 12px; - background: url('chosen-sprite.png') -42px 1px no-repeat; - font-size: 1px; -} -.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover { - background-position: -42px -10px; -} -.chosen-container-multi .chosen-choices li.search-choice-disabled { - padding-right: 5px; - border: 1px solid #ccc; - background-color: #e4e4e4; - background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); - background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); - color: #666; -} -.chosen-container-multi .chosen-choices li.search-choice-focus { - background: #d4d4d4; -} -.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close { - background-position: -42px -10px; -} -.chosen-container-multi .chosen-results { - margin: 0; - padding: 0; -} -.chosen-container-multi .chosen-drop .result-selected { - display: list-item; - color: #ccc; - cursor: default; -} - -/* @end */ -/* @group Active */ -.chosen-container-active .chosen-single { - border: 1px solid #5897fb; - box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); -} -.chosen-container-active.chosen-with-drop .chosen-single { - border: 1px solid #aaa; - -moz-border-radius-bottomright: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomleft: 0; - border-bottom-left-radius: 0; - background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff)); - background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%); - background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%); - background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%); - background-image: linear-gradient(#eeeeee 20%, #ffffff 80%); - box-shadow: 0 1px 0 #fff inset; -} -.chosen-container-active.chosen-with-drop .chosen-single div { - border-left: none; - background: transparent; -} -.chosen-container-active.chosen-with-drop .chosen-single div b { - background-position: -18px 2px; -} -.chosen-container-active .chosen-choices { - border: 1px solid #5897fb; - box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); -} -.chosen-container-active .chosen-choices li.search-field input[type="text"] { - color: #222 !important; -} - -/* @end */ -/* @group Disabled Support */ -.chosen-disabled { - opacity: 0.5 !important; - cursor: default; -} -.chosen-disabled .chosen-single { - cursor: default; -} -.chosen-disabled .chosen-choices .search-choice .search-choice-close { - cursor: default; -} - -/* @end */ -/* @group Right to Left */ -.chosen-rtl { - text-align: right; -} -.chosen-rtl .chosen-single { - overflow: visible; - padding: 0 8px 0 0; -} -.chosen-rtl .chosen-single span { - margin-right: 0; - margin-left: 26px; - direction: rtl; -} -.chosen-rtl .chosen-single-with-deselect span { - margin-left: 38px; -} -.chosen-rtl .chosen-single div { - right: auto; - left: 3px; -} -.chosen-rtl .chosen-single abbr { - right: auto; - left: 26px; -} -.chosen-rtl .chosen-choices li { - float: right; -} -.chosen-rtl .chosen-choices li.search-field input[type="text"] { - direction: rtl; -} -.chosen-rtl .chosen-choices li.search-choice { - margin: 3px 5px 3px 0; - padding: 3px 5px 3px 19px; -} -.chosen-rtl .chosen-choices li.search-choice .search-choice-close { - right: auto; - left: 4px; -} -.chosen-rtl.chosen-container-single-nosearch .chosen-search, -.chosen-rtl .chosen-drop { - left: 9999px; -} -.chosen-rtl.chosen-container-single .chosen-results { - margin: 0 0 4px 4px; - padding: 0 4px 0 0; -} -.chosen-rtl .chosen-results li.group-option { - padding-right: 15px; - padding-left: 0; -} -.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div { - border-right: none; -} -.chosen-rtl .chosen-search input[type="text"] { - padding: 4px 5px 4px 20px; - background: white url('chosen-sprite.png') no-repeat -30px -20px; - background: url('chosen-sprite.png') no-repeat -30px -20px; - direction: rtl; -} -.chosen-rtl.chosen-container-single .chosen-single div b { - background-position: 6px 2px; -} -.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b { - background-position: -12px 2px; -} - -/* @end */ -/* @group Retina compatibility */ -@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi), only screen and (min-resolution: 1.5dppx) { - .chosen-rtl .chosen-search input[type="text"], - .chosen-container-single .chosen-single abbr, - .chosen-container-single .chosen-single div b, - .chosen-container-single .chosen-search input[type="text"], - .chosen-container-multi .chosen-choices .search-choice .search-choice-close, - .chosen-container .chosen-results-scroll-down span, - .chosen-container .chosen-results-scroll-up span { - background-image: url('chosen-sprite@2x.png') !important; - background-size: 52px 37px !important; - background-repeat: no-repeat !important; - } -} -/* @end */ - -.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} - -/*! - * FullCalendar v2.7.1 Stylesheet - * Docs & License: http://fullcalendar.io/ - * (c) 2016 Adam Shaw - */.fc-bgevent,.fc-highlight{opacity:.3;filter:alpha(opacity=30)}.fc-icon,body .fc{font-size:1em}.fc-button-group,.fc-icon{display:inline-block}.fc-bg,.fc-row .fc-bgevent-skeleton,.fc-row .fc-highlight-skeleton{bottom:0}.fc-icon,.fc-unselectable{-khtml-user-select:none;-webkit-touch-callout:none}.fc .fc-axis,.fc button,.fc-time-grid-event .fc-time,.fc-time-grid-event.fc-short .fc-content{white-space:nowrap}.fc{direction:ltr;text-align:left}.fc-rtl{text-align:right}.fc th,.fc-basic-view .fc-week-number,.fc-icon,.fc-toolbar{text-align:center}.fc-unthemed .fc-content,.fc-unthemed .fc-divider,.fc-unthemed .fc-popover,.fc-unthemed .fc-row,.fc-unthemed tbody,.fc-unthemed td,.fc-unthemed th,.fc-unthemed thead{border-color:#ddd}.fc-unthemed .fc-popover{background-color:#fff}.fc-unthemed .fc-divider,.fc-unthemed .fc-popover .fc-header{background:#eee}.fc-unthemed .fc-popover .fc-header .fc-close{color:#666}.fc-unthemed .fc-today{background:#fcf8e3}.fc-highlight{background:#bce8f1}.fc-bgevent{background:#8fdf82}.fc-nonbusiness{background:#d7d7d7}.fc-icon{height:1em;line-height:1em;overflow:hidden;font-family:"Courier New",Courier,monospace;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fc-icon:after{position:relative}.fc-icon-left-single-arrow:after{content:"\02039";font-weight:700;font-size:200%;top:-7%}.fc-icon-right-single-arrow:after{content:"\0203A";font-weight:700;font-size:200%;top:-7%}.fc-icon-left-double-arrow:after{content:"\000AB";font-size:160%;top:-7%}.fc-icon-right-double-arrow:after{content:"\000BB";font-size:160%;top:-7%}.fc-icon-left-triangle:after{content:"\25C4";font-size:125%;top:3%}.fc-icon-right-triangle:after{content:"\25BA";font-size:125%;top:3%}.fc-icon-down-triangle:after{content:"\25BC";font-size:125%;top:2%}.fc-icon-x:after{content:"\000D7";font-size:200%;top:6%}.fc button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;height:2.1em;padding:0 .6em;font-size:1em;cursor:pointer}.fc button::-moz-focus-inner{margin:0;padding:0}.fc-state-default{border:1px solid;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);color:#333;text-shadow:0 1px 1px rgba(255,255,255,.75);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05)}.fc-state-default.fc-corner-left{border-top-left-radius:4px;border-bottom-left-radius:4px}.fc-state-default.fc-corner-right{border-top-right-radius:4px;border-bottom-right-radius:4px}.fc button .fc-icon{position:relative;top:-.05em;margin:0 .2em;vertical-align:middle}.fc-state-active,.fc-state-disabled,.fc-state-down,.fc-state-hover{color:#333;background-color:#e6e6e6}.fc-state-hover{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.fc-state-active,.fc-state-down{background-color:#ccc;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.fc-state-disabled{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);box-shadow:none}.fc-event.fc-draggable,.fc-event[href],.fc-popover .fc-header .fc-close{cursor:pointer}.fc .fc-button-group>*{float:left;margin:0 0 0 -1px}.fc .fc-button-group>:first-child{margin-left:0}.fc-popover{position:absolute;box-shadow:0 2px 6px rgba(0,0,0,.15)}.fc-popover .fc-header{padding:2px 4px}.fc-popover .fc-header .fc-title{margin:0 2px}.fc-ltr .fc-popover .fc-header .fc-title,.fc-rtl .fc-popover .fc-header .fc-close{float:left}.fc-ltr .fc-popover .fc-header .fc-close,.fc-rtl .fc-popover .fc-header .fc-title{float:right}.fc-unthemed .fc-popover{border-width:1px;border-style:solid}.fc-unthemed .fc-popover .fc-header .fc-close{font-size:.9em;margin-top:2px}.fc-popover>.ui-widget-header+.ui-widget-content{border-top:0}.fc-divider{border-style:solid;border-width:1px}hr.fc-divider{height:0;margin:0;padding:0 0 2px;border-width:1px 0}.fc-bg table,.fc-row .fc-bgevent-skeleton table,.fc-row .fc-highlight-skeleton table{height:100%}.fc-clear{clear:both}.fc-bg,.fc-bgevent-skeleton,.fc-helper-skeleton,.fc-highlight-skeleton{position:absolute;top:0;left:0;right:0}.fc table{width:100%;table-layout:fixed;border-collapse:collapse;border-spacing:0;font-size:1em}.fc td,.fc th{border-style:solid;border-width:1px;padding:0;vertical-align:top}.fc td.fc-today{border-style:double}.fc .fc-row{border-style:solid;border-width:0}.fc-row table{border-left:0 hidden transparent;border-right:0 hidden transparent;border-bottom:0 hidden transparent}.fc-row:first-child table{border-top:0 hidden transparent}.fc-row{position:relative}.fc-row .fc-bg{z-index:1}.fc-row .fc-bgevent-skeleton td,.fc-row .fc-highlight-skeleton td{border-color:transparent}.fc-row .fc-bgevent-skeleton{z-index:2}.fc-row .fc-highlight-skeleton{z-index:3}.fc-row .fc-content-skeleton{position:relative;z-index:4;padding-bottom:2px}.fc-row .fc-helper-skeleton{z-index:5}.fc-row .fc-content-skeleton td,.fc-row .fc-helper-skeleton td{background:0 0;border-color:transparent;border-bottom:0}.fc-row .fc-content-skeleton tbody td,.fc-row .fc-helper-skeleton tbody td{border-top:0}.fc-scroller{-webkit-overflow-scrolling:touch}.fc-row.fc-rigid,.fc-time-grid-event{overflow:hidden}.fc-scroller>.fc-day-grid,.fc-scroller>.fc-time-grid{position:relative;width:100%}.fc-event{position:relative;display:block;font-size:.85em;line-height:1.3;border-radius:3px;border:1px solid #3a87ad;background-color:#3a87ad;font-weight:400}.fc-event,.fc-event:hover,.ui-widget .fc-event{color:#fff;text-decoration:none}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc-event .fc-bg{z-index:1;background:#fff;opacity:.25;filter:alpha(opacity=25)}.fc-event .fc-content{position:relative;z-index:2}.fc-event .fc-resizer{position:absolute;z-index:4}.fc-touch .fc-event .fc-resizer{display:none}.fc-touch .fc-event.fc-selected .fc-resizer{display:block}.fc-expander{position:relative}.fc-touch .fc-event .fc-resizer:before,.fc-touch .fc-expander:before{content:"";position:absolute;z-index:9999;top:50%;left:50%;width:40px;height:40px;margin-left:-20px;margin-top:-20px}.fc-event.fc-selected{z-index:9999!important;box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event.fc-selected.fc-dragging{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-h-event.fc-selected:before{content:"";position:absolute;z-index:3;top:-10px;bottom:-10px;left:0;right:0}.fc-ltr .fc-h-event.fc-not-start,.fc-rtl .fc-h-event.fc-not-end{margin-left:0;border-left-width:0;padding-left:1px;border-top-left-radius:0;border-bottom-left-radius:0}.fc-ltr .fc-h-event.fc-not-end,.fc-rtl .fc-h-event.fc-not-start{margin-right:0;border-right-width:0;padding-right:1px;border-top-right-radius:0;border-bottom-right-radius:0}.fc-ltr .fc-h-event .fc-start-resizer,.fc-rtl .fc-h-event .fc-end-resizer{cursor:w-resize;left:-1px}.fc-ltr .fc-h-event .fc-end-resizer,.fc-rtl .fc-h-event .fc-start-resizer{cursor:e-resize;right:-1px}.fc-cursor .fc-h-event .fc-resizer{width:7px;top:-1px;bottom:-1px}.fc-touch .fc-h-event .fc-resizer{border-radius:4px;border-width:1px;width:6px;height:6px;border-style:solid;border-color:inherit;background:#fff;top:50%;margin-top:-4px}.fc-touch.fc-ltr .fc-h-event .fc-start-resizer,.fc-touch.fc-rtl .fc-h-event .fc-end-resizer{margin-left:-4px}.fc-touch.fc-ltr .fc-h-event .fc-end-resizer,.fc-touch.fc-rtl .fc-h-event .fc-start-resizer{margin-right:-4px}.fc-day-grid-event{margin:1px 2px 0;padding:0 1px}.fc-day-grid-event.fc-selected:after{content:"";position:absolute;z-index:1;top:-1px;right:-1px;bottom:-1px;left:-1px;background:#000;opacity:.25;filter:alpha(opacity=25)}.fc-day-grid-event .fc-content{white-space:nowrap;overflow:hidden}.fc-day-grid-event .fc-time{font-weight:700}.fc-cursor.fc-ltr .fc-day-grid-event .fc-start-resizer,.fc-cursor.fc-rtl .fc-day-grid-event .fc-end-resizer{margin-left:-2px}.fc-cursor.fc-ltr .fc-day-grid-event .fc-end-resizer,.fc-cursor.fc-rtl .fc-day-grid-event .fc-start-resizer{margin-right:-2px}a.fc-more{margin:1px 3px;font-size:.85em;cursor:pointer;text-decoration:none}a.fc-more:hover{text-decoration:underline}.fc-limited{display:none}.fc-day-grid .fc-row{z-index:1}.fc-more-popover{z-index:2;width:220px}.fc-more-popover .fc-event-container{padding:10px}.fc-now-indicator{position:absolute;border:0 solid red}.fc-unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fc-toolbar{margin-bottom:1em}.fc-toolbar .fc-left{float:left}.fc-toolbar .fc-right{float:right}.fc-toolbar .fc-center{display:inline-block}.fc .fc-toolbar>*>*{float:left;margin-left:.75em}.fc .fc-toolbar>*>:first-child{margin-left:0}.fc-toolbar h2{margin:0}.fc-toolbar button{position:relative}.fc-toolbar .fc-state-hover,.fc-toolbar .ui-state-hover{z-index:2}.fc-toolbar .fc-state-down{z-index:3}.fc-toolbar .fc-state-active,.fc-toolbar .ui-state-active{z-index:4}.fc-toolbar button:focus{z-index:5}.fc-view-container *,.fc-view-container :after,.fc-view-container :before{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.fc-view,.fc-view>table{position:relative;z-index:1}.fc-basicDay-view .fc-content-skeleton,.fc-basicWeek-view .fc-content-skeleton{padding-top:1px;padding-bottom:1em}.fc-basic-view .fc-body .fc-row{min-height:4em}.fc-row.fc-rigid .fc-content-skeleton{position:absolute;top:0;left:0;right:0}.fc-basic-view .fc-day-number,.fc-basic-view .fc-week-number{padding:0 2px}.fc-basic-view td.fc-day-number,.fc-basic-view td.fc-week-number span{padding-top:2px;padding-bottom:2px}.fc-basic-view .fc-week-number span{display:inline-block;min-width:1.25em}.fc-ltr .fc-basic-view .fc-day-number{text-align:right}.fc-rtl .fc-basic-view .fc-day-number{text-align:left}.fc-day-number.fc-other-month{opacity:.3;filter:alpha(opacity=30)}.fc-agenda-view .fc-day-grid{position:relative;z-index:2}.fc-agenda-view .fc-day-grid .fc-row{min-height:3em}.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton{padding-top:1px;padding-bottom:1em}.fc .fc-axis{vertical-align:middle;padding:0 4px}.fc-ltr .fc-axis{text-align:right}.fc-rtl .fc-axis{text-align:left}.ui-widget td.fc-axis{font-weight:400}.fc-time-grid,.fc-time-grid-container{position:relative;z-index:1}.fc-time-grid{min-height:100%}.fc-time-grid table{border:0 hidden transparent}.fc-time-grid>.fc-bg{z-index:1}.fc-time-grid .fc-slats,.fc-time-grid>hr{position:relative;z-index:2}.fc-time-grid .fc-content-col{position:relative}.fc-time-grid .fc-content-skeleton{position:absolute;z-index:3;top:0;left:0;right:0}.fc-time-grid .fc-business-container{position:relative;z-index:1}.fc-time-grid .fc-bgevent-container{position:relative;z-index:2}.fc-time-grid .fc-highlight-container{z-index:3;position:relative}.fc-time-grid .fc-event-container{position:relative;z-index:4}.fc-time-grid .fc-now-indicator-line{z-index:5}.fc-time-grid .fc-helper-container{position:relative;z-index:6}.fc-time-grid .fc-slats td{height:1.5em;border-bottom:0}.fc-time-grid .fc-slats .fc-minor td{border-top-style:dotted}.fc-time-grid .fc-slats .ui-widget-content{background:0 0}.fc-time-grid .fc-highlight{position:absolute;left:0;right:0}.fc-ltr .fc-time-grid .fc-event-container{margin:0 2.5% 0 2px}.fc-rtl .fc-time-grid .fc-event-container{margin:0 2px 0 2.5%}.fc-time-grid .fc-bgevent,.fc-time-grid .fc-event{position:absolute;z-index:1}.fc-time-grid .fc-bgevent{left:0;right:0}.fc-v-event.fc-not-start{border-top-width:0;padding-top:1px;border-top-left-radius:0;border-top-right-radius:0}.fc-v-event.fc-not-end{border-bottom-width:0;padding-bottom:1px;border-bottom-left-radius:0;border-bottom-right-radius:0}.fc-time-grid-event.fc-selected{overflow:visible}.fc-time-grid-event.fc-selected .fc-bg{display:none}.fc-time-grid-event .fc-content{overflow:hidden}.fc-time-grid-event .fc-time,.fc-time-grid-event .fc-title{padding:0 1px}.fc-time-grid-event .fc-time{font-size:.85em}.fc-time-grid-event.fc-short .fc-time,.fc-time-grid-event.fc-short .fc-title{display:inline-block;vertical-align:top}.fc-time-grid-event.fc-short .fc-time span{display:none}.fc-time-grid-event.fc-short .fc-time:before{content:attr(data-start)}.fc-time-grid-event.fc-short .fc-time:after{content:"\000A0-\000A0"}.fc-time-grid-event.fc-short .fc-title{font-size:.85em;padding:0}.fc-cursor .fc-time-grid-event .fc-resizer{left:0;right:0;bottom:0;height:8px;overflow:hidden;line-height:8px;font-size:11px;font-family:monospace;text-align:center;cursor:s-resize}.fc-cursor .fc-time-grid-event .fc-resizer:after{content:"="}.fc-touch .fc-time-grid-event .fc-resizer{border-radius:5px;border-width:1px;width:8px;height:8px;border-style:solid;border-color:inherit;background:#fff;left:50%;margin-left:-5px;bottom:-5px}.fc-time-grid .fc-now-indicator-line{border-top-width:1px;left:0;right:0}.fc-time-grid .fc-now-indicator-arrow{margin-top:-5px}.fc-ltr .fc-time-grid .fc-now-indicator-arrow{left:0;border-width:5px 0 5px 6px;border-top-color:transparent;border-bottom-color:transparent}.fc-rtl .fc-time-grid .fc-now-indicator-arrow{right:0;border-width:5px 6px 5px 0;border-top-color:transparent;border-bottom-color:transparent} -/** - * simplemde v1.10.1 - * Copyright Next Step Webs, Inc. - * @link https://github.com/NextStepWebs/simplemde-markdown-editor - * @license MIT - */ -.CodeMirror{color:#000}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-invalidchar,.cm-s-default .cm-error{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:#fff}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:0 0!important;border:none!important;-webkit-user-select:none;-moz-user-select:none;user-select:none}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror,.CodeMirror-scroll{min-height:300px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-code{outline:0}.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber,.CodeMirror-scroll,.CodeMirror-sizer{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.CodeMirror-focused div.CodeMirror-cursors,div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected,.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0 0}.CodeMirror{height:auto;border:1px solid #ddd;border-bottom-left-radius:4px;border-bottom-right-radius:4px;padding:10px;font:inherit;z-index:1}.CodeMirror-fullscreen{background:#fff;position:fixed!important;top:50px;left:0;right:0;bottom:0;height:auto;z-index:9}.CodeMirror-sided{width:50%!important}.editor-toolbar{position:relative;opacity:.6;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;padding:0 10px;border-top:1px solid #bbb;border-left:1px solid #bbb;border-right:1px solid #bbb;border-top-left-radius:4px;border-top-right-radius:4px}.editor-toolbar:after,.editor-toolbar:before{display:block;content:' ';height:1px}.editor-toolbar:before{margin-bottom:8px}.editor-toolbar:after{margin-top:8px}.editor-toolbar:hover,.editor-wrapper input.title:focus,.editor-wrapper input.title:hover{opacity:.8}.editor-toolbar.fullscreen{width:100%;height:50px;overflow-x:auto;overflow-y:hidden;white-space:nowrap;padding-top:10px;padding-bottom:10px;box-sizing:border-box;background:#fff;border:0;position:fixed;top:0;left:0;opacity:1;z-index:9}.editor-toolbar.fullscreen::before{width:20px;height:50px;background:-moz-linear-gradient(left,rgba(255,255,255,1) 0,rgba(255,255,255,0) 100%);background:-webkit-gradient(linear,left top,right top,color-stop(0,rgba(255,255,255,1)),color-stop(100%,rgba(255,255,255,0)));background:-webkit-linear-gradient(left,rgba(255,255,255,1) 0,rgba(255,255,255,0) 100%);background:-o-linear-gradient(left,rgba(255,255,255,1) 0,rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left,rgba(255,255,255,1) 0,rgba(255,255,255,0) 100%);background:linear-gradient(to right,rgba(255,255,255,1) 0,rgba(255,255,255,0) 100%);position:fixed;top:0;left:0;margin:0;padding:0}.editor-toolbar.fullscreen::after{width:20px;height:50px;background:-moz-linear-gradient(left,rgba(255,255,255,0) 0,rgba(255,255,255,1) 100%);background:-webkit-gradient(linear,left top,right top,color-stop(0,rgba(255,255,255,0)),color-stop(100%,rgba(255,255,255,1)));background:-webkit-linear-gradient(left,rgba(255,255,255,0) 0,rgba(255,255,255,1) 100%);background:-o-linear-gradient(left,rgba(255,255,255,0) 0,rgba(255,255,255,1) 100%);background:-ms-linear-gradient(left,rgba(255,255,255,0) 0,rgba(255,255,255,1) 100%);background:linear-gradient(to right,rgba(255,255,255,0) 0,rgba(255,255,255,1) 100%);position:fixed;top:0;right:0;margin:0;padding:0}.editor-toolbar a{display:inline-block;text-align:center;text-decoration:none!important;color:#2c3e50!important;width:30px;height:30px;margin:0;border:1px solid transparent;border-radius:3px;cursor:pointer}.editor-toolbar a.active,.editor-toolbar a:hover{background:#fcfcfc;border-color:#95a5a6}.editor-toolbar a:before{line-height:30px}.editor-toolbar i.separator{display:inline-block;width:0;border-left:1px solid #d9d9d9;border-right:1px solid #fff;color:transparent;text-indent:-10px;margin:0 6px}.editor-toolbar a.fa-header-x:after{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;font-size:65%;vertical-align:text-bottom;position:relative;top:2px}.editor-toolbar a.fa-header-1:after{content:"1"}.editor-toolbar a.fa-header-2:after{content:"2"}.editor-toolbar a.fa-header-3:after{content:"3"}.editor-toolbar a.fa-header-bigger:after{content:"▲"}.editor-toolbar a.fa-header-smaller:after{content:"▼"}.editor-toolbar.disabled-for-preview a:not(.no-disable){pointer-events:none;background:#fff;border-color:transparent;text-shadow:inherit}@media only screen and (max-width:700px){.editor-toolbar a.no-mobile{display:none}}.editor-statusbar{padding:8px 10px;font-size:12px;color:#959694;text-align:right}.editor-statusbar span{display:inline-block;min-width:4em;margin-left:1em}.editor-preview,.editor-preview-side{padding:10px;background:#fafafa;overflow:auto;display:none;box-sizing:border-box}.editor-statusbar .lines:before{content:'lines: '}.editor-statusbar .words:before{content:'words: '}.editor-statusbar .characters:before{content:'characters: '}.editor-preview{position:absolute;width:100%;height:100%;top:0;left:0;z-index:7}.editor-preview-side{position:fixed;bottom:0;width:50%;top:50px;right:0;z-index:9;border:1px solid #ddd}.editor-preview-active,.editor-preview-active-side{display:block}.editor-preview-side>p,.editor-preview>p{margin-top:0}.editor-preview pre,.editor-preview-side pre{background:#eee;margin-bottom:10px}.editor-preview table td,.editor-preview table th,.editor-preview-side table td,.editor-preview-side table th{border:1px solid #ddd;padding:5px}.CodeMirror .CodeMirror-code .cm-tag{color:#63a35c}.CodeMirror .CodeMirror-code .cm-attribute{color:#795da3}.CodeMirror .CodeMirror-code .cm-string{color:#183691}.CodeMirror .CodeMirror-selected{background:#d9d9d9}.CodeMirror .CodeMirror-code .cm-header-1{font-size:200%;line-height:200%}.CodeMirror .CodeMirror-code .cm-header-2{font-size:160%;line-height:160%}.CodeMirror .CodeMirror-code .cm-header-3{font-size:125%;line-height:125%}.CodeMirror .CodeMirror-code .cm-header-4{font-size:110%;line-height:110%}.CodeMirror .CodeMirror-code .cm-comment{background:rgba(0,0,0,.05);border-radius:2px}.CodeMirror .CodeMirror-code .cm-link{color:#7f8c8d}.CodeMirror .CodeMirror-code .cm-url{color:#aab2b3}.CodeMirror .CodeMirror-code .cm-strikethrough{text-decoration:line-through}.CodeMirror .CodeMirror-placeholder{opacity:.5}.CodeMirror .cm-spell-error:not(.cm-url):not(.cm-comment):not(.cm-tag):not(.cm-word){background:rgba(255,0,0,.15)} -/*! - * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.6.3');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} - -.c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:gray;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #CCC}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#FFF}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max,.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000} \ No newline at end of file diff --git a/sources/assets/fonts/FontAwesome.otf b/sources/assets/fonts/FontAwesome.otf deleted file mode 100644 index d4de13e832d567ff29c5b4e9561b8c370348cc9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124988 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ÐT?>-5aYhU|+1c>&YMpPK5x#-mbV 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'NS^o{z1ZKlHsAybrl=JE7AP369ntV%vB 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 CDx5C> diff --git a/sources/assets/fonts/fontawesome-webfont.eot b/sources/assets/fonts/fontawesome-webfont.eot deleted file mode 100644 index c7b00d2ba8896fd29de846b19f89fcf0d56ad152..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76518 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%0DyT{kunD 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⋙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 z - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/sources/assets/fonts/fontawesome-webfont.ttf b/sources/assets/fonts/fontawesome-webfont.ttf deleted file mode 100644 index f221e50a2ef60738ba30932d834530cdfe55cb3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152796 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

=v_rA!CPE#mM^4@)}X7qf;At+v)G*FZd&; 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 ALjV8( diff --git a/sources/assets/fonts/fontawesome-webfont.woff b/sources/assets/fonts/fontawesome-webfont.woff deleted file mode 100644 index 6e7483cf61b490c08ed644d6ef802c69472eb247..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90412 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%0Ded40&XED0GYFoIh+AV*?9!MR5pBW?X_8Bp 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 IH>08b4`|GD*#H0l diff --git a/sources/assets/fonts/fontawesome-webfont.woff2 b/sources/assets/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 7eb74fd127ee5eddf3b95fee6a20dc1684b0963b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71896 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≠dR0E9ICQ{-tcR;@{R^I5P#1GUH!p=-{c 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 diff --git a/sources/assets/img/favicon.png b/sources/assets/img/favicon.png deleted file mode 100644 index f2895941784df51864916e9340f3fb2062c06523..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2051 zcmV+e2>kbnP)C^aO?_OU1eL*6X;-zupkpAI^NdMpi$Q26TTv3r&;J9-K4|8)lc~R@vdv2Z- z+%6Yx*3@9riWQh17l#WcPx|BrL;%|9ME(5vaCdgH@)VONW9Yhdfk?pvOKU4~XU)Pc zA8`UAKy!XRx_|zel_OE95Nk4ll1c-S0s}>xHo>%eH^Uy{g)0iS%1X3s-O9;}*}E4* zj7DBQ4Mro3W5)RG@3z@cfA1b1H8z56a=Z1@Pmwrn8b&1~cx*%kaJ99eAv+szyIFba z`SYR9%Hr)eZO$C5-nNaCXYc93t(qF_$jieom6eQsx66e+UwwrgrKKJl(Vu{M$r3pK z`G=J=#Arm!H{Xy9>w!!z$7_=(qqw31+rIk_5()G6E}T4xX0zGTCMJO8&>>il9b@HC zQYm7;{g!tb6@wX>nV7e18N*J~G_GH~=xGxXz;Wje8dt95*Id5rITtMe-P_BrB?J zQ!IJ?5$~mXv_F3AITs}W-;$@_vj?H^@nS;xjkp(IWZ3$@9Q_u6cgf4lL}YfhzhOkf zYOyeE!wd$`x!(ftDtRMDKp&uz#}{>f|IM&Pixogf$&;$p{)8X~Zvu#V0_?YM^DB94 z)<7|3ict4NaigjVzgJfeuu&9+Det`FX$uyhAt#5k`uKe@|Bz%yo4zKX`y!zy6AfQ>VQ0vRAD_N_zSL8&Lt&85xMo$sy?y08nN! zq0D3wsM6@c#PL48&hXuF-HTiys)DluW|ROA*E;Cx*j-kvju z!8w2YI7$y3@U)39i}%#lqA4$rv|GUlS1M6>^eB>N&SdoMTDJ~e|BYq^3qZ+aoSfF} z+hHp&7wVcgD2l?y0|yZLM9!^EO*r%Y_W=A5AiAJ{n?%#7&&h$S-^xp{po@-1+U(g3 zyWavtE?NZD6T?Yw=rx;R{`g~|?gN5})2B0Rzg@Y4UZ>NKp8!Q6X8(SK==GdjYiTLk z4jvR5f;h&GAJ4Ek>~`F}dDFj_pj4-Wp`-+$C{FIf+*~;B-t{L8F+}QgUhPfw_5N3Z zh}2Z*czphLcXsxb#@=3kLy1OMc(_-4r`0O13`TF+0(rj=jlR%bU5!T@H;M@*3SB-H zaNKUUH~}b`tZ%)aM`>&+C_vYhD`LX=jkcB+uXeRoD}Ep(Pe?%YmMxq-+T}vSf(39} ztztt8#;uwful7itj?73!sD3P#y&}=rN{KN@{eN;jMxhDVsLiBpX?BCCe+qiTo=SLM1plKTU zAAJO;m#u#jQ&IpBo(!qd)1l$m76$+>ivvaExQgt=ndUi^pJV=&CBF+>^yM-(Xp`}TflaT4$aHswH?O(*I#H_ zy*f~7c%YAq!{MqbjC*2NYQO}bq*54;9O1Pg>hZpP=qM`-NFK7VFk~)YjvsH_z$+6b zF!~3)1Ed-a!jqHPJqp<75*icrJl9_4L-Pi8_f+3g0GW>g+Z;=B2uS=N}~bAW2z23g91ElJoolDyqr z82-2SpV<%O{r7Zn43W6Zdv>oEv!jT^!{3WuS=E=nn>({Nn{qwMopX1J174;stchm)rt9r^h0-m2H3;hpUIyN=HOq!ME#C*L8mC;$BF zJ$~<|EjAHQ*k$vNPrgdN{;~5?PKl*E`wBPC;OU=c6LsN8U)1w*^SM1YX8n3pvPddS zYVsm8xrLg6k&AAzt`;@@$M`wE*Hz46MJ+HW97|jyN|N()b5rw57@UJ#9Yg$stQ68y zbh8Rl(-q1L^$Zj=N{ch|(iJ?t+!ee6T-_DQEDSVt6befdb23XR6>JqO4Y+ot+-V0I zrV27FC9x#cD!C{XNHG{07@F!DnCKc>gcuoH0gbP0l+XkK+Qz?D diff --git a/sources/assets/img/icon.svg b/sources/assets/img/icon.svg deleted file mode 100644 index be34908..0000000 --- a/sources/assets/img/icon.svg +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - K - B - - diff --git a/sources/assets/img/touch-icon-ipad-retina.png b/sources/assets/img/touch-icon-ipad-retina.png deleted file mode 100644 index 9336a60bf777c0407cc564ec2d9def95383fb4e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4157 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 diff --git a/sources/assets/img/touch-icon-iphone-retina.png b/sources/assets/img/touch-icon-iphone-retina.png deleted file mode 100644 index f21bb3cbe47ee98b47c1fa9e0a680c6b4ad33b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3454 zcma)9X*3jW)E~lsEZMgi*~z|-T^PogCfUk1$U4@HCCh}$ZZI=;B@&e)J40e5#84>1 z*vpoEZ6T%fPUpNI-w*F|&VBBAo_p?>d++ae@6E8awmi!QW&;2KXD=dP_H-TbPk=1+ zJNskmExKa5VRrEKv4WvgamI%;AMAZ1uB~)RoG%LlUM25iGD>=Mbq-+q$P82b%~|ad2h-gcb;P zvQ=VWV9jOXm5@0}PjLVa$!HD5gVuj!e=dnBBU9FgeP7KPGCm#)V9I{CG7!yZH2hj* zhzBdJ&loCWxk&g7B)XkGVfJZQWLJSdiO`o$5<>;+(xNs4AWGhH-}~ z`&XA50Hcv_lB}2#7I&`W(m2ub3VzjBM zQeOCv^rmla2GBO;ADGwXveXGWwD|W;Px^J^OcOqI#Yu8-_^N8iMR=}T`@W%=FMPsi z7dcA@-&M2RZs?{`fzE9l)aomsw>Z&J0il(Z%1d4{Sa@ z38(viUjOWjmmEdhx_p*DFpvac^492OW0T;{5Pq9^tGP(c(gBTbpbUX$G{6=2bh$*i z#6INZhRy@W8ofAV4{=H%A>6Up=}6*O04xiBrWMKDicBp*qve$pdR{Jj&v)GZc)pIa zOU!VpuFtZ|sGTRuLg)G{(?|v%3F6Djdf?HVQi0!)K{p*SG%yQ+xrA&+Vvjvg-^IP&w-r*7z<`8$QtQHQtjv_^Dgm zJ~R}$9=UON9P}r)g@RMhYpRE1R8yePVc9jNYxlL;PpluNJ-dojIHmNOwd}%#T~3bX z0=mMJi{P)Rl{wZW1M~!}a@pApD#|CAN;HCNYHRxLG`Me%jdtX2^_t1Q2z^EmA1>@? z{lJ?iGGuihmda^rzFZusDd@@R>8-0;G#Ymn=xyeOQ)IZ_SGVx+Y@H+g&Q8$A_IBXV zU`w+E*toRf$uxSp%1#*Jm9}=;6?b9QS*v;J+xrUr+oeTm5M!}Z{L}n9mHsC<7>hWG^DwG3&Yh4bST#m6a=*?q?O523H+@P!KRFX8XDR z$HCcQD^k(jaq59b2S4=~o2DtnE^cCi44++FlQTA?Ar6=NY%z22OXiSxz0WQ#9B7zW znI@>U9dia~t!01bukmvsWqP4-XXuU7HVAu8_w|3_U>8^p9{4;N1NQ&^N$LdmxVUgz z!qf}+i>n+IYc#I;)uWyX&orXhAr#^ml^)A905M8?xT3bE1w6iA>>o?gpGUa6fP$QA z%PYrdv~qR9%`Lae#;rdtTFES&+SICX4Jr*d)AC>MqGwvOR7ut|8&?8I&li!clMcT5 z_d(2upcN}@%#A}_ z(P)l7awGQ=arcBB2VCv1AjjM&qwIVa^!9o*VJN{VIODDTThw5sCn4#d*=)-4`oZE0l z(fu%p4Q!-`+j?5o={aEya2fv^< z8RUU$Z@s^P0-O2w)nqLy6iRuGo;yd52hpv)*=8ydkH>HV3JO&}|NIc6;52zR=7r2! zW(#XHBsF*zN=>p&h{9glj&=54EyaJum+?#n+wY5KhKJB*zkX2m^5rC-sq1-MwN3bX z>26toGe&>$w{z7Q90%b**0Kb0o$49x@K?tvDr&;2bMb@-+-zL4y z^*>aI>>m{~AsVDU+HNt&e}7;ijwvf6McwBVBXwrBDCJvuS#s_zz!4nDN8Nmo|LXd^-&LmiN8c%8_y zm#^uSQa4cG(UJ0W01n_hC2-7imE=~Q&gSt>G`Lbs;q~S+{ng6j<2B|4eijzZw)cN~ zI-&x8t_s0PZvQZWWG=wy^&u9=qV>)zh6)=Rlp`)CLhJk_l)mQ1#`R^H5jsko8W_Xu zf0&mQ_9JFS+TJ23jF{tOE@MxAp$K--7_sQgTzb;He*VPs_d4v(r9TbrM*nmFb?i(C z!~`)ezF}YpzsjGaQd`iLN{`WpYYzQ5!65{hTsr`XIi1jp@|9bxd$D-9oJEQ<0E<*0 zE;CG3V#Sq4%jArYEPu|G>fKGRx{Ne84j(e060UaBk#8D?!Fmi zzMTDdzU}PRBPo_!Q zrui6}B6gsEY;tUhHl}I{W%~y*a&P?c#uxyoZojxkY$O}C+r|G#m7TD#Al2C9CA9wV zEIueeYP7fLh||HCt@AZS-Pbh4@BFTlP2(cx`Ab@H zIw7L}TF__TyKW+L&K}u?3JQ){=ZlZWzi+zV;q#FJe4l$ID(0ssKAXAs6+O}QL+lJl zpR0d&&iSC1y{e(Qf`5N^J-u4XKl;}Bw}=>V@s!n72F&;I*qjFhKdpU=MDCSzu9ZVN zn}$wr66l>w;`a4K5j!|z!us(Spxev5S2;ZZiy%bVO$8keW23GhRzz1<)5^wJJ@o4ycZdui<@Qh6ls~`5 zCIj{31i4O6V^}mJjG>Z}gMYqQaBm9Ozz{JHVUSNkbO1Dt+y{6l^LWiHmcWrQT37mFg19*AAILJ ztEgye9%koJ+@N-vSDfKfScq_K>fK2u=;L;7-|M@IZS?*gARJ|YLOq{%8|39(3|ZM; z5lux%^?b`e@AbB(VYzbZTJj)qIkU_05Q{2D(ULha7!3DC8SYCm2duyZBV~@S2VopU z{F|JO02mSEbN6QUw+WFU0k<{XJc{Q3XLb1Bz2d-R_>;yFmBuqe-<1FtEv#YnW}Zp^ E1D-^83jhEB diff --git a/sources/assets/img/touch-icon-iphone.png b/sources/assets/img/touch-icon-iphone.png deleted file mode 100644 index 00e337f17058f557dfad114baa75709550bf4603..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1855 zcmV-F2f+A=P)8R(EWQIN$SSdF5nAxvDHj9@~hS%_i`Oq3C!B0`aJRW3s5Z9mkm zr|mhtoTDa;=hyeW@6-4Fp7iVYz2`k;84LykCOOz&dI6sUQz9n|rbJE_Oo^N<;F?a< zO-<1D^jIZwyuINX8fsV2@y15z`uj=!Y^g1014;{i!X=xTd#zYQPRA8{Un4G|3 zK~hozjzGXvN~^eW?i|X`pC{P3BwUA}Q7X}8V+#spGI+$q*cGo{tp?A<#j3BbyBn`s zThZ3sjFK~FplE8c;1nG>f*%qS;p*-VfQfHXuZMEmHp!s5tC zY)nZ(#givESXgMm=~t=n$Bi4tIc<@Br%qwCriRqd_V9rJwQFGUcyv=)#^!L4n4XSx z$;lSJ+PioEaj7X$HxIUDRQX19D^4xk`vhM&vIRu!pkfd-^~qtSJ(H;aWt5wqXS*Lc2RPKSy^^p z7fhk^#S6mRS0XWv9TTb7Lz$EW-QXZ8g~{u}5xji6bgcUWqdqD0RhH2Beg5f-ydSC;@m-$78QZR;aK&V z)~>D3o>}-qA|i0?!UckjzQ|8-U7X6wa(o#a4pzp;BS$WWr8dwS9hK^x5t4M>iP!sXMa@or?q!cSXdZ+14u9zCKPhBmr8 zI`H$peMpXq!tk3n1Rw3~YS3!YnV5*L>+8X`(KWLdcb-27m*lS1sMUC-P~cTd3z{1m zaQo_2=uA%if9mUzx^^wjS63Umc#NE`6D=+1&d6Y_AQuM)l6D3FASgK4INp|-iR|6G z@wdsNRYPqpa#B-qqND@>gFT)>xg5i{ZZQ?kZp;e{!{z(;5jb})!Cra&I#ivV02~m> z6^j8jHC?%LC$z6$JF!%H;PQBo<>wP@I;|F^MMVG{5a}8o4&na&lpI}OAC%j-17G0f z^@`Y7%r)!q|0d~kE>No-4NnVx zvu0V?I-L;-05f;(!nAekC^_SejZhst=uCL0VO|6Pz(7xr^H+#OE(h1okCM}0P=FB| z&!9{~`SPWO%}XF~UL;2-gyhmCfW;yw84OTv-%iFPY&O1_z(7wA8tdvT>~j__q+jv)=Hy*=k41lxANX|MO+*JhH6)SNC-qHPf~L9 zBO~ZcOr-1+If}0KcI?}{8EJ8G(Cc&rAD73&jt?CMMxH_dK#-P(;mS&kR8^63#_H62}kzlbPxpWDN&`@Z5dr4`1 zxw-IMy&CSzmy>dCU%5hSDc^qg9rheMW}Gwnp8>9~FT^$u7=um+Wl|FKLqklaHX=4D z2}QSVfo;<5WBkub(_&*GNKK{WOtiJ(^`1S9=A9c7g8Z^FoG2+VzDEBD!gigWkN}qj z3#YvM#1XCg>3#LR)7W^+n{tNw`FOsLJ%c=kX002ovPDHLkV1mm!UjP6A diff --git a/sources/assets/js/app.min.js b/sources/assets/js/app.min.js deleted file mode 100644 index 2a8178e..0000000 --- a/sources/assets/js/app.min.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict";var Kanboard={};Kanboard.Accordion=function(t){this.app=t},Kanboard.Accordion.prototype.listen=function(){$(document).on("click",".accordion-toggle",function(t){var e=$(this).parents(".accordion-section");t.preventDefault(),e.hasClass("accordion-collapsed")?(e.find(".accordion-content").show(),e.removeClass("accordion-collapsed")):(e.find(".accordion-content").hide(),e.addClass("accordion-collapsed"))})},Kanboard.App=function(){this.controllers={}},Kanboard.App.prototype.get=function(t){return this.controllers[t]},Kanboard.App.prototype.execute=function(){for(var t in Kanboard)if("App"!==t){var e=new Kanboard[t](this);this.controllers[t]=e,"function"==typeof e.execute&&e.execute(),"function"==typeof e.listen&&e.listen(),"function"==typeof e.focus&&e.focus(),"function"==typeof e.keyboardShortcuts&&e.keyboardShortcuts()}this.focus(),this.chosen(),this.keyboardShortcuts(),this.datePicker(),this.autoComplete(),this.tagAutoComplete()},Kanboard.App.prototype.keyboardShortcuts=function(){var t=this;Mousetrap.bindGlobal("mod+enter",function(){var e=$("form");1==e.length?e.submit():e.length>1&&("INPUT"===document.activeElement.tagName||"TEXTAREA"===document.activeElement.tagName?$(document.activeElement).parents("form").submit():t.get("Popover").isOpen()&&$("#popover-container form").submit())}),Mousetrap.bind("b",function(t){t.preventDefault(),$("#board-selector").trigger("chosen:open")}),Mousetrap.bindGlobal("esc",function(){t.get("Popover").close(),t.get("Dropdown").close()}),Mousetrap.bind("?",function(){t.get("Popover").open($("body").data("keyboard-shortcut-url"))})},Kanboard.App.prototype.focus=function(){$(document).on("focus",".auto-select",function(){$(this).select()}),$(document).on("mouseup",".auto-select",function(t){t.preventDefault()})},Kanboard.App.prototype.chosen=function(){$(".chosen-select").each(function(){var t=$(this).data("search-threshold");void 0===t&&(t=10),$(this).chosen({width:"180px",no_results_text:$(this).data("notfound"),disable_search_threshold:t})}),$(".select-auto-redirect").change(function(){var t=new RegExp($(this).data("redirect-regex"),"g");window.location=$(this).data("redirect-url").replace(t,$(this).val())})},Kanboard.App.prototype.datePicker=function(){var t=$("body"),e=t.data("js-date-format"),a=t.data("js-time-format"),o=t.data("js-lang");$.datepicker.setDefaults($.datepicker.regional[o]),$.timepicker.setDefaults($.timepicker.regional[o]),$(".form-date").datepicker({showOtherMonths:!0,selectOtherMonths:!0,dateFormat:e,constrainInput:!1}),$(".form-datetime").datetimepicker({dateFormat:e,timeFormat:a,constrainInput:!1})},Kanboard.App.prototype.tagAutoComplete=function(){$(".tag-autocomplete").select2({tags:!0})},Kanboard.App.prototype.autoComplete=function(){$(".autocomplete").each(function(){var t=$(this),e=t.data("dst-field"),a=t.data("dst-extra-field");""==$("#form-"+e).val()&&t.parent().find("button[type=submit]").attr("disabled","disabled"),t.autocomplete({source:t.data("search-url"),minLength:1,select:function(o,n){$("input[name="+e+"]").val(n.item.id),a&&$("input[name="+a+"]").val(n.item[a]),t.parent().find("button[type=submit]").removeAttr("disabled")}})})},Kanboard.App.prototype.hasId=function(t){return!!document.getElementById(t)},Kanboard.App.prototype.showLoadingIcon=function(){$("body").append(' ')},Kanboard.App.prototype.hideLoadingIcon=function(){$("#app-loading-icon").remove()},Kanboard.App.prototype.formatDuration=function(t){return t>=86400?Math.round(t/86400)+"d":t>=3600?Math.round(t/3600)+"h":t>=60?Math.round(t/60)+"m":t+"s"},Kanboard.App.prototype.isVisible=function(){var t="";return"undefined"!=typeof document.hidden?t="visibilityState":"undefined"!=typeof document.mozHidden?t="mozVisibilityState":"undefined"!=typeof document.msHidden?t="msVisibilityState":"undefined"!=typeof document.webkitHidden&&(t="webkitVisibilityState"),""!=t?"visible"==document[t]:!0},Kanboard.AvgTimeColumnChart=function(t){this.app=t},Kanboard.AvgTimeColumnChart.prototype.execute=function(){this.app.hasId("analytic-avg-time-column")&&this.show()},Kanboard.AvgTimeColumnChart.prototype.show=function(){var t=$("#chart"),e=t.data("metrics"),a=[t.data("label")],o=[];for(var n in e)a.push(e[n].average),o.push(e[n].title);c3.generate({data:{columns:[a],type:"bar"},bar:{width:{ratio:.5}},axis:{x:{type:"category",categories:o},y:{tick:{format:this.app.formatDuration}}},legend:{show:!1}})},Kanboard.BoardCollapsedMode=function(t){this.app=t},Kanboard.BoardCollapsedMode.prototype.keyboardShortcuts=function(){var t=this;t.app.hasId("board")&&Mousetrap.bind("s",function(){t.toggle()})},Kanboard.BoardCollapsedMode.prototype.toggle=function(){var t=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:$('.filter-display-mode:not([style="display: none;"]) a').attr("href"),success:function(e){$(".filter-display-mode").toggle(),t.app.get("BoardDragAndDrop").refresh(e)}})},Kanboard.BoardColumnScrolling=function(t){this.app=t},Kanboard.BoardColumnScrolling.prototype.execute=function(){this.app.hasId("board")&&(this.render(),$(window).on("load",this.render),$(window).resize(this.render))},Kanboard.BoardColumnScrolling.prototype.listen=function(){var t=this;$(document).on("click",".filter-toggle-height",function(e){e.preventDefault(),t.toggle()})},Kanboard.BoardColumnScrolling.prototype.onBoardRendered=function(){this.render()},Kanboard.BoardColumnScrolling.prototype.toggle=function(){var t=localStorage.getItem("column_scroll");void 0==t&&(t=1),localStorage.setItem("column_scroll",0==t?1:0),this.render()},Kanboard.BoardColumnScrolling.prototype.render=function(){var t=$(".board-task-list"),e=$(".board-rotation-wrapper"),a=$(".filter-max-height"),o=$(".filter-min-height");if(0==localStorage.getItem("column_scroll")){var n=80;a.show(),o.hide(),e.css("min-height",""),t.each(function(){var t=$(this).height();t>n&&(n=t)}),t.css("min-height",n),t.css("height","")}else if(a.hide(),o.show(),$(".board-swimlane").length>1)t.each(function(){$(this).height()>500?$(this).css("height",500):($(this).css("min-height",320),e.css("min-height",320))});else{var n=$(window).height()-170;t.css("height",n),e.css("min-height",n)}},Kanboard.BoardColumnView=function(t){this.app=t},Kanboard.BoardColumnView.prototype.execute=function(){this.app.hasId("board")&&this.render()},Kanboard.BoardColumnView.prototype.listen=function(){var t=this;$(document).on("click",".board-toggle-column-view",function(){t.toggle($(this).data("column-id"))})},Kanboard.BoardColumnView.prototype.onBoardRendered=function(){this.render()},Kanboard.BoardColumnView.prototype.render=function(){var t=this;$(".board-column-header").each(function(){var e=$(this).data("column-id");localStorage.getItem("hidden_column_"+e)&&t.hideColumn(e)})},Kanboard.BoardColumnView.prototype.toggle=function(t){localStorage.getItem("hidden_column_"+t)?this.showColumn(t):this.hideColumn(t)},Kanboard.BoardColumnView.prototype.hideColumn=function(t){$(".board-column-"+t+" .board-column-expanded").hide(),$(".board-column-"+t+" .board-column-collapsed").show(),$(".board-column-header-"+t+" .board-column-expanded").hide(),$(".board-column-header-"+t+" .board-column-collapsed").show(),$(".board-column-header-"+t).each(function(){$(this).removeClass("board-column-compact"),$(this).addClass("board-column-header-collapsed")}),$(".board-column-"+t).each(function(){$(this).addClass("board-column-task-collapsed")}),$(".board-column-"+t+" .board-rotation").each(function(){$(this).css("width",$(".board-column-"+t).height())}),localStorage.setItem("hidden_column_"+t,1)},Kanboard.BoardColumnView.prototype.showColumn=function(t){$(".board-column-"+t+" .board-column-expanded").show(),$(".board-column-"+t+" .board-column-collapsed").hide(),$(".board-column-header-"+t+" .board-column-expanded").show(),$(".board-column-header-"+t+" .board-column-collapsed").hide(),$(".board-column-header-"+t).removeClass("board-column-header-collapsed"),$(".board-column-"+t).removeClass("board-column-task-collapsed"),0==localStorage.getItem("horizontal_scroll")&&$(".board-column-header-"+t).addClass("board-column-compact"),localStorage.removeItem("hidden_column_"+t)},Kanboard.BoardHorizontalScrolling=function(t){this.app=t},Kanboard.BoardHorizontalScrolling.prototype.execute=function(){this.app.hasId("board")&&this.render()},Kanboard.BoardHorizontalScrolling.prototype.listen=function(){var t=this;$(document).on("click",".filter-toggle-scrolling",function(e){e.preventDefault(),t.toggle()})},Kanboard.BoardHorizontalScrolling.prototype.keyboardShortcuts=function(){var t=this;t.app.hasId("board")&&Mousetrap.bind("c",function(){t.toggle()})},Kanboard.BoardHorizontalScrolling.prototype.onBoardRendered=function(){this.render()},Kanboard.BoardHorizontalScrolling.prototype.toggle=function(){var t=localStorage.getItem("horizontal_scroll")||1;localStorage.setItem("horizontal_scroll",0==t?1:0),this.render()},Kanboard.BoardHorizontalScrolling.prototype.render=function(){0==localStorage.getItem("horizontal_scroll")?($(".filter-wide").show(),$(".filter-compact").hide(),$("#board-container").addClass("board-container-compact"),$("#board th:not(.board-column-header-collapsed)").addClass("board-column-compact")):($(".filter-wide").hide(),$(".filter-compact").show(),$("#board-container").removeClass("board-container-compact"),$("#board th").removeClass("board-column-compact"))},Kanboard.BoardPolling=function(t){this.app=t},Kanboard.BoardPolling.prototype.execute=function(){if(this.app.hasId("board")){var t=parseInt($("#board").attr("data-check-interval"));t>0&&window.setInterval(this.check.bind(this),1e3*t)}},Kanboard.BoardPolling.prototype.check=function(){if(this.app.isVisible()&&!this.app.get("BoardDragAndDrop").savingInProgress){var t=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:$("#board").data("check-url"),statusCode:{200:function(e){t.app.get("BoardDragAndDrop").refresh(e)},304:function(){t.app.hideLoadingIcon()}}})}},Kanboard.BoardTask=function(t){this.app=t},Kanboard.BoardTask.prototype.listen=function(){var t=this;$(document).on("click",".task-board-change-assignee",function(e){e.preventDefault(),e.stopPropagation(),t.app.get("Popover").open($(this).data("url"))}),$(document).on("click",".task-board",function(t){"A"!=t.target.tagName&&"IMG"!=t.target.tagName&&(window.location=$(this).data("task-url"))})},Kanboard.BoardTask.prototype.keyboardShortcuts=function(){var t=this;t.app.hasId("board")&&Mousetrap.bind("n",function(){t.app.get("Popover").open($("#board").data("task-creation-url"))})},Kanboard.BurndownChart=function(t){this.app=t},Kanboard.BurndownChart.prototype.execute=function(){this.app.hasId("analytic-burndown")&&this.show()},Kanboard.BurndownChart.prototype.show=function(){for(var t=$("#chart"),e=t.data("metrics"),a=[[t.data("label-total")]],o=[],n=d3.time.format("%Y-%m-%d"),r=d3.time.format(t.data("date-format")),i=0;i0&&(void 0==a[0][i]&&a[0].push(0),a[0][i]+=e[i][s]),0==s&&o.push(r(n.parse(e[i][s]))));c3.generate({data:{columns:a},axis:{x:{type:"category",categories:o}}})},Kanboard.Calendar=function(t){this.app=t},Kanboard.Calendar.prototype.execute=function(){var t=$("#calendar");1==t.length&&this.show(t)},Kanboard.Calendar.prototype.show=function(t){t.fullCalendar({lang:$("body").data("js-lang"),editable:!0,eventLimit:!0,defaultView:"month",header:{left:"prev,next today",center:"title",right:"month,agendaWeek,agendaDay"},eventDrop:function(e){$.ajax({cache:!1,url:t.data("save-url"),contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({task_id:e.id,date_due:e.start.format()})})},viewRender:function(){var e=t.data("check-url"),a={start:t.fullCalendar("getView").start.format(),end:t.fullCalendar("getView").end.format()};for(var o in a)e+="&"+o+"="+a[o];$.getJSON(e,function(e){t.fullCalendar("removeEvents"),t.fullCalendar("addEventSource",e),t.fullCalendar("rerenderEvents")})}})},Kanboard.Column=function(t){this.app=t},Kanboard.Column.prototype.listen=function(){this.dragAndDrop()},Kanboard.Column.prototype.dragAndDrop=function(){var t=this;$(".draggable-row-handle").mouseenter(function(){$(this).parent().parent().addClass("draggable-item-hover")}).mouseleave(function(){$(this).parent().parent().removeClass("draggable-item-hover")}),$(".columns-table tbody").sortable({forcePlaceholderSize:!0,handle:"td:first i",helper:function(t,e){return e.children().each(function(){$(this).width($(this).width())}),e},stop:function(e,a){var o=a.item;o.removeClass("draggable-item-selected"),t.savePosition(o.data("column-id"),o.index()+1)},start:function(t,e){e.item.addClass("draggable-item-selected")}}).disableSelection()},Kanboard.Column.prototype.savePosition=function(t,e){var a=$(".columns-table").data("save-position-url"),o=this;this.app.showLoadingIcon(),$.ajax({cache:!1,url:a,contentType:"application/json",type:"POST",processData:!1,data:JSON.stringify({column_id:t,position:e}),complete:function(){o.app.hideLoadingIcon()}})},Kanboard.CompareHoursColumnChart=function(t){this.app=t},Kanboard.CompareHoursColumnChart.prototype.execute=function(){this.app.hasId("analytic-compare-hours")&&this.show()},Kanboard.CompareHoursColumnChart.prototype.show=function(){var t=$("#chart"),e=t.data("metrics"),a=t.data("label-open"),o=t.data("label-closed"),n=[t.data("label-spent")],r=[t.data("label-estimated")],i=[];for(var s in e)n.push(parseFloat(e[s].time_spent)),r.push(parseFloat(e[s].time_estimated)),i.push("open"==s?a:o);c3.generate({data:{columns:[n,r],type:"bar"},bar:{width:{ratio:.2}},axis:{x:{type:"category",categories:i}},legend:{show:!0}})},Kanboard.CumulativeFlowDiagram=function(t){this.app=t},Kanboard.CumulativeFlowDiagram.prototype.execute=function(){this.app.hasId("analytic-cfd")&&this.show()},Kanboard.CumulativeFlowDiagram.prototype.show=function(){for(var t=$("#chart"),e=t.data("metrics"),a=[],o=[],n=[],r=d3.time.format("%Y-%m-%d"),i=d3.time.format(t.data("date-format")),s=0;s0&&o.push(e[s][d])):(a[d].push(e[s][d]),0==d&&n.push(i(r.parse(e[s][d]))));c3.generate({data:{columns:a,type:"area-spline",groups:[o]},axis:{x:{type:"category",categories:n}}})},Kanboard.Dropdown=function(t){this.app=t},Kanboard.Dropdown.prototype.listen=function(){var t=this;$(document).on("click",function(){t.close()}),$(document).on("click",".dropdown-menu",function(e){e.preventDefault(),e.stopImmediatePropagation(),t.close();var a=$(this).next("ul"),o=$(this).offset();$("body").append(jQuery("

",{id:"dropdown"})),a.clone().appendTo("#dropdown");var n=$("#dropdown ul");n.addClass("dropdown-submenu-open");var r=n.outerHeight(),i=n.outerWidth();o.top+r-$(window).scrollTop()<$(window).height()||$(window).scrollTop()+o.top$(window).width()?n.css("left",o.left-i+$(this).outerWidth()):n.css("left",o.left)}),$(document).on("click",".dropdown-submenu-open li",function(t){$(t.target).is("li")&&$(this).find("a:visible")[0].click()})},Kanboard.Dropdown.prototype.close=function(){$("#dropdown").remove()},Kanboard.Dropdown.prototype.onPopoverOpened=function(){this.close()},Kanboard.FileUpload=function(t){this.app=t,this.files=[],this.currentFile=0},Kanboard.FileUpload.prototype.onPopoverOpened=function(){var t=document.getElementById("file-dropzone"),e=this;t&&(t.ondragover=t.ondragenter=function(t){t.stopPropagation(),t.preventDefault()},t.ondrop=function(t){t.stopPropagation(),t.preventDefault(),e.files=t.dataTransfer.files,e.show(),$("#file-error-max-size").hide()},$(document).on("click","#file-browser",function(t){t.preventDefault(),$("#file-form-element").get(0).click()}),$(document).on("click","#file-upload-button",function(t){t.preventDefault(),e.currentFile=0,e.checkFiles()}),$("#file-form-element").change(function(){e.files=document.getElementById("file-form-element").files,e.show(),$("#file-error-max-size").hide()}))},Kanboard.FileUpload.prototype.show=function(){if($("#file-list").remove(),this.files.length>0){$("#file-upload-button").prop("disabled",!1),$("#file-dropzone-inner").hide();for(var t=jQuery("