diff --git a/Gemfile.lock b/Gemfile.lock index c236730d45d4..67c7526eaf3e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -226,35 +226,35 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (2.0.1) - actioncable (7.1.5) - actionpack (= 7.1.5) - activesupport (= 7.1.5) + actioncable (7.1.5.1) + actionpack (= 7.1.5.1) + activesupport (= 7.1.5.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.5) - actionpack (= 7.1.5) - activejob (= 7.1.5) - activerecord (= 7.1.5) - activestorage (= 7.1.5) - activesupport (= 7.1.5) + actionmailbox (7.1.5.1) + actionpack (= 7.1.5.1) + activejob (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.5) - actionpack (= 7.1.5) - actionview (= 7.1.5) - activejob (= 7.1.5) - activesupport (= 7.1.5) + actionmailer (7.1.5.1) + actionpack (= 7.1.5.1) + actionview (= 7.1.5.1) + activejob (= 7.1.5.1) + activesupport (= 7.1.5.1) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.5) - actionview (= 7.1.5) - activesupport (= 7.1.5) + actionpack (7.1.5.1) + actionview (= 7.1.5.1) + activesupport (= 7.1.5.1) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -265,31 +265,31 @@ GEM actionpack-xml_parser (2.0.1) actionpack (>= 5.0) railties (>= 5.0) - actiontext (7.1.5) - actionpack (= 7.1.5) - activerecord (= 7.1.5) - activestorage (= 7.1.5) - activesupport (= 7.1.5) + actiontext (7.1.5.1) + actionpack (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.5) - activesupport (= 7.1.5) + actionview (7.1.5.1) + activesupport (= 7.1.5.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.5) - activesupport (= 7.1.5) + activejob (7.1.5.1) + activesupport (= 7.1.5.1) globalid (>= 0.3.6) - activemodel (7.1.5) - activesupport (= 7.1.5) + activemodel (7.1.5.1) + activesupport (= 7.1.5.1) activemodel-serializers-xml (1.0.3) activemodel (>= 5.0.0.a) activesupport (>= 5.0.0.a) builder (~> 3.1) - activerecord (7.1.5) - activemodel (= 7.1.5) - activesupport (= 7.1.5) + activerecord (7.1.5.1) + activemodel (= 7.1.5.1) + activesupport (= 7.1.5.1) timeout (>= 0.4.0) activerecord-import (1.8.1) activerecord (>= 4.2) @@ -302,13 +302,13 @@ GEM multi_json (~> 1.11, >= 1.11.2) rack (>= 2.0.8, < 4) railties (>= 6.1) - activestorage (7.1.5) - actionpack (= 7.1.5) - activejob (= 7.1.5) - activerecord (= 7.1.5) - activesupport (= 7.1.5) + activestorage (7.1.5.1) + actionpack (= 7.1.5.1) + activejob (= 7.1.5.1) + activerecord (= 7.1.5.1) + activesupport (= 7.1.5.1) marcel (~> 1.0) - activesupport (7.1.5) + activesupport (7.1.5.1) base64 benchmark (>= 0.3) bigdecimal @@ -330,7 +330,7 @@ GEM public_suffix (>= 2.0.2, < 7.0) aes_key_wrap (1.1.0) afm (0.2.2) - airbrake (13.0.4) + airbrake (13.0.5) airbrake-ruby (~> 6.0) airbrake-ruby (6.2.2) rbtree3 (~> 0.6) @@ -344,7 +344,7 @@ GEM awesome_nested_set (3.8.0) activerecord (>= 4.0.0, < 8.1) aws-eventstream (1.3.0) - aws-partitions (1.1017.0) + aws-partitions (1.1022.0) aws-sdk-core (3.214.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) @@ -353,7 +353,7 @@ GEM aws-sdk-kms (1.96.0) aws-sdk-core (~> 3, >= 3.210.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.176.0) + aws-sdk-s3 (1.176.1) aws-sdk-core (~> 3, >= 3.210.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) @@ -916,20 +916,20 @@ GEM rackup (1.0.1) rack (< 3) webrick - rails (7.1.5) - actioncable (= 7.1.5) - actionmailbox (= 7.1.5) - actionmailer (= 7.1.5) - actionpack (= 7.1.5) - actiontext (= 7.1.5) - actionview (= 7.1.5) - activejob (= 7.1.5) - activemodel (= 7.1.5) - activerecord (= 7.1.5) - activestorage (= 7.1.5) - activesupport (= 7.1.5) + rails (7.1.5.1) + actioncable (= 7.1.5.1) + actionmailbox (= 7.1.5.1) + actionmailer (= 7.1.5.1) + actionpack (= 7.1.5.1) + actiontext (= 7.1.5.1) + actionview (= 7.1.5.1) + activejob (= 7.1.5.1) + activemodel (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) bundler (>= 1.15.0) - railties (= 7.1.5) + railties (= 7.1.5.1) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -944,9 +944,9 @@ GEM rails-i18n (7.0.10) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.5) - actionpack (= 7.1.5) - activesupport (= 7.1.5) + railties (7.1.5.1) + actionpack (= 7.1.5.1) + activesupport (= 7.1.5.1) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -1015,7 +1015,7 @@ GEM rspec-support (3.13.1) rspec-wait (1.0.1) rspec (>= 3.4) - rubocop (1.69.1) + rubocop (1.69.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) diff --git a/app/components/_index.sass b/app/components/_index.sass index aa9da94c01f9..59f6c3cdfa43 100644 --- a/app/components/_index.sass +++ b/app/components/_index.sass @@ -20,3 +20,4 @@ @import "work_packages/exports/modal_dialog_component" @import "work_package_relations_tab/index_component" @import "users/hover_card_component" +@import "enterprise_edition/banner_component" diff --git a/app/components/enterprise_edition/banner_component.html.erb b/app/components/enterprise_edition/banner_component.html.erb new file mode 100644 index 000000000000..5161729b5d58 --- /dev/null +++ b/app/components/enterprise_edition/banner_component.html.erb @@ -0,0 +1,19 @@ +<%= + grid_layout("op-ee-banner", **@system_arguments) do |grid| + grid.with_area(:'icon-container') do + content_tag :div, class: "op-ee-banner--shield" do + render(Primer::Beta::Octicon.new(icon: 'op-enterprise-addons', + size: :medium, + classes: "op-ee-banner--icon")) + end + end + grid.with_area(:'title-container') { render(Primer::Beta::Text.new) { title } } + grid.with_area(:'description-container') { render(Primer::Beta::Text.new) { description } } + grid.with_area(:'link-container') do + render(Primer::Beta::Link.new(href: href)) do |link| + link.with_trailing_visual_icon(icon: 'link-external') + link_title + end + end + end +%> diff --git a/app/components/enterprise_edition/banner_component.rb b/app/components/enterprise_edition/banner_component.rb new file mode 100644 index 000000000000..f7ac7ed39bab --- /dev/null +++ b/app/components/enterprise_edition/banner_component.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module EnterpriseEdition + # Add a general description of component here + # Add additional usage considerations or best practices that may aid the user to use the component correctly. + # @accessibility Add any accessibility considerations + class BannerComponent < ApplicationComponent + include OpPrimer::ComponentHelpers + + # @param feature_key [Symbol, NilClass] The key of the feature to show the banner for. + # @param title [String] The title of the banner. + # @param description [String] The description of the banner. + # @param href [String] The URL to link to. + # @param skip_render [Boolean] Whether to skip rendering the banner. + # @param system_arguments [Hash] <%= link_to_system_arguments_docs %> + def initialize(feature_key, + title: nil, + description: nil, + link_title: nil, + href: nil, + skip_render: !EnterpriseToken.show_banners?, + **system_arguments) + @system_arguments = system_arguments + @system_arguments[:tag] = "div" + super + + @feature_key = feature_key + @title = title + @description = description + @link_title = link_title + @href = href + @skip_render = skip_render + end + + private + + attr_reader :skip_render, + :feature_key + + def title + @title || I18n.t("ee.upsale.#{feature_key}.title", default: I18n.t("ee.upsale.title")) + end + + def description + @description || begin + I18n.t("ee.upsale.#{feature_key}.description") + rescue StandardError + I18n.t("ee.upsale.#{feature_key}.description_html") + end + rescue I18n::MissingTranslationData => e + raise e.exception( + <<~TEXT.squish + The expected '#{I18n.locale}.ee.upsale.#{feature_key}.description' key does not exist. + Ideally, provide it in the locale file. + If that isn't applicable, a description parameter needs to be provided. + TEXT + ) + end + + def link_title + @link_title || I18n.t("ee.upsale.#{feature_key}.link_title", default: I18n.t("ee.upsale.link_title")) + end + + def href + href_value = @href || OpenProject::Static::Links.links.dig(:enterprise_docs, feature_key, :href) + + unless href_value + raise "Neither a custom href is provided nor is a value set " \ + "in OpenProject::Static::Links.enterprise_docs[#{feature_key}][:href]" + end + + href_value + end + + def render? + !skip_render + end + end +end diff --git a/app/components/enterprise_edition/banner_component.sass b/app/components/enterprise_edition/banner_component.sass new file mode 100644 index 000000000000..d8ca7bc2f193 --- /dev/null +++ b/app/components/enterprise_edition/banner_component.sass @@ -0,0 +1,68 @@ +/*! + / -- copyright + / OpenProject is an open source project management software. + / Copyright (C) 2024 the OpenProject GmbH + / + / This program is free software; you can redistribute it and/or + / modify it under the terms of the GNU General Public License version 3. + / + / OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + / Copyright (C) 2006-2013 Jean-Philippe Lang + / Copyright (C) 2010-2013 the ChiliProject Team + / + / This program is free software; you can redistribute it and/or + / modify it under the terms of the GNU General Public License + / as published by the Free Software Foundation; either version 2 + / of the License, or (at your option) any later version. + / + / This program is distributed in the hope that it will be useful, + / but WITHOUT ANY WARRANTY; without even the implied warranty of + / MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + / GNU General Public License for more details. + / + / You should have received a copy of the GNU General Public License + / along with this program; if not, write to the Free Software + / Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + / + / See COPYRIGHT and LICENSE files for more details. + / ++ + / + +$op-ee-banner--shield-width: 32px + +// This is not named op-enterprise-banner because as of now, there is still a legacy angular component that uses that block name. +.op-ee-banner + display: grid + grid-template-columns: $op-ee-banner--shield-width auto auto + grid-template-areas: "icon-container title-container" "icon-container description-container" "icon-container link-container" + grid-column-gap: 0.5rem + justify-content: left + @media screen and (min-width: $breakpoint-md) + grid-template-areas: "icon-container title-container title-container" "icon-container description-container link-container" + + &--icon-container + @extend .upsale-colored + align-self: start + justify-self: center + + &--shield + @extend .upsale-border-colored + width: $op-ee-banner--shield-width + height: 42px + border-width: 10px 5px 10px 5px + border-radius: 0 0 10px 10px + border-style: solid + display: flex + align-items: center + justify-content: center + + &--icon + width: $op-ee-banner--shield-width + height: $op-ee-banner--shield-width + + &--title-container + @extend .upsale-colored + font-weight: bold + + &--link-container + align-self: end diff --git a/app/components/shares/project_queries/upsale_component.html.erb b/app/components/shares/project_queries/upsale_component.html.erb index 1f0a77a91888..946bbda996a5 100644 --- a/app/components/shares/project_queries/upsale_component.html.erb +++ b/app/components/shares/project_queries/upsale_component.html.erb @@ -1,7 +1,7 @@ <%= modal_content.with_row(data: { 'test-selector': 'op-share-dialog-upsale-block' }) do render Primer::OpenProject::FeedbackMessage.new(icon_arguments: { icon: :"op-enterprise-addons", classes: "upsale-colored" }, border: true) do |component| - component.with_heading(tag: :h2, classes: 'upsale-colored').with_content(I18n.t(:label_enterprise_addon)) + component.with_heading(tag: :h2, classes: 'upsale-colored').with_content(I18n.t(:"ee.upsale.title")) component.with_description { I18n.t('sharing.project_queries.upsale.message') } href = "#{OpenProject::Static::Links.links[:upsale][:href]}/?utm_source=unknown&utm_medium=community-edition&utm_campaign=project-list-sharing-modal" diff --git a/app/components/shares/work_packages/modal_upsale_component.html.erb b/app/components/shares/work_packages/modal_upsale_component.html.erb index f1be3ab6dc33..036bc35a673b 100644 --- a/app/components/shares/work_packages/modal_upsale_component.html.erb +++ b/app/components/shares/work_packages/modal_upsale_component.html.erb @@ -1,7 +1,7 @@ <%= component_wrapper(tag: 'turbo-frame') do render Primer::OpenProject::FeedbackMessage.new(icon_arguments: { icon: :"op-enterprise-addons", classes: "upsale-colored" }, border: true) do |component| - component.with_heading(tag: :h2, classes: 'upsale-colored').with_content(I18n.t(:label_enterprise_addon)) + component.with_heading(tag: :h2, classes: 'upsale-colored').with_content(I18n.t(:"ee.upsale.title")) component.with_description { I18n.t('mail.sharing.work_packages.enterprise_text') } href = "#{OpenProject::Static::Links.links[:upsale][:href]}/?utm_source=unknown&utm_medium=community-edition&utm_campaign=work-package-sharing-modal" diff --git a/app/contracts/api_tokens/create_contract.rb b/app/contracts/api_tokens/create_contract.rb index f9c3d93484f4..b4835e55eb6c 100644 --- a/app/contracts/api_tokens/create_contract.rb +++ b/app/contracts/api_tokens/create_contract.rb @@ -32,7 +32,7 @@ module APITokens class CreateContract < BaseContract attribute :token_name - validates :token_name, presence: { message: I18n.t("my.access_token.errors.token_name_blank") } + validates :token_name, presence: { message: proc { I18n.t("my.access_token.errors.token_name_blank") } } validate :token_name_is_unique, unless: :token_name_is_blank? private diff --git a/app/controllers/concerns/op_turbo/component_stream.rb b/app/controllers/concerns/op_turbo/component_stream.rb index 6d3b3fa27162..6cc60cd36918 100644 --- a/app/controllers/concerns/op_turbo/component_stream.rb +++ b/app/controllers/concerns/op_turbo/component_stream.rb @@ -74,8 +74,8 @@ def add_before_via_turbo_stream(component:, target_component:) turbo_streams << target_component.insert_as_turbo_stream(component:, view_context:, action: :before) end - def render_error_flash_message_via_turbo_stream(**kwargs) - update_flash_message_via_turbo_stream(**kwargs.merge(scheme: :danger, icon: :stop)) + def render_error_flash_message_via_turbo_stream(**) + update_flash_message_via_turbo_stream(**, scheme: :danger, icon: :stop) end def update_flash_message_via_turbo_stream(message:, component: OpPrimer::FlashComponent, **) @@ -89,6 +89,12 @@ def scroll_into_view_via_turbo_stream(target, behavior: :auto, block: :start) .render_in(view_context) end + def add_caption_to_input_element_via_turbo_stream(target, caption:, clean_other_captions: true) + turbo_streams << OpTurbo::StreamComponent + .new(action: :addInputCaption, target:, caption:, clean_other_captions:) + .render_in(view_context) + end + def turbo_streams @turbo_streams ||= [] end diff --git a/app/controllers/custom_fields_controller.rb b/app/controllers/custom_fields_controller.rb index 2beb4cfd0ff5..c280ec2dfebb 100644 --- a/app/controllers/custom_fields_controller.rb +++ b/app/controllers/custom_fields_controller.rb @@ -30,14 +30,17 @@ class CustomFieldsController < ApplicationController include CustomFields::SharedActions # share logic with ProjectCustomFieldsControlller layout "admin" + # rubocop:disable Rails/LexicallyScopedActionFilter before_action :require_admin before_action :find_custom_field, only: %i(edit update destroy delete_option reorder_alphabetical) before_action :prepare_custom_option_position, only: %i(update create) before_action :find_custom_option, only: :delete_option + before_action :validate_enterprise_token, only: %i(create) + # rubocop:enable Rails/LexicallyScopedActionFilter def index # loading wp cfs exclicity to allow for eager loading - @custom_fields_by_type = CustomField.all + @custom_fields_by_type = CustomField .where.not(type: ["WorkPackageCustomField", "ProjectCustomField"]) .group_by { |f| f.class.name } @@ -64,6 +67,12 @@ def show_local_breadcrumb false end + def validate_enterprise_token + if params.dig(:custom_field, :field_format) == "hierarchy" && !EnterpriseToken.allows_to?(:custom_field_hierarchies) + render_403 + end + end + def find_custom_field @custom_field = CustomField.find(params[:id]) rescue ActiveRecord::RecordNotFound diff --git a/app/forms/custom_fields/hierarchy/item_form.rb b/app/forms/custom_fields/hierarchy/item_form.rb index 50f9d41e8529..be2e5185feb8 100644 --- a/app/forms/custom_fields/hierarchy/item_form.rb +++ b/app/forms/custom_fields/hierarchy/item_form.rb @@ -56,7 +56,7 @@ class ItemForm < ApplicationForm ) end - item_form.group(layout: :horizontal) do |button_group| + item_form.group(layout: :horizontal, align_self: :end) do |button_group| button_group.button(name: :cancel, tag: :a, label: I18n.t(:button_cancel), diff --git a/app/forms/work_packages/activities_tab/journals/submit.rb b/app/forms/work_packages/activities_tab/journals/submit.rb index 08bce83ed9ea..defd84b26d54 100644 --- a/app/forms/work_packages/activities_tab/journals/submit.rb +++ b/app/forms/work_packages/activities_tab/journals/submit.rb @@ -28,7 +28,7 @@ module WorkPackages::ActivitiesTab::Journals class Submit < ApplicationForm form do |notes_form| - notes_form.submit(name: :submit, label: "Save", scheme: :primary, + notes_form.submit(name: :submit, label: I18n.t("button_save"), scheme: :primary, data: { test_selector: "op-submit-work-package-journal-form" }) end end diff --git a/app/helpers/custom_fields_helper.rb b/app/helpers/custom_fields_helper.rb index f9880b5d14e6..1c81066a9009 100644 --- a/app/helpers/custom_fields_helper.rb +++ b/app/helpers/custom_fields_helper.rb @@ -219,7 +219,7 @@ def label_for_custom_field_format(format_string) label = format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label) show_enterprise_text = format_string == "hierarchy" && !EnterpriseToken.allows_to?(:custom_field_hierarchies) - suffix = show_enterprise_text ? " (#{I18n.t(:label_enterprise_addon)})" : "" + suffix = show_enterprise_text ? " (#{I18n.t(:"ee.upsale.title")})" : "" "#{label}#{suffix}" end diff --git a/app/menus/notifications/menu.rb b/app/menus/notifications/menu.rb index cc6961c823ef..8b03c3864285 100644 --- a/app/menus/notifications/menu.rb +++ b/app/menus/notifications/menu.rb @@ -63,7 +63,7 @@ def inbox_menu end def reason_filters - %w[mentioned assigned responsible watched dateAlert shared].map do |reason| + %w[mentioned assigned responsible watched dateAlert shared reminder].map do |reason| count = unread_by_reason[reason] menu_item(title: I18n.t("notifications.reasons.#{reason}"), icon_key: reason, @@ -128,7 +128,8 @@ def icon_map "responsible" => :"op-person-accountable", "watched" => :eye, "shared" => :"share-android", - "dateAlert" => :"op-calendar-alert" + "dateAlert" => :"op-calendar-alert", + "reminder" => :clock } end diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index f7f148183239..1808c08da8e1 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -326,12 +326,15 @@ def possible_version_values_options(obj) def possible_user_values_options(obj) mapped_with_deduced_project(obj) do |project| - if project&.persisted? - project.principals - else - Principal - .in_visible_project_or_me(User.current) - end + scope = if project&.persisted? + project.principals + else + Principal + .in_visible_project_or_me(User.current) + end + + scope + .select(*(User::USER_FORMATS_STRUCTURE[Setting.user_format].map(&:to_s) << "id")) end end diff --git a/app/models/work_package/pdf_export/common/common.rb b/app/models/work_package/pdf_export/common/common.rb index c91d44836ab5..63c055a40044 100644 --- a/app/models/work_package/pdf_export/common/common.rb +++ b/app/models/work_package/pdf_export/common/common.rb @@ -35,7 +35,7 @@ module WorkPackage::PDFExport::Common::Common private - def get_pdf(_language) + def get_pdf ::WorkPackage::PDFExport::Common::View.new(current_language) end @@ -164,6 +164,13 @@ def draw_text_multiline_part(line, text_style, x_position, y_position) measure_text_height(line, text_style) end + def ellipsis_if_longer(text, available_width, text_style) + title_text_width = measure_text_width(text, text_style) + return text if title_text_width < available_width + + truncate_ellipsis(text, available_width, text_style) + end + def truncate_ellipsis(text, available_width, text_style) line = text.dup while line.present? && (measure_text_width("#{line}...", text_style) > available_width) @@ -285,4 +292,12 @@ def footer_date def current_page_nr pdf.page_number + @page_count - (with_cover? ? 1 : 0) end + + def write_horizontal_line(y_position, height, color) + draw_horizontal_line( + y_position, + pdf.bounds.left, pdf.bounds.right, + height, color + ) + end end diff --git a/app/models/work_package/pdf_export/document_generator.rb b/app/models/work_package/pdf_export/document_generator.rb index 37b69c6b4ea0..26a3a46ceb88 100644 --- a/app/models/work_package/pdf_export/document_generator.rb +++ b/app/models/work_package/pdf_export/document_generator.rb @@ -52,7 +52,7 @@ def initialize(work_package, _options = {}) end def setup_page! - self.pdf = get_pdf(current_language) + self.pdf = get_pdf end def export! diff --git a/app/models/work_package/pdf_export/export/cover.rb b/app/models/work_package/pdf_export/export/cover.rb index e50d0c101c30..a91eed6ead2f 100644 --- a/app/models/work_package/pdf_export/export/cover.rb +++ b/app/models/work_package/pdf_export/export/cover.rb @@ -40,17 +40,34 @@ def write_cover_page! def write_cover_hero max_width = pdf.bounds.width - styles.cover_hero_padding[:right_padding] float_top = write_background_image - float_top -= write_hero_title(float_top, max_width) if project + float_top -= write_hero_title(float_top, max_width) float_top -= write_hero_heading(float_top, max_width) - write_hero_subheading(float_top, max_width) unless User.current.nil? + float_top -= write_hero_dates(float_top, max_width) + write_hero_subheading(float_top, max_width) end def available_title_height(current_y) current_y - - styles.cover_hero_title_max_height - - styles.cover_hero_title_spacing - - styles.cover_hero_heading_spacing - - styles.cover_hero_subheading_max_height + cover_hero_title_max_height - + cover_hero_heading_max_height - + cover_hero_dates_max_height - + cover_hero_subheading_max_height + end + + def cover_hero_title_max_height + cover_page_title&.then { styles.cover_hero_title_max_height + styles.cover_hero_title_spacing } || 0 + end + + def cover_hero_heading_max_height + cover_page_heading&.then { styles.cover_hero_heading_spacing } || 0 + end + + def cover_hero_dates_max_height + cover_page_dates&.then { styles.cover_hero_dates_max_height } || 0 + end + + def cover_hero_subheading_max_height + cover_page_title&.then { styles.cover_hero_title_max_height + styles.cover_hero_title_spacing } || 0 end def write_cover_hr @@ -81,27 +98,44 @@ def validate_cover_text_color end def write_hero_title(top, width) + return 0 if cover_page_title.blank? + write_hero_text( top:, width:, - text: project.name, + text: cover_page_title, text_style: styles.cover_hero_title, height: styles.cover_hero_title_max_height ) + styles.cover_hero_title_spacing end def write_hero_heading(top, width) + return 0 if cover_page_heading.blank? + write_hero_text( top:, width:, - text: heading, + text: cover_page_heading, text_style: styles.cover_hero_heading, height: available_title_height(top) ) + styles.cover_hero_heading_spacing end + def write_hero_dates(top, width) + return 0 if cover_page_dates.blank? + + write_hero_text( + top:, width:, + text: cover_page_dates, + text_style: styles.cover_hero_dates, + height: styles.cover_hero_dates_max_height + ) + styles.cover_hero_dates_spacing + end + def write_hero_subheading(top, width) + return 0 if cover_page_subheading.blank? + write_hero_text( top:, width:, - text: User.current.name, + text: cover_page_subheading, text_style: styles.cover_hero_subheading, height: styles.cover_hero_subheading_max_height ) diff --git a/app/models/work_package/pdf_export/export/schema.json b/app/models/work_package/pdf_export/export/schema.json index 50c64700b44a..316f60469667 100644 --- a/app/models/work_package/pdf_export/export/schema.json +++ b/app/models/work_package/pdf_export/export/schema.json @@ -193,6 +193,42 @@ } ] }, + "dates" : { + "title" : "The dates block in the hero", + "type" : "object", + "x-example" : { + "heading" : { + "spacing" : 10, + "max_height" : 20, + "size" : 32, + "color" : "414d5f", + "styles" : [ + "bold" + ] + } + }, + "properties" : { + "max_height" : { + "title" : "Maximum height of the block", + "examples" : [ + 30 + ], + "$ref" : "#/$defs/measurement" + }, + "spacing" : { + "title" : "Minimum spacing between dates and subheading", + "examples" : [ + 10 + ], + "$ref" : "#/$defs/measurement" + } + }, + "allOf" : [ + { + "$ref" : "#/$defs/font" + } + ] + }, "subheading" : { "title" : "The last block in the hero", "type" : "object", diff --git a/app/models/work_package/pdf_export/export/standard.yml b/app/models/work_package/pdf_export/export/standard.yml index 915d6dd37c2e..ecfc8a0a904b 100644 --- a/app/models/work_package/pdf_export/export/standard.yml +++ b/app/models/work_package/pdf_export/export/standard.yml @@ -275,9 +275,14 @@ cover: styles: - bold size: 16 + dates: + spacing: 4 + max_height: 16 + color: '414d5f' + size: 10 + styles: + - bold subheading: max_height: 30 color: '414d5f' - styles: - - italic size: 10 diff --git a/app/models/work_package/pdf_export/export/style.rb b/app/models/work_package/pdf_export/export/style.rb index 4a1a152adf1f..8e4197138903 100644 --- a/app/models/work_package/pdf_export/export/style.rb +++ b/app/models/work_package/pdf_export/export/style.rb @@ -253,6 +253,18 @@ def cover_hero_heading_spacing resolve_pt(@styles.dig(:cover, :hero, :heading, :spacing), 0) end + def cover_hero_dates + resolve_font(@styles.dig(:cover, :hero, :dates)) + end + + def cover_hero_dates_spacing + resolve_pt(@styles.dig(:cover, :hero, :dates, :spacing), 0) + end + + def cover_hero_dates_max_height + resolve_pt(@styles.dig(:cover, :hero, :dates, :max_height), 0) + end + def cover_hero_subheading resolve_font(@styles.dig(:cover, :hero, :subheading)) end diff --git a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb index 9a1ca49c949e..b62855f71c5b 100644 --- a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb +++ b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb @@ -86,7 +86,7 @@ def export! private def setup_page! - self.pdf = get_pdf(current_language) + self.pdf = get_pdf configure_page_size!(wants_report? ? :portrait : :landscape) end @@ -111,6 +111,22 @@ def with_cover? wants_report? end + def cover_page_title + project&.name + end + + def cover_page_heading + heading + end + + def cover_page_subheading + User.current&.name + end + + def cover_page_dates + nil + end + def render_work_packages_pdfs(work_packages, filename) write_cover_page! if with_cover? if wants_gantt? diff --git a/app/models/work_package/pdf_export/work_package_to_pdf.rb b/app/models/work_package/pdf_export/work_package_to_pdf.rb index 5dcfa09dd8c8..2006616c0fc4 100644 --- a/app/models/work_package/pdf_export/work_package_to_pdf.rb +++ b/app/models/work_package/pdf_export/work_package_to_pdf.rb @@ -63,7 +63,7 @@ def export! end def setup_page! - self.pdf = get_pdf(current_language) + self.pdf = get_pdf @page_count = 0 configure_page_size!(:portrait) end diff --git a/app/services/duration_converter.rb b/app/services/duration_converter.rb index e2efe5a771e7..c16c3b58b0bf 100644 --- a/app/services/duration_converter.rb +++ b/app/services/duration_converter.rb @@ -96,7 +96,7 @@ def valid?(duration) false end - def output(duration_in_hours) + def output(duration_in_hours, format: default_format) return duration_in_hours if duration_in_hours.nil? seconds = (duration_in_hours * 3600).to_i @@ -142,7 +142,7 @@ def do_parse(duration_string) **duration_length_options) / 3600.to_f end - def format + def default_format Setting.duration_format == "days_and_hours" ? :days_and_hours : :hours_only end diff --git a/app/views/wiki/export_multiple.html.erb b/app/views/wiki/export_multiple.html.erb index 83462dae26a2..f7f3daa7f2f8 100644 --- a/app/views/wiki/export_multiple.html.erb +++ b/app/views/wiki/export_multiple.html.erb @@ -53,7 +53,7 @@ See COPYRIGHT and LICENSE files for more details. <% @pages.each do |page| %>
- <%= format_text page.content ,:text, wiki_links: :anchor %> + <%= format_text page ,:text, wiki_links: :anchor %> <% end %> diff --git a/config/initializers/feature_decisions.rb b/config/initializers/feature_decisions.rb index 6bc6e4c17686..546662ab0263 100644 --- a/config/initializers/feature_decisions.rb +++ b/config/initializers/feature_decisions.rb @@ -47,9 +47,6 @@ description: "Allows to generate a PDF document from a work package description. " \ "See #45896 for details." -OpenProject::FeatureDecisions.add :recurring_meetings, - description: "Differentiate between one-time and recurring meetings." - # TODO: Remove once the feature flag primerized_work_package_activities is removed altogether OpenProject::FeatureDecisions.define_singleton_method(:primerized_work_package_activities_active?) do Rails.env.production? || diff --git a/config/locales/crowdin/af.yml b/config/locales/crowdin/af.yml index f438a90e83c6..c07d4a8fb8f7 100644 --- a/config/locales/crowdin/af.yml +++ b/config/locales/crowdin/af.yml @@ -855,6 +855,9 @@ af: lag: "Lag" from: "Werkspakket" to: "Verwante werk pakket" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "Bronadres" role: @@ -1433,6 +1436,7 @@ af: login: "Username" mail: "E-pos" name: "Naam" + note: "Note" password: "Wagwoord" priority: "Prioriteit" project: "Projek" @@ -1529,6 +1533,7 @@ af: button_print: "Print" button_quote: "Haal aan" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Hernoem" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ af: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Wys" button_sort: "Rangskik" button_submit: "Dien in" @@ -1744,12 +1750,12 @@ af: direction: lnr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Werkspakket prioriteite" enumeration_reported_project_statuses: "Gerapporteerde projekstatus" @@ -1782,6 +1788,7 @@ af: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Die werkspakket is nie gekry nie of behoort nie aan hierdie projek nie" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "moet projeklid wees" @@ -2075,6 +2082,7 @@ af: responsible: "Accountable" shared: "Shared" watched: "Dophouer" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ af: label_delete: "Delete" label_deleted: "geskrap" label_deleted_custom_field: "(pasgemaakte veld geskrap)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ af: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Omgewing" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ af: label_this_month: "vandeesmaand" label_this_week: "vandeesweek" label_this_year: "vandeesjaar" + label_time: "Time" label_time_entry_plural: "Tyd gespandeer" label_time_entry_activity_plural: "Spent time activities" label_title: "Titel" @@ -3782,6 +3791,12 @@ af: edit_description: "Can view, comment and edit this work package." view: "Bekyk" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml index 56e0e2995479..20f36103a819 100644 --- a/config/locales/crowdin/ar.yml +++ b/config/locales/crowdin/ar.yml @@ -887,6 +887,9 @@ ar: lag: "Lag" from: "مجموعة العمل" to: "مجموعة عمل ذات صلة" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "الرابط" role: @@ -1505,6 +1508,7 @@ ar: login: "Username" mail: "البريد الإكتروني" name: "الاسم" + note: "Note" password: "كلمة المرور" priority: "الأولوية" project: "مشروع" @@ -1601,6 +1605,7 @@ ar: button_print: "طباعة" button_quote: "اقتباس" button_remove: إزالة + button_remove_reminder: "Remove reminder" button_rename: "اعادة التّسمية" button_replace: "Replace" button_revoke: "Revoke" @@ -1611,6 +1616,7 @@ ar: button_save_as: "احفظ بشكل" button_apply_changes: "Apply changes" button_save_back: "حفظ والعودة" + button_set_reminder: "Set reminder" button_show: "إظهار" button_sort: "فرز" button_submit: "إرسال" @@ -1888,12 +1894,12 @@ ar: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "أولويات مجموعة العمل" enumeration_reported_project_statuses: "حالة للمشروع المبلغ عنه" @@ -1926,6 +1932,7 @@ ar: error_pdf_export_too_many_columns: "تم تحديد عدد كبير جداً من الأعمدة لتصدير PDF. الرجاء تقليل عدد الأعمدة." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "مجموعة العمل غير موجودة, أو أنها لا تخص هذا المشروع" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "يجب أن تكون عضو في المشروع" @@ -2219,6 +2226,7 @@ ar: responsible: "Accountable" shared: "Shared" watched: "المشاهد" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2389,6 +2397,7 @@ ar: label_delete: "Delete" label_deleted: "محذوف" label_deleted_custom_field: "(حذف حقل مخصص)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(فارغ)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2425,7 +2434,6 @@ ar: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "بيئة" label_estimates_and_progress: "Estimates and progress" label_equals: "يكون" @@ -2774,6 +2782,7 @@ ar: label_this_month: "هذا الشهر" label_this_week: "هذا الأسبوع" label_this_year: "هذه السنة" + label_time: "Time" label_time_entry_plural: "الوقت المستهلك" label_time_entry_activity_plural: "Spent time activities" label_title: "العنوان" @@ -3936,6 +3945,12 @@ ar: edit_description: "Can view, comment and edit this work package." view: "عرض" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/az.yml b/config/locales/crowdin/az.yml index 37e31fb6135a..ec0a4642a845 100644 --- a/config/locales/crowdin/az.yml +++ b/config/locales/crowdin/az.yml @@ -855,6 +855,9 @@ az: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ az: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ az: button_print: "Print" button_quote: "Sitat" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ az: button_save_as: "Fərqli saxla" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ az: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ az: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ az: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ az: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ az: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ az: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3782,6 +3791,12 @@ az: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/be.yml b/config/locales/crowdin/be.yml index 22f53a98ba3a..bb6bcc6a84f7 100644 --- a/config/locales/crowdin/be.yml +++ b/config/locales/crowdin/be.yml @@ -871,6 +871,9 @@ be: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1469,6 +1472,7 @@ be: login: "Username" mail: "Email" name: "Імя" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1565,6 +1569,7 @@ be: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1575,6 +1580,7 @@ be: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1816,12 +1822,12 @@ be: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1854,6 +1860,7 @@ be: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2147,6 +2154,7 @@ be: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2317,6 +2325,7 @@ be: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2353,7 +2362,6 @@ be: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2702,6 +2710,7 @@ be: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3860,6 +3869,12 @@ be: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/bg.yml b/config/locales/crowdin/bg.yml index 56c2d7e800ff..f83ef48c56f3 100644 --- a/config/locales/crowdin/bg.yml +++ b/config/locales/crowdin/bg.yml @@ -855,6 +855,9 @@ bg: lag: "Lag" from: "Работен пакет" to: "Свързани работени пакети" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL АДРЕС" role: @@ -1433,6 +1436,7 @@ bg: login: "Username" mail: "E-mail" name: "Име" + note: "Note" password: "Парола" priority: "Приоритет" project: "Проект" @@ -1529,6 +1533,7 @@ bg: button_print: "Отпечатване" button_quote: "Цитат" button_remove: Премахване + button_remove_reminder: "Remove reminder" button_rename: "Преименуване" button_replace: "Замени" button_revoke: "Отмени" @@ -1539,6 +1544,7 @@ bg: button_save_as: "Запиши като" button_apply_changes: "Приложи промените" button_save_back: "Записване и обратно" + button_set_reminder: "Set reminder" button_show: "Покажи" button_sort: "Сортиране" button_submit: "Изпрати" @@ -1744,12 +1750,12 @@ bg: direction: отляво надясно ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Добавяне на нови групи атрибути" rename_groups: "Преименуване на групи атрибути" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Дейности за проследяване на времето" enumeration_work_package_priorities: "Приоритети на работни пакети" enumeration_reported_project_statuses: "Докладвани статуси на проект" @@ -1782,6 +1788,7 @@ bg: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Работен пакет не е намерен или не принадлежи на този проект" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "трябва да бъде член проекта" @@ -2075,6 +2082,7 @@ bg: responsible: "Accountable" shared: "Shared" watched: "Наблюдател" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ bg: label_delete: "Delete" label_deleted: "изтрит" label_deleted_custom_field: "(изтрито потребителско поле)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(празно)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ bg: label_enterprise_active_users: "%{current}/%{limit} резервирани активни потребители" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Поддръжка за големи предприятия" - label_enterprise_addon: "Добавка за големи предприятия" label_environment: "Среда" label_estimates_and_progress: "Оценки и напредък" label_equals: "е" @@ -2630,6 +2638,7 @@ bg: label_this_month: "този месец" label_this_week: "тази седмица" label_this_year: "тази година" + label_time: "Time" label_time_entry_plural: "Отработено време" label_time_entry_activity_plural: "Прекарано време" label_title: "Заглавие" @@ -3782,6 +3791,12 @@ bg: edit_description: "Can view, comment and edit this work package." view: "Изглед" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/ca.yml b/config/locales/crowdin/ca.yml index a465d320dc0e..9493cdf246bd 100644 --- a/config/locales/crowdin/ca.yml +++ b/config/locales/crowdin/ca.yml @@ -851,6 +851,9 @@ ca: lag: "Retard" from: "Paquet de treball" to: "Paquet de treball relacionat" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1429,6 +1432,7 @@ ca: login: "Nom d'usuari" mail: "Correu electrònic" name: "Nom" + note: "Note" password: "Contrasenya" priority: "Prioritat" project: "Projecte" @@ -1525,6 +1529,7 @@ ca: button_print: "Imprimir" button_quote: "Citar" button_remove: Suprimir + button_remove_reminder: "Remove reminder" button_rename: "Renombrar" button_replace: "Substitueix" button_revoke: "Revoca" @@ -1535,6 +1540,7 @@ ca: button_save_as: "Desa com a" button_apply_changes: "Aplicar canvis" button_save_back: "Desar i tornar" + button_set_reminder: "Set reminder" button_show: "Mostra" button_sort: "Ordena" button_submit: "Enviar" @@ -1740,12 +1746,12 @@ ca: direction: dta. a esq. ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Personalitza la configuració del formulari amb aquestes extensions addicionals:" add_groups: "Afegir un nou atribut de grups" rename_groups: "Reanomena els atributs de grups" - project_filters: - description_html: "Filtrar i ordenar camps personalitzats és una extensió de l'edició Enterprise." enumeration_activities: "Activitats de rastrejament del temps" enumeration_work_package_priorities: "Prioritats dels paquets de treball" enumeration_reported_project_statuses: "Estats de projecte notificats" @@ -1778,6 +1784,7 @@ ca: error_pdf_export_too_many_columns: "Masses columnes seleccionades per a l'exportació PDF. Si us plau, redueix el nombre de columnes." error_pdf_failed_to_export: "No s'ha pogut guardar l'exportació PDF: %{error}" error_token_authenticity: "No s'ha pogut verificar el token de \"Cross-Site Request Forgery\". Has provat de sotmetre les dades en múltiples navegadors o pestanyes? Si us plau, tanca totes les pestanyes i prova-ho de nou." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "El paquet de treball no s'ha trobat o no pertany a aquest projecte" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "ha de ser membre del projecte" @@ -2071,6 +2078,7 @@ ca: responsible: "Responsable" shared: "Compartida" watched: "Observador" + reminder: "Reminder" facets: unread: "Sense llegir" unread_title: "Mostrar no llegits" @@ -2241,6 +2249,7 @@ ca: label_delete: "Delete" label_deleted: "suprimit" label_deleted_custom_field: "(camp personalitzat suprimit)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opció eliminada)" label_empty_element: "(buit)" label_missing_or_hidden_custom_option: "(valor absent o manca de permisos per accedir)" @@ -2277,7 +2286,6 @@ ca: label_enterprise_active_users: "%{current}/%{limit} usuaris actius registrats" label_enterprise_edition: "Edició Enterprise." label_enterprise_support: "Suport Enterprise" - label_enterprise_addon: "Enterprise add-on" label_environment: "Entorn" label_estimates_and_progress: "Estimates and progress" label_equals: "és" @@ -2626,6 +2634,7 @@ ca: label_this_month: "aquest més" label_this_week: "aquesta setmana" label_this_year: "aquest any" + label_time: "Time" label_time_entry_plural: "Temps utilitzat" label_time_entry_activity_plural: "Spent time activities" label_title: "Títol" @@ -3772,6 +3781,12 @@ ca: edit_description: "Can view, comment and edit this work package." view: "Mostra" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/ckb-IR.yml b/config/locales/crowdin/ckb-IR.yml index 3e212cd394af..1e93ba9a70bc 100644 --- a/config/locales/crowdin/ckb-IR.yml +++ b/config/locales/crowdin/ckb-IR.yml @@ -855,6 +855,9 @@ ckb-IR: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ ckb-IR: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ ckb-IR: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ ckb-IR: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ ckb-IR: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ ckb-IR: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ ckb-IR: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ ckb-IR: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ ckb-IR: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ ckb-IR: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3782,6 +3791,12 @@ ckb-IR: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/cs.yml b/config/locales/crowdin/cs.yml index d47917397260..49cb6f1b88df 100644 --- a/config/locales/crowdin/cs.yml +++ b/config/locales/crowdin/cs.yml @@ -871,6 +871,9 @@ cs: lag: "Lag" from: "Pracovní balíček" to: "Související pracovní balíček" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1469,6 +1472,7 @@ cs: login: "Uživatelské jméno" mail: "E-mail" name: "Název" + note: "Note" password: "Heslo" priority: "Priorita" project: "Projekt" @@ -1565,6 +1569,7 @@ cs: button_print: "Tisk" button_quote: "Citovat" button_remove: Odstranit + button_remove_reminder: "Remove reminder" button_rename: "Přejmenovat" button_replace: "Nahradit" button_revoke: "Revoke" @@ -1575,6 +1580,7 @@ cs: button_save_as: "Uložit jako" button_apply_changes: "Použít změny" button_save_back: "Uložit a odejít" + button_set_reminder: "Set reminder" button_show: "Zobrazit" button_sort: "Řadit" button_submit: "Potvrdit" @@ -1816,12 +1822,12 @@ cs: direction: zleva doprava ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Přizpůsobte si konfiguraci formuláře s těmito doplňky:" add_groups: "Přidat nové skupiny atributů" rename_groups: "Přejmenovat skupiny atributů" - project_filters: - description_html: "Filtrování a třídění na vlastních polích je doplněk edice Enterprise." enumeration_activities: "Sledování času" enumeration_work_package_priorities: "Priority pracovního balíčku" enumeration_reported_project_statuses: "Nahlášený stav projektu" @@ -1854,6 +1860,7 @@ cs: error_pdf_export_too_many_columns: "Příliš mnoho sloupců vybraných pro PDF export. Snižte počet sloupců." error_pdf_failed_to_export: "PDF export nelze uložit: %{error}" error_token_authenticity: "Nelze ověřit token Cross-Site Request Forgy. Pokusili jste se odeslat data na více prohlížečích nebo kartách? Prosím zavřete všechny panely a zkuste to znovu." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Pracovný balíček nebyl nalezen, nebo nepatří k tomuto projektu" error_work_package_id_not_found: "Pracovní balíček nebyl nalezen." error_must_be_project_member: "musí být členem projektu" @@ -2147,6 +2154,7 @@ cs: responsible: "Odpovědný" shared: "Sdíleno" watched: "Sledující" + reminder: "Reminder" facets: unread: "Nepřečtené" unread_title: "Zobrazit nepřečtené" @@ -2317,6 +2325,7 @@ cs: label_delete: "Delete" label_deleted: "Smazáno" label_deleted_custom_field: "(odstraněno vlastní pole)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(prázdný)" label_missing_or_hidden_custom_option: "(chybí hodnota nebo chybí oprávnění k přístupu)" @@ -2353,7 +2362,6 @@ cs: label_enterprise_active_users: "%{current}/%{limit} rezervováno aktivních uživatelů" label_enterprise_edition: "Enterprise Edice" label_enterprise_support: "Podpora pro Enterprise edici" - label_enterprise_addon: "Doplňky Enterprise Edice" label_environment: "Prostředí" label_estimates_and_progress: "Odhady a posup" label_equals: "je" @@ -2702,6 +2710,7 @@ cs: label_this_month: "tento měsíc" label_this_week: "tento týden" label_this_year: "tento rok" + label_time: "Time" label_time_entry_plural: "Strávený čas" label_time_entry_activity_plural: "Aktivity strávený čas" label_title: "Název" @@ -3858,6 +3867,12 @@ cs: edit_description: "Může zobrazovat, komentovat a upravovat tento pracovní balíček." view: "Zobrazit" view_description: "Může zobrazit tento pracovní balíček." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 uživatelů" diff --git a/config/locales/crowdin/da.yml b/config/locales/crowdin/da.yml index ebfa8ce85326..d4720686d4b2 100644 --- a/config/locales/crowdin/da.yml +++ b/config/locales/crowdin/da.yml @@ -853,6 +853,9 @@ da: lag: "Lag" from: "Arbejdspakke" to: "Sammenhørende arbejdspakker" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "Webadresse" role: @@ -1431,6 +1434,7 @@ da: login: "Username" mail: "E-mail" name: "Navn" + note: "Note" password: "Adgangskode" priority: "Prioritet" project: "Projekt" @@ -1527,6 +1531,7 @@ da: button_print: "Print" button_quote: "Citer" button_remove: Fjern + button_remove_reminder: "Remove reminder" button_rename: "Omdøb" button_replace: "Replace" button_revoke: "Revoke" @@ -1537,6 +1542,7 @@ da: button_save_as: "Gem som" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Vis" button_sort: "Sorter" button_submit: "Indsend" @@ -1742,12 +1748,12 @@ da: direction: Fra venstre mod højre ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Prioritering af arbejdspakker" enumeration_reported_project_statuses: "Rapporteret projektstatus" @@ -1780,6 +1786,7 @@ da: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Arbejdspakken er ikke fundet, eller den hører ikke til dette projekt" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "skal være et medlem af projektet" @@ -2073,6 +2080,7 @@ da: responsible: "Accountable" shared: "Shared" watched: "Tilsynsførende" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2243,6 +2251,7 @@ da: label_delete: "Delete" label_deleted: "slettet" label_deleted_custom_field: "(slettet selvvalgt felt)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(tom)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2279,7 +2288,6 @@ da: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Miljø" label_estimates_and_progress: "Estimates and progress" label_equals: "er" @@ -2628,6 +2636,7 @@ da: label_this_month: "denne måned" label_this_week: "denne uge" label_this_year: "dette år" + label_time: "Time" label_time_entry_plural: "Anvendt tid" label_time_entry_activity_plural: "Spent time activities" label_title: "Titel" @@ -3778,6 +3787,12 @@ da: edit_description: "Can view, comment and edit this work package." view: "Se" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/de.yml b/config/locales/crowdin/de.yml index 3bfae054b432..d99f40b2dc5c 100644 --- a/config/locales/crowdin/de.yml +++ b/config/locales/crowdin/de.yml @@ -218,7 +218,7 @@ de: heading: Für alle Projekte description: Dieses Projekt-Attribut ist in allen Projekten aktiviert, da die Option "Für alle Projekte" aktiviert ist. Es kann nicht für einzelne Projekte deaktiviert werden. items: - actions: "Element-Aktionen" + actions: "Aktionen" blankslate: root: title: "Ihre Liste der Elemente ist leer" @@ -848,6 +848,9 @@ de: lag: "Verzögerung" from: "Arbeitspaket" to: "Zugehöriges Arbeitspaket" + reminder: + remind_at_date: "Datum" + remind_at_time: "Time" repository: url: "URL" role: @@ -1426,6 +1429,7 @@ de: login: "Benutzername" mail: "E-Mail" name: "Name" + note: "Note" password: "Kennwort" priority: "Priorität" project: "Projekt" @@ -1522,6 +1526,7 @@ de: button_print: "Drucken" button_quote: "Zitieren" button_remove: Entfernen + button_remove_reminder: "Remove reminder" button_rename: "Umbenennen" button_replace: "Ersetzen" button_revoke: "Widerrufen" @@ -1532,6 +1537,7 @@ de: button_save_as: "Speichern unter" button_apply_changes: "Änderungen anwenden" button_save_back: "Speichern und zurück" + button_set_reminder: "Set reminder" button_show: "Anzeigen" button_sort: "Sortierung" button_submit: "OK" @@ -1737,12 +1743,12 @@ de: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Anpassen der Form-Konfiguration mit diesen zusätzlichen Add-ons:" add_groups: "Neue Attributgruppen hinzufügen" rename_groups: "Attributgruppen umbenennen" - project_filters: - description_html: "Filtern und Sortieren auf benutzerdefinierten Feldern ist ein Add-on der Enterprise Edition." enumeration_activities: "Aktivitäten für Zeiterfassung" enumeration_work_package_priorities: "Arbeitspaket-Prioritäten" enumeration_reported_project_statuses: "Gemeldeter Projekt-Status" @@ -1775,6 +1781,7 @@ de: error_pdf_export_too_many_columns: "Zu viele Spalten für PDF-Export ausgewählt. Bitte reduzieren Sie die Anzahl der ausgewählten Spalten." error_pdf_failed_to_export: "Der PDF-Export konnte nicht gespeichert werden: %{error}" error_token_authenticity: "Das Cross-Site Request Forgery Token konnte nicht verfiziert werden. Wenn Sie versucht haben, Daten auf mehreren Tabs oder Browsern abzuspeichern, schließen sie diese und laden diese Seite erneut um den Vorgang zu wiederholen." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Das Arbeitspaket wurde nicht gefunden oder gehört nicht zu diesem Projekt." error_work_package_id_not_found: "Das Arbeitspaket wurde nicht gefunden." error_must_be_project_member: "muss Mitglied des Projekts sein" @@ -1832,7 +1839,7 @@ de: label: "XLS" columns: input_label_report: "Spalten zur Attributtabelle hinzufügen" - input_caption_report: "Standardmäßig sind alle Attribute, die als Spalten in der Arbeitspaketliste hinzugefügt wurden, ausgewählt. Textfelder sind in der Attribut-Tabelle nicht verfügbar, können aber unterhalb der Tabelle angezeigt werden." + input_caption_report: "Standardmäßig sind alle Attribute, die als Spalten in der Arbeitspaketliste hinzugefügt wurden, ausgewählt. Langtextfelder sind in der Attributtabelle nicht verfügbar, können aber unterhalb der Tabelle angezeigt werden." input_caption_table: "Standardmäßig sind alle Attribute, die als Spalten in der Arbeitspaketliste hinzugefügt wurden, ausgewählt. Textfelder sind in tabellenbasierten Exporten nicht verfügbar." pdf: export_type: @@ -2068,6 +2075,7 @@ de: responsible: "Verantwortlich" shared: "Geteilt" watched: "Beobachter" + reminder: "Reminder" facets: unread: "Ungelesen" unread_title: "Ungelesene anzeigen" @@ -2238,6 +2246,7 @@ de: label_delete: "Löschen" label_deleted: "gelöscht" label_deleted_custom_field: "(gelöschtes benutzerdefiniertes Feld)" + label_deleted_custom_item: "(gelöschter Eintrag)" label_deleted_custom_option: "(gelöschte Option)" label_empty_element: "(leer)" label_missing_or_hidden_custom_option: "(Fehlender Wert oder fehlende Zugriffsberechtigungen)" @@ -2274,7 +2283,6 @@ de: label_enterprise_active_users: "%{current}/%{limit} gebuchte aktive Nutzer" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise Support" - label_enterprise_addon: "Enterprise Add-on" label_environment: "Umgebung" label_estimates_and_progress: "Schätzungen und Fortschritt" label_equals: "ist" @@ -2623,6 +2631,7 @@ de: label_this_month: "aktueller Monat" label_this_week: "aktuelle Woche" label_this_year: "aktuelles Jahr" + label_time: "Time" label_time_entry_plural: "Aufgewendete Zeit" label_time_entry_activity_plural: "Zeitbuchung-Aktivität" label_title: "Titel" @@ -3774,6 +3783,12 @@ de: edit_description: "Kann dieses Arbeitspaket ansehen, kommentieren und editieren." view: "Ansicht" view_description: "Kann dieses Arbeitspaket ansehen." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 Benutzer" diff --git a/config/locales/crowdin/el.yml b/config/locales/crowdin/el.yml index 1ce207c4e075..b5022cc13ef7 100644 --- a/config/locales/crowdin/el.yml +++ b/config/locales/crowdin/el.yml @@ -851,6 +851,9 @@ el: lag: "Lag" from: "Εργασία" to: "Σχετικές εργασίες" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1429,6 +1432,7 @@ el: login: "Όνομα χρήστη" mail: "Email" name: "Όνομα" + note: "Note" password: "Κωδικός" priority: "Προτεραιότητα" project: "Έργο" @@ -1525,6 +1529,7 @@ el: button_print: "Εκτύπωση" button_quote: "Παράθεση" button_remove: Αφαίρεση + button_remove_reminder: "Remove reminder" button_rename: "Μετονομασία" button_replace: "Αντικατάσταση" button_revoke: "Ανάκληση" @@ -1535,6 +1540,7 @@ el: button_save_as: "Αποθήκευση ως" button_apply_changes: "Apply changes" button_save_back: "Αποθήκευση και επιστροφή" + button_set_reminder: "Set reminder" button_show: "Εμφάνιση" button_sort: "Ταξινόμηση" button_submit: "Υποβολή" @@ -1740,12 +1746,12 @@ el: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Προσθήκη καινούργιων ομάδων χαρακτηριστικών" rename_groups: "Μετονομασία ομάδων χαρακτηριστικών" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Δραστηριότητες καταγραφής χρόνου" enumeration_work_package_priorities: "Προτεραιότητες πακέτου εργασίας" enumeration_reported_project_statuses: "Αναφερόμενη κατάσταση έργου" @@ -1778,6 +1784,7 @@ el: error_pdf_export_too_many_columns: "Επιλέχθηκαν πάρα πολλές στήλες για εξαγωγή σε PDF. Παρακαλούμε μειώστε τον αριθμό των στηλών." error_pdf_failed_to_export: "Η εξαγωγή σε PDF δεν ήταν δυνατό να αποθηκευτεί: %{error}" error_token_authenticity: "Δεν ήταν δυνατή η επαλήθευση του Cross-Site Request Forgery token. Προσπαθήσατε να υποβάλετε δεδομένα σε πολλαπλούς περιηγητές ή καρτέλες; Παρακαλούμε κλείστε όλες τις καρτέλες και δοκιμάστε ξανά." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Το πακέτο εργασίας δεν βρέθηκε ή δεν ανοίκει σε αυτό το έργο" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "πρέπει να είναι μέλος έργου" @@ -2071,6 +2078,7 @@ el: responsible: "Υπόλογος" shared: "Shared" watched: "Παρατηρητής" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2241,6 +2249,7 @@ el: label_delete: "Delete" label_deleted: "διαγραμμένο" label_deleted_custom_field: "(διαγραμμένο προσαρμοσμένο πεδίο)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(διαγραμμένη επιλογή)" label_empty_element: "(άδειο)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2277,7 +2286,6 @@ el: label_enterprise_active_users: "%{current}/%{limit} κλεισμένοι ενεργοί χρήστες" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Περιβάλλον" label_estimates_and_progress: "Estimates and progress" label_equals: "είναι" @@ -2626,6 +2634,7 @@ el: label_this_month: "αυτό το μήνα" label_this_week: "αυτή την εβδομάδα" label_this_year: "αυτό το έτος" + label_time: "Time" label_time_entry_plural: "Χρόνος που δαπανήθηκε" label_time_entry_activity_plural: "Spent time activities" label_title: "Τίτλος" @@ -3776,6 +3785,12 @@ el: edit_description: "Can view, comment and edit this work package." view: "Προβολή" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/eo.yml b/config/locales/crowdin/eo.yml index dd5214f8bf0c..209d67f98133 100644 --- a/config/locales/crowdin/eo.yml +++ b/config/locales/crowdin/eo.yml @@ -855,6 +855,9 @@ eo: lag: "Lag" from: "Laborpakaĵo" to: "Rilata laborpakaĵo" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ eo: login: "Uzantnomo" mail: "Retpoŝto" name: "Nomo" + note: "Note" password: "Pasvorto" priority: "Prioritato" project: "Projekto" @@ -1529,6 +1533,7 @@ eo: button_print: "Printi" button_quote: "Citi" button_remove: Forigi + button_remove_reminder: "Remove reminder" button_rename: "Alinomi" button_replace: "Anstataŭigi" button_revoke: "Eksvalidigi" @@ -1539,6 +1544,7 @@ eo: button_save_as: "Konservi kiel" button_apply_changes: "Apply changes" button_save_back: "Konservi kaj retroiri" + button_set_reminder: "Set reminder" button_show: "Montri" button_sort: "Ordigi" button_submit: "Sendi" @@ -1744,12 +1750,12 @@ eo: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ eo: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "vi devas esti membro de la projekto." @@ -2075,6 +2082,7 @@ eo: responsible: "Respondeculo" shared: "Shared" watched: "Atentanto" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ eo: label_delete: "Delete" label_deleted: "forigita" label_deleted_custom_field: "(propra kampo forigita)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ eo: label_enterprise_active_users: "%{current}/%{limit} rezervitaj aktivaj uzantoj" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Medio" label_estimates_and_progress: "Estimates and progress" label_equals: "estas" @@ -2630,6 +2638,7 @@ eo: label_this_month: "tiu ĉi monato" label_this_week: "tiu ĉi semajno" label_this_year: "tiu ĉi jaro" + label_time: "Time" label_time_entry_plural: "Uzata tempo" label_time_entry_activity_plural: "Spent time activities" label_title: "Titolo" @@ -3782,6 +3791,12 @@ eo: edit_description: "Can view, comment and edit this work package." view: "Montri" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/es.yml b/config/locales/crowdin/es.yml index 210faf1310d4..8444761f7818 100644 --- a/config/locales/crowdin/es.yml +++ b/config/locales/crowdin/es.yml @@ -852,6 +852,9 @@ es: lag: "Retraso" from: "Paquete de trabajo" to: "Paquete de trabajo relacionado" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1430,6 +1433,7 @@ es: login: "Nombre usuario" mail: "Correo electrónico" name: "Nombre" + note: "Note" password: "Contraseña" priority: "Prioridad" project: "Proyecto" @@ -1526,6 +1530,7 @@ es: button_print: "Imprimir" button_quote: "Comentario" button_remove: Eliminar + button_remove_reminder: "Remove reminder" button_rename: "Cambiar el nombre" button_replace: "Sustituir" button_revoke: "Revocar" @@ -1536,6 +1541,7 @@ es: button_save_as: "Guardar como" button_apply_changes: "Aplicar cambios" button_save_back: "Guardar y volver" + button_set_reminder: "Set reminder" button_show: "Mostrar" button_sort: "Ordenar" button_submit: "Enviar" @@ -1741,12 +1747,12 @@ es: direction: iad (ltr) ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Personalice la configuración del formulario con estas extensiones:" add_groups: "Añadir nuevos grupos de atributos" rename_groups: "Cambiar nombre de grupos de atributos" - project_filters: - description_html: "Filtrar y ordenar en campos personalizados es una extensión de Enterprise." enumeration_activities: "Actividades de seguimiento del tiempo" enumeration_work_package_priorities: "Prioridades del paquete de trabajo" enumeration_reported_project_statuses: "Estatus del proyecto reportado" @@ -1779,6 +1785,7 @@ es: error_pdf_export_too_many_columns: "Demasiadas columnas seleccionadas para la exportación de PDF. Reduzca el número de columnas." error_pdf_failed_to_export: "No se ha podido guardar la exportación PDF: %{error}" error_token_authenticity: "No se puede verificar el token de falsificación de solicitud entre sitios. ¿Intentó enviar datos en varios navegadores o pestañas? Cierre de todas las pestañas y vuelva a intentarlo." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "El paquete de trabajo no se ha encontrado o no pertenece a este proyecto" error_work_package_id_not_found: "No se ha encontrado el paquete de trabajo." error_must_be_project_member: "debe ser miembro del proyecto" @@ -2072,6 +2079,7 @@ es: responsible: "Responsable" shared: "Compartido" watched: "Observador" + reminder: "Reminder" facets: unread: "No leídas" unread_title: "Mostrar no leídos" @@ -2242,6 +2250,7 @@ es: label_delete: "Delete" label_deleted: "borrado" label_deleted_custom_field: "(campo personalizado borrado)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opción eliminada)" label_empty_element: "(vacío)" label_missing_or_hidden_custom_option: "(faltan valores o permisos de acceso)" @@ -2278,7 +2287,6 @@ es: label_enterprise_active_users: "%{current}/%{limit} usuarios activos que han reservado" label_enterprise_edition: "Enterprise" label_enterprise_support: "Soporte empresarial" - label_enterprise_addon: "Extensión Enterprise" label_environment: "Entorno" label_estimates_and_progress: "Estimaciones y progreso" label_equals: "es" @@ -2627,6 +2635,7 @@ es: label_this_month: "este mes" label_this_week: "esta semana" label_this_year: "este año" + label_time: "Time" label_time_entry_plural: "Tiempo invertido" label_time_entry_activity_plural: "Actividades de tiempo invertido" label_title: "Título" @@ -3777,6 +3786,12 @@ es: edit_description: "Puede ver, comentar y editar este paquete de trabajo." view: "Ver" view_description: "Puede ver este paquete de trabajo." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 usuarios" diff --git a/config/locales/crowdin/et.yml b/config/locales/crowdin/et.yml index af12d6a187b3..e0535f32c38c 100644 --- a/config/locales/crowdin/et.yml +++ b/config/locales/crowdin/et.yml @@ -855,6 +855,9 @@ et: lag: "Lag" from: "Teema" to: "Seotud teema" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ et: login: "Kasutajanimi" mail: "E-posti aadress" name: "Nimi" + note: "Note" password: "Parool" priority: "Prioriteet" project: "Projekt" @@ -1529,6 +1533,7 @@ et: button_print: "Prindi" button_quote: "Tsiteeri" button_remove: Eemalda + button_remove_reminder: "Remove reminder" button_rename: "Nimeta ümber" button_replace: "Asenda" button_revoke: "Võta tagasi" @@ -1539,6 +1544,7 @@ et: button_save_as: "Salvesta kui" button_apply_changes: "Apply changes" button_save_back: "Salvesta ja mine tagasi" + button_set_reminder: "Set reminder" button_show: "Kuva" button_sort: "Sorteeri" button_submit: "Sisesta" @@ -1744,12 +1750,12 @@ et: direction: vasakult paremale ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Teemade prioriteedid" enumeration_reported_project_statuses: "Esitatud projekti olek" @@ -1782,6 +1788,7 @@ et: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Teemat ei leitud või see ei kuulu siia projekti" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "peab olema projekti liige" @@ -2075,6 +2082,7 @@ et: responsible: "Accountable" shared: "Shared" watched: "Jälgija" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ et: label_delete: "Delete" label_deleted: "kustutatud" label_deleted_custom_field: "(kustutatud lisaväli)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(tühi)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ et: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Keskkond" label_estimates_and_progress: "Estimates and progress" label_equals: "võrdub" @@ -2630,6 +2638,7 @@ et: label_this_month: "sel kuul" label_this_week: "sel nädalal" label_this_year: "sel aastal" + label_time: "Time" label_time_entry_plural: "Kulutatud aeg" label_time_entry_activity_plural: "Spent time activities" label_title: "Pealkiri" @@ -3782,6 +3791,12 @@ et: edit_description: "Can view, comment and edit this work package." view: "Kuva" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/eu.yml b/config/locales/crowdin/eu.yml index 31d218243505..935d21275934 100644 --- a/config/locales/crowdin/eu.yml +++ b/config/locales/crowdin/eu.yml @@ -855,6 +855,9 @@ eu: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ eu: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ eu: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ eu: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ eu: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ eu: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ eu: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ eu: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ eu: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ eu: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3782,6 +3791,12 @@ eu: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/fa.yml b/config/locales/crowdin/fa.yml index f7c0a372481a..3f806358c02f 100644 --- a/config/locales/crowdin/fa.yml +++ b/config/locales/crowdin/fa.yml @@ -855,6 +855,9 @@ fa: lag: "Lag" from: "بسته کاری" to: "بسته کاری وابسته" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "نشانی اینترنت" role: @@ -1433,6 +1436,7 @@ fa: login: "نام كاربري" mail: "Email" name: "نام" + note: "Note" password: "کلمه عبور" priority: "اولويت" project: "پروژه" @@ -1529,6 +1533,7 @@ fa: button_print: "چاپ کردن" button_quote: "نقل قول" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "تغییر نام" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ fa: button_save_as: "ذخیره به عنوان" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "نمایش" button_sort: "مرتب‌سازی" button_submit: "ثبت کردن" @@ -1744,12 +1750,12 @@ fa: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ fa: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ fa: responsible: "Accountable" shared: "Shared" watched: "ناظر" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ fa: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ fa: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ fa: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "زمان صرف شده" label_time_entry_activity_plural: "Spent time activities" label_title: "عنوان" @@ -3782,6 +3791,12 @@ fa: edit_description: "Can view, comment and edit this work package." view: "مشاهده" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/fi.yml b/config/locales/crowdin/fi.yml index 932189e5bf3a..454732432516 100644 --- a/config/locales/crowdin/fi.yml +++ b/config/locales/crowdin/fi.yml @@ -855,6 +855,9 @@ fi: lag: "Lag" from: "Tehtävä" to: "Liittyy tehtävään" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ fi: login: "Käyttäjätunnus" mail: "Sähköposti" name: "Nimi" + note: "Note" password: "Salasana" priority: "Prioriteetti" project: "Projekti" @@ -1529,6 +1533,7 @@ fi: button_print: "Tulosta" button_quote: "Siteeraa" button_remove: Poista + button_remove_reminder: "Remove reminder" button_rename: "Nimeä uudelleen" button_replace: "Korvaa" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ fi: button_save_as: "Tallenna nimellä" button_apply_changes: "Apply changes" button_save_back: "Tallenna ja palaa" + button_set_reminder: "Set reminder" button_show: "Näytä" button_sort: "Järjestä" button_submit: "Lähetä" @@ -1744,12 +1750,12 @@ fi: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Ajanseurannan tapahtumat" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ fi: error_pdf_export_too_many_columns: "Liikaa sarakkeita valittuina PDF-vientiin. Pienennä sarakkeiden määrää." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Toimia paketti ei löydy tai ei kuulu tähän projektiin" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "on oltava projekti jäsen" @@ -2075,6 +2082,7 @@ fi: responsible: "Vastuuhenkilö" shared: "Shared" watched: "Seuraajat" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ fi: label_delete: "Delete" label_deleted: "poistettu" label_deleted_custom_field: "(poistettu mukautettu kenttä)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(tyhjä)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ fi: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Ympäristö" label_estimates_and_progress: "Estimates and progress" label_equals: "on" @@ -2630,6 +2638,7 @@ fi: label_this_month: "tässä kuussa" label_this_week: "tällä viikolla" label_this_year: "tänä vuonna" + label_time: "Time" label_time_entry_plural: "Käytetty aika" label_time_entry_activity_plural: "Spent time activities" label_title: "Otsikko" @@ -3782,6 +3791,12 @@ fi: edit_description: "Can view, comment and edit this work package." view: "Näytä" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/fil.yml b/config/locales/crowdin/fil.yml index 137b059bca1d..a93830ff88cc 100644 --- a/config/locales/crowdin/fil.yml +++ b/config/locales/crowdin/fil.yml @@ -855,6 +855,9 @@ fil: lag: "Lag" from: "Work package" to: "Ang kaugnayan sa pakete na ginagawa" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "Ang URL" role: @@ -1433,6 +1436,7 @@ fil: login: "Username" mail: "Email" name: "Pangalan" + note: "Note" password: "Password" priority: "Ang prayoridad" project: "Proyekto" @@ -1529,6 +1533,7 @@ fil: button_print: "I-print" button_quote: "Quote" button_remove: Tanggalin + button_remove_reminder: "Remove reminder" button_rename: "Baguhin ang pangalan" button_replace: "Palitan" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ fil: button_save_as: "I-save bilang" button_apply_changes: "Apply changes" button_save_back: "I-save at bumalik" + button_set_reminder: "Set reminder" button_show: "Ipakita" button_sort: "Ayusin" button_submit: "Sumite" @@ -1744,12 +1750,12 @@ fil: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Magdgdag ng mga bagong attribute na grupo" rename_groups: "Palitan ng pangalan ang mga grupong attribute" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Ang mga prioridad ng work package" enumeration_reported_project_statuses: "Estado ng inuulat na proyekto" @@ -1782,6 +1788,7 @@ fil: error_pdf_export_too_many_columns: "Masyadong maraming hanay ang napili para sa PDF export. Mangyaring bawasan ang mga bilang ng hanay." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Ang work package ay hindi natagpuan o hindi kabilang sa proyektong ito" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "dapat ay miyembro ng proyekto" @@ -2075,6 +2082,7 @@ fil: responsible: "Accountable" shared: "Shared" watched: "Tagapagmasid" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ fil: label_delete: "Delete" label_deleted: "binura" label_deleted_custom_field: "(binurang custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(walang laman)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ fil: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Kalikasan" label_estimates_and_progress: "Estimates and progress" label_equals: "ay" @@ -2630,6 +2638,7 @@ fil: label_this_month: "ngayong buwan" label_this_week: "ngayong semana" label_this_year: "ngayong taon" + label_time: "Time" label_time_entry_plural: "Nauubos na oras" label_time_entry_activity_plural: "Spent time activities" label_title: "Pamagat" @@ -3780,6 +3789,12 @@ fil: edit_description: "Can view, comment and edit this work package." view: "Tingnan" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml index 2d0bf6362443..cdbe611bcb75 100644 --- a/config/locales/crowdin/fr.yml +++ b/config/locales/crowdin/fr.yml @@ -853,6 +853,9 @@ fr: lag: "Délai" from: "Lot de travaux" to: "Lot de travaux associé" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1431,6 +1434,7 @@ fr: login: "Nom d'utilisateur" mail: "E-mail" name: "Nom" + note: "Note" password: "Mot de passe" priority: "Priorité" project: "Projet" @@ -1527,6 +1531,7 @@ fr: button_print: "Imprimer" button_quote: "Citer" button_remove: Supprimer + button_remove_reminder: "Remove reminder" button_rename: "Renommer" button_replace: "Remplacer" button_revoke: "Révoquer" @@ -1537,6 +1542,7 @@ fr: button_save_as: "Enregistrer sous" button_apply_changes: "Appliquer les modifications" button_save_back: "Enregistrer et revenir" + button_set_reminder: "Set reminder" button_show: "Afficher" button_sort: "Trier" button_submit: "Envoyer" @@ -1742,12 +1748,12 @@ fr: direction: de gauche à droite ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Personnaliser la configuration du formulaire avec ces add-ons supplémentaires :" add_groups: "Ajouter de nouveaux groupes d’attributs" rename_groups: "Renommer les groupes d’attributs" - project_filters: - description_html: "Le filtrage et le tri sur les champs personnalisés sont un add-on de l'édition Entreprise." enumeration_activities: "Activités de suivi du temps" enumeration_work_package_priorities: "Priorités du Lot de Travaux" enumeration_reported_project_statuses: "Statuts de projet signalés" @@ -1780,6 +1786,7 @@ fr: error_pdf_export_too_many_columns: "Trop de colonnes sélectionnées pour l’exportation PDF. Veuillez réduire le nombre de colonnes." error_pdf_failed_to_export: "L'export PDF n'a pas pu être enregistré: %{error}" error_token_authenticity: "Impossible de vérifier le jeton de Cross-Site Request Forgery. Avez-vous essayé d'envoyer des données sur plusieurs navigateurs ou onglets ? Veuillez fermer tous les onglets et réessayer." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Le Lot de Travaux n'a pas été trouvé ou n'appartient pas à ce projet" error_work_package_id_not_found: "Le lot de travaux n'a pas été trouvé." error_must_be_project_member: "doit être membre du projet" @@ -2073,6 +2080,7 @@ fr: responsible: "Responsable" shared: "Partagé" watched: "Observateur" + reminder: "Reminder" facets: unread: "Non lu" unread_title: "Afficher les messages non lus" @@ -2243,6 +2251,7 @@ fr: label_delete: "Delete" label_deleted: "supprimé" label_deleted_custom_field: "(champs personnalisés supprimés)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(option supprimée)" label_empty_element: "(vide)" label_missing_or_hidden_custom_option: "(valeur manquante ou manque d'autorisations d'accès)" @@ -2279,7 +2288,6 @@ fr: label_enterprise_active_users: "%{current}/%{limit} utilisateurs actifs inscrits" label_enterprise_edition: "Version Entreprise" label_enterprise_support: "Support Enterprise" - label_enterprise_addon: "add-on Enterprise" label_environment: "Environement" label_estimates_and_progress: "Estimations et progression" label_equals: "est" @@ -2628,6 +2636,7 @@ fr: label_this_month: "ce mois" label_this_week: "cette semaine" label_this_year: "cette année" + label_time: "Time" label_time_entry_plural: "Temps passé" label_time_entry_activity_plural: "Activités du temps passé" label_title: "Titre" @@ -3779,6 +3788,12 @@ fr: edit_description: "Peut consulter, commenter et modifier ce lot de travaux." view: "Voir" view_description: "Peut consulter ce lot de travaux." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 utilisateur" diff --git a/config/locales/crowdin/he.yml b/config/locales/crowdin/he.yml index df7db425c794..20f2daa8adef 100644 --- a/config/locales/crowdin/he.yml +++ b/config/locales/crowdin/he.yml @@ -871,6 +871,9 @@ he: lag: "Lag" from: "חבילת עבודה" to: "חבילת עבודה קשורה" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "כתובת URL" role: @@ -1469,6 +1472,7 @@ he: login: "Username" mail: "אימייל" name: "שם" + note: "Note" password: "סיסמה" priority: "עדיפות" project: "פרוייקט" @@ -1565,6 +1569,7 @@ he: button_print: "Print" button_quote: "צטט" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "שינוי שם" button_replace: "Replace" button_revoke: "Revoke" @@ -1575,6 +1580,7 @@ he: button_save_as: "שמירה בשם" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "הצג" button_sort: "מיין" button_submit: "שלח" @@ -1816,12 +1822,12 @@ he: direction: משמאל לימין ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "עדיפויות חבילת עבודה" enumeration_reported_project_statuses: "סטטוסים של הפרויקט המדווח" @@ -1854,6 +1860,7 @@ he: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "חבילת העבודה לא נמצאה או לא שייכת לפרוייקט זה" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "חייב להיות חבר בפרוייקט" @@ -2147,6 +2154,7 @@ he: responsible: "Accountable" shared: "Shared" watched: "צופה" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2317,6 +2325,7 @@ he: label_delete: "Delete" label_deleted: "נמחק" label_deleted_custom_field: "(למחוק שדה מותאם אישית)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2353,7 +2362,6 @@ he: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "סביבה" label_estimates_and_progress: "Estimates and progress" label_equals: "הינו" @@ -2702,6 +2710,7 @@ he: label_this_month: "החודש" label_this_week: "השבוע" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "זמן שבוזבז" label_time_entry_activity_plural: "Spent time activities" label_title: "כותרת" @@ -3860,6 +3869,12 @@ he: edit_description: "Can view, comment and edit this work package." view: "תצוגה" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/hi.yml b/config/locales/crowdin/hi.yml index b5d870a7367e..da1a55dbfb4d 100644 --- a/config/locales/crowdin/hi.yml +++ b/config/locales/crowdin/hi.yml @@ -853,6 +853,9 @@ hi: lag: "Lag" from: "कार्य पैकेज" to: "संबंधित कार्य पैकेज" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "यू आर एल" role: @@ -1431,6 +1434,7 @@ hi: login: "Username" mail: "ईमेल" name: "नाम" + note: "Note" password: "पासवर्ड" priority: "वरीयता" project: "परियोजना" @@ -1527,6 +1531,7 @@ hi: button_print: "Print" button_quote: "उद्धरण" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "नाम बदलें" button_replace: "Replace" button_revoke: "Revoke" @@ -1537,6 +1542,7 @@ hi: button_save_as: "के रूप में सहेजें..." button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "दिखाएँ" button_sort: "क्रम में लगायें" button_submit: "सबमिट करें" @@ -1742,12 +1748,12 @@ hi: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "रिपोर्ट की गई प्रोजेक्ट स्थिति" @@ -1780,6 +1786,7 @@ hi: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "क्रॉस-साइट अनुरोध जालसाज़ी टोकन सत्यापित करने में असमर्थ । क्या आपने एकाधिक ब्राउज़र्स या टैब पर डेटा सबमिट करने का प्रयास किया है? कृपया सभी टैब बंद करें और पुन: प्रयास करे ।" + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "कार्य पैकेज नहीं मिला, या इस प्रोजेक्ट से संबंधित नहीं है" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "प्रोजेक्ट सदस्य होना जरूरी है" @@ -2073,6 +2080,7 @@ hi: responsible: "जवाबदेह" shared: "Shared" watched: "वॉचर" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2243,6 +2251,7 @@ hi: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2279,7 +2288,6 @@ hi: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2628,6 +2636,7 @@ hi: label_this_month: "इस महीने" label_this_week: "इस सप्ताह" label_this_year: "इस वर्ष" + label_time: "Time" label_time_entry_plural: "समय बिताया" label_time_entry_activity_plural: "Spent time activities" label_title: "शीर्षक" @@ -3780,6 +3789,12 @@ hi: edit_description: "Can view, comment and edit this work package." view: "दृश्य" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/hr.yml b/config/locales/crowdin/hr.yml index 6230cec12fa6..b58e09f7575a 100644 --- a/config/locales/crowdin/hr.yml +++ b/config/locales/crowdin/hr.yml @@ -863,6 +863,9 @@ hr: lag: "Lag" from: "Radni paket" to: "Pripadajući radni paket" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1451,6 +1454,7 @@ hr: login: "Korisničko ime" mail: "Email" name: "Naziv" + note: "Note" password: "Lozinka" priority: "Prioritet" project: "Projekt" @@ -1547,6 +1551,7 @@ hr: button_print: "Ispis" button_quote: "Citiraj" button_remove: Ukloni + button_remove_reminder: "Remove reminder" button_rename: "Preimenuj" button_replace: "Zamijeni" button_revoke: "Revoke" @@ -1557,6 +1562,7 @@ hr: button_save_as: "Spremiti kao" button_apply_changes: "Apply changes" button_save_back: "Snimi i vratiti" + button_set_reminder: "Set reminder" button_show: "Prikaži" button_sort: "Sortiraj" button_submit: "Pošalji" @@ -1780,12 +1786,12 @@ hr: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Prioriteti radnog paketa" enumeration_reported_project_statuses: "Priopćeni statusi projekta" @@ -1818,6 +1824,7 @@ hr: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Radni paket nije pronađen ili ne pripada ovom projektu" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "mora biti član projekta" @@ -2111,6 +2118,7 @@ hr: responsible: "Accountable" shared: "Shared" watched: "Nadglednik" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2281,6 +2289,7 @@ hr: label_delete: "Delete" label_deleted: "izbrisano" label_deleted_custom_field: "(izbrisano prilagođeno polje)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(prazno)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2317,7 +2326,6 @@ hr: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Okruženje" label_estimates_and_progress: "Estimates and progress" label_equals: "je" @@ -2666,6 +2674,7 @@ hr: label_this_month: "ovaj mjesec" label_this_week: "ovog tjedna" label_this_year: "ove godine" + label_time: "Time" label_time_entry_plural: "Utrošeno vrijeme" label_time_entry_activity_plural: "Spent time activities" label_title: "Naziv" @@ -3821,6 +3830,12 @@ hr: edit_description: "Can view, comment and edit this work package." view: "Pregled" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/hu.yml b/config/locales/crowdin/hu.yml index 69b76aca2b26..71569a012a48 100644 --- a/config/locales/crowdin/hu.yml +++ b/config/locales/crowdin/hu.yml @@ -852,6 +852,9 @@ hu: lag: "Lag" from: "Feladatcsoport" to: "Kapcsolódó feladatcsoport" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1430,6 +1433,7 @@ hu: login: "Felhasználónév" mail: "Email" name: "Név" + note: "Note" password: "Jelszó" priority: "Fontosság" project: "Projekt" @@ -1526,6 +1530,7 @@ hu: button_print: "Nyomtatás" button_quote: "Idéz" button_remove: Eltávolítás + button_remove_reminder: "Remove reminder" button_rename: "Átnevezés" button_replace: "Csere" button_revoke: "Visszavonás" @@ -1536,6 +1541,7 @@ hu: button_save_as: "Mentés másként" button_apply_changes: "Változások alkalmazása" button_save_back: "Mentés és vissza" + button_set_reminder: "Set reminder" button_show: "Mutat" button_sort: "Rendez" button_submit: "Küldés" @@ -1741,12 +1747,12 @@ hu: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Testre szabhatja az űrlap konfigurációját ezekkel a további bővítményekkel:" add_groups: "Attribútum-csoport hozzáadása" rename_groups: "Attribútum-csoportok átnevezése" - project_filters: - description_html: "Az egyéni mezők szűrése és rendezése a Vállalati Verzió kiegészítője." enumeration_activities: "Időnyilvántartási tevékenységek" enumeration_work_package_priorities: "Feladatcsoport fontosság" enumeration_reported_project_statuses: "Projekt állapot beszámoló" @@ -1779,6 +1785,7 @@ hu: error_pdf_export_too_many_columns: "Túl sok oszlop lett kiválasztva a PDF exportáláshoz. Kérlek csökkentsd a sorok számát." error_pdf_failed_to_export: "A PDF-Exportálás mentése nem sikerült: %{error}" error_token_authenticity: "Nem sikerült ellenőrizni a Cross-Site Request Forgery token-t. Megpróbált adatokat küldeni több böngészőn vagy lapon keresztül? Kérjük, zárja be az összes lapot, és próbálkozzon újra." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "A feladatcsoport nem található, vagy nem tartozik ehhez a projekthez" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "projekt tagnak kell lennie" @@ -2072,6 +2079,7 @@ hu: responsible: "Felelős" shared: "Megosztva" watched: "Megfigyelő" + reminder: "Reminder" facets: unread: "Olvasatlan" unread_title: "Show unread" @@ -2242,6 +2250,7 @@ hu: label_delete: "Delete" label_deleted: "Törölve" label_deleted_custom_field: "(egyéni mező törölve)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opció törlése)" label_empty_element: "(üres)" label_missing_or_hidden_custom_option: "(hiányzó érték vagy a hozzáférési jogosultságok hiánya)\n" @@ -2278,7 +2287,6 @@ hu: label_enterprise_active_users: "%{current}/%{limit} foglalt aktív felhasználók" label_enterprise_edition: "Vállalati Verzió." label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Környezet" label_estimates_and_progress: "Estimates and progress" label_equals: "van" @@ -2627,6 +2635,7 @@ hu: label_this_month: "Ebben a hónapban" label_this_week: "ezen a héten" label_this_year: "Ebben az évben" + label_time: "Time" label_time_entry_plural: "Eltöltött idő" label_time_entry_activity_plural: "Spent time activities" label_title: "Cím" @@ -3778,6 +3787,12 @@ hu: edit_description: "Can view, comment and edit this work package." view: "Nézet" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/id.yml b/config/locales/crowdin/id.yml index 0779a0e3a55d..1f51a7d20e12 100644 --- a/config/locales/crowdin/id.yml +++ b/config/locales/crowdin/id.yml @@ -840,6 +840,9 @@ id: lag: "Lag" from: "Paket-Penugasan" to: "Work package terkait" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1408,6 +1411,7 @@ id: login: "Nama pengguna" mail: "Email" name: "Nama" + note: "Note" password: "Password" priority: "Prioritas" project: "Project" @@ -1504,6 +1508,7 @@ id: button_print: "Cetak" button_quote: "Kutipan" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Ubah nama" button_replace: "Ganti" button_revoke: "Menarik kembali" @@ -1514,6 +1519,7 @@ id: button_save_as: "Simpan sebagai" button_apply_changes: "Menerapkan perubahan" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Tampilkan" button_sort: "Urutkan" button_submit: "Kirim" @@ -1701,12 +1707,12 @@ id: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Menambahkan atribut kelompok-kelompok baru" rename_groups: "Menamai ulang atribut kelompok-kelompok" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Kegiatan pelacakan waktu" enumeration_work_package_priorities: "Paket-Penugasan prioritas" enumeration_reported_project_statuses: "Status Project yang di-Report" @@ -1739,6 +1745,7 @@ id: error_pdf_export_too_many_columns: "Kolom yang dipilih utnuk ekspor PDF terlalu banyak. Mohon kurangi jumlah kolom." error_pdf_failed_to_export: "Ekspor PDF tidak dapat disimpan: %{error}" error_token_authenticity: "Tidak dapat memverifikasi token Pemalsuan Permintaan Lintas Situs. Apakah Anda mencoba mengirimkan data di beberapa browser atau tab? Harap tutup semua tab dan coba lagi." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Paket-Penugasan tidak ditemukan atau tidak termasuk dalam Project ini" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "harus sbg Project Member" @@ -2032,6 +2039,7 @@ id: responsible: "Akuntabel" shared: "Shared" watched: "Pemantau" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2202,6 +2210,7 @@ id: label_delete: "Delete" label_deleted: "dihapus" label_deleted_custom_field: "(isian kustom dihapus)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opsi dihapus)" label_empty_element: "(kosong)" label_missing_or_hidden_custom_option: "(nilai hilang atau kurang izin untuk mengakses)" @@ -2238,7 +2247,6 @@ id: label_enterprise_active_users: "%{current}/%{limit} pengguna aktif yang dipesan" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Dukungan perusahaan" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "adalah" @@ -2587,6 +2595,7 @@ id: label_this_month: "bulan ini" label_this_week: "minggu ini" label_this_year: "tahun ini" + label_time: "Time" label_time_entry_plural: "Durasi" label_time_entry_activity_plural: "Spent time activities" label_title: "Judul" @@ -3733,6 +3742,12 @@ id: edit_description: "Can view, comment and edit this work package." view: "Lihat" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/it.yml b/config/locales/crowdin/it.yml index 4f88f91d8791..f210e52b9899 100644 --- a/config/locales/crowdin/it.yml +++ b/config/locales/crowdin/it.yml @@ -851,6 +851,9 @@ it: lag: "Ritardo" from: "Macro-attività" to: "Macro-attività correlata" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1429,6 +1432,7 @@ it: login: "Nome utente" mail: "Email" name: "Nome" + note: "Note" password: "Password" priority: "Priorità" project: "Progetto" @@ -1525,6 +1529,7 @@ it: button_print: "Stampa" button_quote: "Cita" button_remove: Rimuovi + button_remove_reminder: "Remove reminder" button_rename: "Rinomina" button_replace: "Sostituisci" button_revoke: "Revoca" @@ -1535,6 +1540,7 @@ it: button_save_as: "Salva come" button_apply_changes: "Applica modifiche" button_save_back: "Salva e ritorna" + button_set_reminder: "Set reminder" button_show: "Mostra" button_sort: "Ordina" button_submit: "Invia" @@ -1740,12 +1746,12 @@ it: direction: da sinistra a destra ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Personalizza la configurazione del modulo con le seguenti aggiunte:" add_groups: "Aggiunta di gruppi di proprietà" rename_groups: "Rinominazione di gruppi di proprietà" - project_filters: - description_html: "Le opzioni di filtraggio e ordinamento dei campi personalizzati sono disponibili nella versione Enterprise." enumeration_activities: "Attività di monitoraggio dei tempi" enumeration_work_package_priorities: "Priorità della macro-attività" enumeration_reported_project_statuses: "Stato di progetto segnalato" @@ -1778,6 +1784,7 @@ it: error_pdf_export_too_many_columns: "Troppe colonne selezionate per l'esportazione in PDF. Ridurre il numero di colonne." error_pdf_failed_to_export: "L'esportazione del PDF non può essere salvata: %{error}" error_token_authenticity: "Impossibile verificare il token di richiesta. Forse hai provato a inviare i dati da più browser o schede? Chiudi tutte le schede e riprova." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "La macro-attività non è stata trovata o non appartiene a questo progetto" error_work_package_id_not_found: "Impossibile trovare la macro-attività." error_must_be_project_member: "deve essere membro del progetto" @@ -2071,6 +2078,7 @@ it: responsible: "Responsabile" shared: "Condiviso" watched: "Osservatore" + reminder: "Reminder" facets: unread: "Non letta" unread_title: "Mostra non lette" @@ -2241,6 +2249,7 @@ it: label_delete: "Delete" label_deleted: "cancellato" label_deleted_custom_field: "(campo personalizzato eliminato)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opzione eliminata)" label_empty_element: "(vuoto)" label_missing_or_hidden_custom_option: "(valore mancante o assenza di permessi di accesso)" @@ -2277,7 +2286,6 @@ it: label_enterprise_active_users: "%{current}/%{limit} utenti attivi riservati" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Supporto per Imprese" - label_enterprise_addon: "Componente aggiuntivo Enterprise" label_environment: "Ambiente" label_estimates_and_progress: "Stime e progressi" label_equals: "è" @@ -2626,6 +2634,7 @@ it: label_this_month: "questo mese" label_this_week: "questa settimana" label_this_year: "questo anno" + label_time: "Time" label_time_entry_plural: "Tempo speso" label_time_entry_activity_plural: "Attività che richiedono tempo" label_title: "Titolo" @@ -3778,6 +3787,12 @@ it: edit_description: "Può visu" view: "Visualizzare" view_description: "Può visualizzare questa macro-attività." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 utenti" diff --git a/config/locales/crowdin/ja.yml b/config/locales/crowdin/ja.yml index 3b9e2e342597..972607eeab96 100644 --- a/config/locales/crowdin/ja.yml +++ b/config/locales/crowdin/ja.yml @@ -843,6 +843,9 @@ ja: lag: "Lag" from: "ワーク パッケージ" to: "関係するワークパッケージ" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1411,6 +1414,7 @@ ja: login: "ユーザー名" mail: "電子メールアドレス" name: "名称" + note: "Note" password: "パスワード" priority: "優先度" project: "プロジェクト" @@ -1507,6 +1511,7 @@ ja: button_print: "印刷" button_quote: "引用" button_remove: 削除 + button_remove_reminder: "Remove reminder" button_rename: "名称変更" button_replace: "置き換え" button_revoke: "取り消し" @@ -1517,6 +1522,7 @@ ja: button_save_as: "名前をつけて保存" button_apply_changes: "Apply changes" button_save_back: "保存して戻る" + button_set_reminder: "Set reminder" button_show: "表示" button_sort: "並べ替え" button_submit: "適用" @@ -1704,12 +1710,12 @@ ja: direction: 左から右 ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "これらの追加機能でフォームの設定をカスタマイズします:" add_groups: "新しい属性グループを追加" rename_groups: "属性グループの名前を変更" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "タイムトラッキングアクティビティ" enumeration_work_package_priorities: "ワークパッケージの優先度" enumeration_reported_project_statuses: "報告されるプロジェクト進捗状況" @@ -1742,6 +1748,7 @@ ja: error_pdf_export_too_many_columns: "PDF エクスポート用に選択された列が多すぎます。 列の数を減らしてください。" error_pdf_failed_to_export: "PDFエクスポートを保存できませんでした: %{error}" error_token_authenticity: "クロスサイトリクエスト偽造トークンを確認できません。 複数のブラウザやタブでデータを送信しようとしましたか? すべてのタブを閉じてもう一度やり直してください。" + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "ワークパッケージが見つからないか、このプロジェクトに属していません。" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "プロジェクトのメンバーである必要があります。" @@ -2035,6 +2042,7 @@ ja: responsible: "責任者" shared: "Shared" watched: "ウォッチャー" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2205,6 +2213,7 @@ ja: label_delete: "Delete" label_deleted: "削除された" label_deleted_custom_field: "(削除されたカスタムフィールド)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(削除されたオプション)" label_empty_element: "(空)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2241,7 +2250,6 @@ ja: label_enterprise_active_users: "%{current}/%{limit} 予約済みのアクティブユーザー" label_enterprise_edition: "エンタープライズ版" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "環境" label_estimates_and_progress: "Estimates and progress" label_equals: "等しい" @@ -2590,6 +2598,7 @@ ja: label_this_month: "今月" label_this_week: "今週" label_this_year: "今年" + label_time: "Time" label_time_entry_plural: "作業時間の記録" label_time_entry_activity_plural: "Spent time activities" label_title: "タイトル" @@ -3738,6 +3747,12 @@ ja: edit_description: "Can view, comment and edit this work package." view: "表示" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/js-af.yml b/config/locales/crowdin/js-af.yml index 7fd6e036bf10..aee75fb4981b 100644 --- a/config/locales/crowdin/js-af.yml +++ b/config/locales/crowdin/js-af.yml @@ -654,6 +654,8 @@ af: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ af: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-ar.yml b/config/locales/crowdin/js-ar.yml index 0408453c40dd..2152b2aa895f 100644 --- a/config/locales/crowdin/js-ar.yml +++ b/config/locales/crowdin/js-ar.yml @@ -658,6 +658,8 @@ ar: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1048,6 +1050,12 @@ ar: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-az.yml b/config/locales/crowdin/js-az.yml index 3a3dd4bae062..5fb529e005d1 100644 --- a/config/locales/crowdin/js-az.yml +++ b/config/locales/crowdin/js-az.yml @@ -654,6 +654,8 @@ az: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ az: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-be.yml b/config/locales/crowdin/js-be.yml index 57cdef866995..042b76112cfb 100644 --- a/config/locales/crowdin/js-be.yml +++ b/config/locales/crowdin/js-be.yml @@ -656,6 +656,8 @@ be: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1046,6 +1048,12 @@ be: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-bg.yml b/config/locales/crowdin/js-bg.yml index 217b6240570b..8717fec8c84f 100644 --- a/config/locales/crowdin/js-bg.yml +++ b/config/locales/crowdin/js-bg.yml @@ -654,6 +654,8 @@ bg: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ bg: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Датите на този работен пакет се извеждат автоматично от неговите деца. Активирайте „Ръчно планиране“, за да зададете датите." is_switched_from_manual_to_automatic: "Датите на този работен пакет може да се наложи да бъдат преизчислени след преминаване от ръчно към автоматично планиране поради връзки с други работни пакети." diff --git a/config/locales/crowdin/js-ca.yml b/config/locales/crowdin/js-ca.yml index 6bc7e7f56a35..c332318bc09d 100644 --- a/config/locales/crowdin/js-ca.yml +++ b/config/locales/crowdin/js-ca.yml @@ -654,6 +654,8 @@ ca: new_notifications: message: "No hi ha notificacions noves" link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Pots modificar la teva configuració de notificacions per assegurar-te que mai et perds informació important.' title: "Configuració de notificacions" @@ -1044,6 +1046,12 @@ ca: not_found: "No existeix aquesta vista" duplicate_query_title: "El nom de la vista ja existeix. Canvia de totes formes?" text_no_results: "No hi ha vistes que coincideixin" + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Les dates d'aquest paquet de treball estan derivades automàticament dels seus fills. Activa la \"Planificació manual\" per canviar les dates." is_switched_from_manual_to_automatic: "Pot ser que les dates d'aquest paquet de treball no es tornin a calcular automàticament en canviar de planificació manual a automàtica a causa de les relacions amb altres paquets de treball." diff --git a/config/locales/crowdin/js-ckb-IR.yml b/config/locales/crowdin/js-ckb-IR.yml index f0487c4d7ea9..828b3083ba32 100644 --- a/config/locales/crowdin/js-ckb-IR.yml +++ b/config/locales/crowdin/js-ckb-IR.yml @@ -654,6 +654,8 @@ ckb-IR: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ ckb-IR: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-cs.yml b/config/locales/crowdin/js-cs.yml index bd211c20e2ef..a95ad32a184f 100644 --- a/config/locales/crowdin/js-cs.yml +++ b/config/locales/crowdin/js-cs.yml @@ -655,6 +655,8 @@ cs: new_notifications: message: "Máte nová oznámení." link_text: "Klikněte zde pro jejich načtení." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Můžete změnit nastavení oznámení , abyste se ujistili, že nikdy nezmeškáte důležitou aktualizaci.' title: "Nastavení oznámení" @@ -1045,6 +1047,12 @@ cs: not_found: "Neexistuje takové zobrazení" duplicate_query_title: "Název tohoto zobrazení již existuje. Chcete přesto změnit?" text_no_results: "Nebyly nalezeny žádné odpovídající zobrazení." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Data tohoto pracovního balíčku jsou automaticky odvozena od jeho dětí. Aktivujte 'Manuální plánování' pro ručné nastavení dat." is_switched_from_manual_to_automatic: "Data tohoto pracovního balíčku budou možná muset být přepočítána po přepnutí z manuálu na automatické plánování kvůli vztahům s ostatními pracovními balíčky." diff --git a/config/locales/crowdin/js-da.yml b/config/locales/crowdin/js-da.yml index 8d0c35e652ba..c69c399ff73e 100644 --- a/config/locales/crowdin/js-da.yml +++ b/config/locales/crowdin/js-da.yml @@ -653,6 +653,8 @@ da: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1043,6 +1045,12 @@ da: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-de.yml b/config/locales/crowdin/js-de.yml index e108c635a2e9..a81d21bc7697 100644 --- a/config/locales/crowdin/js-de.yml +++ b/config/locales/crowdin/js-de.yml @@ -653,6 +653,8 @@ de: new_notifications: message: "Es gibt neue Benachrichtigungen." link_text: "Hier klicken zum Aktualisieren." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Sie können Ihre Benachrichtigungseinstellungen ändern, um sicherzustellen, dass Sie keine wichtige Aktualisierung verpassen.' title: "Benachrichtigungseinstellungen" @@ -1043,6 +1045,12 @@ de: not_found: "Diese Ansicht konnte nicht gefunden werden" duplicate_query_title: "Eine Ansicht mit diesem Namen existiert bereits. Trotzdem ändern?" text_no_results: "Keine übereinstimmenden Ansichten gefunden." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Die Termine dieses Arbeitspakets werden automatisch von seinen Kindern aggregiert. Aktivieren Sie \"Manuelle Planung\", um die Termine frei zu setzen." is_switched_from_manual_to_automatic: "Die Termine dieses Arbeitspakets müssen nach dem Wechsel auf automatische Planung neu berechnet werden." diff --git a/config/locales/crowdin/js-el.yml b/config/locales/crowdin/js-el.yml index 144e3c72e0e8..547136ae70c6 100644 --- a/config/locales/crowdin/js-el.yml +++ b/config/locales/crowdin/js-el.yml @@ -653,6 +653,8 @@ el: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1043,6 +1045,12 @@ el: not_found: "Δεν υπάρχει τέτοια προβολή" duplicate_query_title: "Το όνομα αυτής της προβολής υπάρχει ήδη. Αλλαγή παρόλα αυτά;" text_no_results: "Δεν βρέθηκαν προβολές που να ταιριάζουν." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Οι ημερομηνίες αυτού του πακέτου εργασίας προκύπτουν αυτόματα από τα παιδιά του. Ενεργοποιήστε τον \"Χειροκίνητο προγραμματισμό\" για να ορίσετε τις ημερομηνίες." is_switched_from_manual_to_automatic: "Οι ημερομηνίες αυτού του πακέτου εργασίας μπορεί να χρειαστεί να υπολογιστούν εκ νέου μετά τη μετάβαση από χειροκίνητο σε αυτόματο προγραμματισμό λόγω των σχέσεων με άλλα πακέτα εργασίας." diff --git a/config/locales/crowdin/js-eo.yml b/config/locales/crowdin/js-eo.yml index b905e6be6b6b..697a1272a5aa 100644 --- a/config/locales/crowdin/js-eo.yml +++ b/config/locales/crowdin/js-eo.yml @@ -654,6 +654,8 @@ eo: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ eo: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-es.yml b/config/locales/crowdin/js-es.yml index 6e165a1f1d56..181ab2e459b7 100644 --- a/config/locales/crowdin/js-es.yml +++ b/config/locales/crowdin/js-es.yml @@ -654,6 +654,8 @@ es: new_notifications: message: "Hay nuevas notificaciones." link_text: "Haga clic aquí para cargarlas." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Puede modificar su configuración de notificaciones para asegurarse que nunca se pierda una actualización importante.' title: "Ajustes de notificación" @@ -1044,6 +1046,12 @@ es: not_found: "No existe la vista" duplicate_query_title: "El nombre de la vista ya existe. ¿Quiere cambiarlo de todos modos?" text_no_results: "No se encontraron vistas que coincidan." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Las fechas de este paquete de trabajo son deducidas automáticamente de sus sub-elementos. Active 'Programación manual' para establecer las fechas." is_switched_from_manual_to_automatic: "Las fechas de este paquete de trabajo pueden necesitar ser recalculadas después de pasar de programación manual a programación automática debido a las relaciones con otros paquetes de trabajo." diff --git a/config/locales/crowdin/js-et.yml b/config/locales/crowdin/js-et.yml index 51be9d97a36f..d00ba33c9a60 100644 --- a/config/locales/crowdin/js-et.yml +++ b/config/locales/crowdin/js-et.yml @@ -654,6 +654,8 @@ et: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ et: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-eu.yml b/config/locales/crowdin/js-eu.yml index d78dfbaac1d1..dda917b0a670 100644 --- a/config/locales/crowdin/js-eu.yml +++ b/config/locales/crowdin/js-eu.yml @@ -654,6 +654,8 @@ eu: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ eu: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-fa.yml b/config/locales/crowdin/js-fa.yml index 4630f177c66c..b964e2030cd4 100644 --- a/config/locales/crowdin/js-fa.yml +++ b/config/locales/crowdin/js-fa.yml @@ -654,6 +654,8 @@ fa: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ fa: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-fi.yml b/config/locales/crowdin/js-fi.yml index 87089c8df960..a7d4845e985d 100644 --- a/config/locales/crowdin/js-fi.yml +++ b/config/locales/crowdin/js-fi.yml @@ -654,6 +654,8 @@ fi: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ fi: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-fil.yml b/config/locales/crowdin/js-fil.yml index 065012a95b55..21184fb0fb56 100644 --- a/config/locales/crowdin/js-fil.yml +++ b/config/locales/crowdin/js-fil.yml @@ -654,6 +654,8 @@ fil: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ fil: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-fr.yml b/config/locales/crowdin/js-fr.yml index 3c1bffc7f754..2458c0dae425 100644 --- a/config/locales/crowdin/js-fr.yml +++ b/config/locales/crowdin/js-fr.yml @@ -654,6 +654,8 @@ fr: new_notifications: message: "Il y a de nouvelles notifications." link_text: "Cliquez ici pour les télécharger." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Vous pouvez modifier vos paramètres de notification pour vous assurer de ne jamais manquer une mise à jour importante.' title: "Paramètres de notifications" @@ -1044,6 +1046,12 @@ fr: not_found: "Cette vue n'existe pas" duplicate_query_title: "Le nom de cette vue existe déjà. Changer quand même ?" text_no_results: "Aucune vue correspondante n'a été trouvée." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Les dates de ce lot de travaux sont automatiquement déduites de ses enfants. Activez la « Planification manuelle » pour définir les dates." is_switched_from_manual_to_automatic: "Les dates de ce lot de travaux peuvent avoir besoin d'être recalculées après avoir passé de la planification manuelle à la planification automatique en raison de relations avec d'autres lots de travaux." diff --git a/config/locales/crowdin/js-he.yml b/config/locales/crowdin/js-he.yml index 21cbe60d7632..30b34a8824fa 100644 --- a/config/locales/crowdin/js-he.yml +++ b/config/locales/crowdin/js-he.yml @@ -656,6 +656,8 @@ he: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1046,6 +1048,12 @@ he: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-hi.yml b/config/locales/crowdin/js-hi.yml index b8f206c77fc2..f61c8dfe9442 100644 --- a/config/locales/crowdin/js-hi.yml +++ b/config/locales/crowdin/js-hi.yml @@ -654,6 +654,8 @@ hi: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ hi: not_found: "ऐसा कोई दृश्य नहीं है" duplicate_query_title: "इस दृश्य का नाम पहले से मौजूद है । वैसे भी बदल?" text_no_results: "कोई मेल खाता दृश्य नहीं मिले ।" + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-hr.yml b/config/locales/crowdin/js-hr.yml index 0583452e82b6..868028be14f1 100644 --- a/config/locales/crowdin/js-hr.yml +++ b/config/locales/crowdin/js-hr.yml @@ -655,6 +655,8 @@ hr: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1045,6 +1047,12 @@ hr: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-hu.yml b/config/locales/crowdin/js-hu.yml index b9dd5834da26..fa0565c07a67 100644 --- a/config/locales/crowdin/js-hu.yml +++ b/config/locales/crowdin/js-hu.yml @@ -654,6 +654,8 @@ hu: new_notifications: message: "Új értesítések érkeztek." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Értesítési beállítások" @@ -1044,6 +1046,12 @@ hu: not_found: "Nincs ilyen nézet" duplicate_query_title: "A nézet neve már létezik. Biztos megváltoztatod?" text_no_results: "Nem található egyező nézet" + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "A munkacsomag dátumait automatikusan levezetik a gyermekeiből. A dátumok beállításához aktiválja a „Kézi ütemezést”" is_switched_from_manual_to_automatic: "Ennek a munkacsomagnak a dátumait újra kell kalkulálni, miután a kézi üzemmódról az automatikus ütemezésre váltott, más munkacsomagokkal való kapcsolat miatt.\n" diff --git a/config/locales/crowdin/js-id.yml b/config/locales/crowdin/js-id.yml index ce560dbb0424..8bc8ce6e95ad 100644 --- a/config/locales/crowdin/js-id.yml +++ b/config/locales/crowdin/js-id.yml @@ -653,6 +653,8 @@ id: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1043,6 +1045,12 @@ id: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-it.yml b/config/locales/crowdin/js-it.yml index 7c6ebf5a06b4..3d38334d9a90 100644 --- a/config/locales/crowdin/js-it.yml +++ b/config/locales/crowdin/js-it.yml @@ -654,6 +654,8 @@ it: new_notifications: message: "Ci sono nuove notifiche." link_text: "Clicca qui per caricarli." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Puoi modificare le tue impostazioni di notifica per assicurarti di non perderti mai un aggiornamento importante.' title: "Impostazioni notifiche" @@ -1044,6 +1046,12 @@ it: not_found: "La vista non esiste" duplicate_query_title: "Il nome di questa vista è già esistente. Cambiarlo comunque?" text_no_results: "Nessuna vista corrispondente trovata." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Le date di questa macro-attività vengono automaticamente dedotte dai suoi figli. Attiva 'Programmazione manuale' per impostare le date." is_switched_from_manual_to_automatic: "Potrebbe essere necessario ricalcolare le date di questa macro-attività dopo il passaggio dalla programmazione manuale alla programmazione automatica a causa delle relazioni con altre macro-attività." diff --git a/config/locales/crowdin/js-ja.yml b/config/locales/crowdin/js-ja.yml index e267a402c9fa..850f22db3d11 100644 --- a/config/locales/crowdin/js-ja.yml +++ b/config/locales/crowdin/js-ja.yml @@ -654,6 +654,8 @@ ja: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ ja: not_found: "そのようなビューはありません" duplicate_query_title: "このビューの名前は既に存在します。 とにかく変更しますか?" text_no_results: "一致するビューは見つかりませんでした。" + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "このワークパッケージの日付は、その子から自動的に推定されます。日付を設定するには、「手動スケジューリング」を有効にします。" is_switched_from_manual_to_automatic: "他のワークパッケージとの関連により、手動スケジューリングから自動スケジューリングに切り替えた後に、このワークパッケージの日付を再計算する必要がある場合があります。" diff --git a/config/locales/crowdin/js-ka.yml b/config/locales/crowdin/js-ka.yml index 56054a9e8ed5..fe8c484b9956 100644 --- a/config/locales/crowdin/js-ka.yml +++ b/config/locales/crowdin/js-ka.yml @@ -654,6 +654,8 @@ ka: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ ka: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-kk.yml b/config/locales/crowdin/js-kk.yml index 9c566be069d5..7213234c9f86 100644 --- a/config/locales/crowdin/js-kk.yml +++ b/config/locales/crowdin/js-kk.yml @@ -654,6 +654,8 @@ kk: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ kk: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-ko.yml b/config/locales/crowdin/js-ko.yml index 994cec5e634e..fc10cca7cd79 100644 --- a/config/locales/crowdin/js-ko.yml +++ b/config/locales/crowdin/js-ko.yml @@ -653,6 +653,8 @@ ko: new_notifications: message: "새 알림이 있습니다." link_text: "로드하려면 여기를 클릭하세요." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: '중요 업데이트를 놓치지 않도록 알림 설정을 수정할 수 있습니다.' title: "알림 설정" @@ -1043,6 +1045,12 @@ ko: not_found: "해당 보기가 없습니다." duplicate_query_title: "이 보기의 이름이 이미 존재합니다. 그래도 변경하시겠습니까?" text_no_results: "일치하는 보기가 없습니다." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "이 작업 패키지의 날짜는 자식으로부터 자동으로 추정됩니다. '수동 스케줄링'을 활성화하여 날짜를 설정할 수 있습니다." is_switched_from_manual_to_automatic: "다른 작업 패키지와의 관계로 인해 수동 스케줄링에서 자동 스케줄링으로 전환한 후 이 작업 패키지의 날짜를 다시 계산해야 할 수 있습니다." diff --git a/config/locales/crowdin/js-lt.yml b/config/locales/crowdin/js-lt.yml index 5171ed37fd4f..5dfbd388faa3 100644 --- a/config/locales/crowdin/js-lt.yml +++ b/config/locales/crowdin/js-lt.yml @@ -656,6 +656,8 @@ lt: new_notifications: message: "Yra naujų pranešimų." link_text: "Spauskite čia, kad juos įkeltumėte." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Jūs galite keisti savo pranešimų nustatymus, kad užtikrintumėte, jog niekada nepraleisite svarbaus atnaujinimo.' title: "Pranešimų nustatymai" @@ -1046,6 +1048,12 @@ lt: not_found: "Nėra tokio vaizdo" duplicate_query_title: "Toks vaizdo vardas jau yra. Vis tiek keisti?" text_no_results: "Atitinkančių vaizdų nerasta." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Šio darbų paketo datos yra automatiškai nustatomos pagal jo vaikų datas. Norėdami nustatyti kitokias datas įjunkite „Rankinį tvarkaraščio parinkimą“" is_switched_from_manual_to_automatic: "Po perjungimo iš rankinio į automatinį tvarkaraščio parinkimą, šio darbų paketo datas gali reikėti perskaičiuoti, nes yra sąryšių su kitais darbų paketais." diff --git a/config/locales/crowdin/js-lv.yml b/config/locales/crowdin/js-lv.yml index 170eccb67c8a..273720bebd06 100644 --- a/config/locales/crowdin/js-lv.yml +++ b/config/locales/crowdin/js-lv.yml @@ -655,6 +655,8 @@ lv: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1045,6 +1047,12 @@ lv: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-mn.yml b/config/locales/crowdin/js-mn.yml index 0366ebb0c55b..0762e4161108 100644 --- a/config/locales/crowdin/js-mn.yml +++ b/config/locales/crowdin/js-mn.yml @@ -654,6 +654,8 @@ mn: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ mn: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-ms.yml b/config/locales/crowdin/js-ms.yml index 8f1b40598f61..71a37a82e4e7 100644 --- a/config/locales/crowdin/js-ms.yml +++ b/config/locales/crowdin/js-ms.yml @@ -653,6 +653,8 @@ ms: new_notifications: message: "Terdapat pemberitahuan baharu." link_text: "Klik sini untuk memuatkan mereka." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Anda boleh mengubah suai tetapan pemberitahuan anda untuk memastikan anda tidak terlepas tarikh yang penting.' title: "Tetapan pemberitahuan" @@ -1043,6 +1045,12 @@ ms: not_found: "Tiada paparan seperti itu" duplicate_query_title: "Nama paparan ini sudah wujud. Tukar juga?" text_no_results: "Tiada paparan yang sepadan ditemui." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Tarikh pakej kerja ini disimpulkan secara automatik dari anaknya. Aktifkan 'Penjadualan Manual' untuk tetapkan tarikh." is_switched_from_manual_to_automatic: "Tarikh pakej kerja ini mungkin perlu dikira semula selepas menukar dari penjadualan manual ke automatik kerana hubungan dengan pakej kerja lain." diff --git a/config/locales/crowdin/js-ne.yml b/config/locales/crowdin/js-ne.yml index 955b4551aa99..3d7baf4299d5 100644 --- a/config/locales/crowdin/js-ne.yml +++ b/config/locales/crowdin/js-ne.yml @@ -654,6 +654,8 @@ ne: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ ne: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-nl.yml b/config/locales/crowdin/js-nl.yml index 0d8ecf544b6a..bb06d79e54b7 100644 --- a/config/locales/crowdin/js-nl.yml +++ b/config/locales/crowdin/js-nl.yml @@ -654,6 +654,8 @@ nl: new_notifications: message: "Er zijn nieuwe meldingen." link_text: "Klik hier om ze te laden." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Instellingen voor meldingen" @@ -1044,6 +1046,12 @@ nl: not_found: "Deze weergave bestaat niet" duplicate_query_title: "Naam van deze weergave bestaat al. Toch wijzigen?" text_no_results: "Geen overeenkomende weergaven werden gevonden." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-no.yml b/config/locales/crowdin/js-no.yml index d8b9aeece342..e9b5c6980fc2 100644 --- a/config/locales/crowdin/js-no.yml +++ b/config/locales/crowdin/js-no.yml @@ -654,6 +654,8 @@ new_notifications: message: "Det finnes nye varsler." link_text: "Klikk her for å laste dem" + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Du kan endre varslingsinnstillinger for å sikre at du aldri går glipp av en viktig oppdatering.' title: "Varslingsinnstillinger" @@ -1044,6 +1046,12 @@ not_found: "Det finnes ingen slik visning." duplicate_query_title: "Navnet på denne visningen finnes allerede. Endre allikevel?" text_no_results: "Ingen samsvarende visninger ble funnet." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Datoene for denne arbeidspakken trekkes automatisk fra de underordnede. Aktiver 'Manuell planlegging' for å angi datoene." is_switched_from_manual_to_automatic: "Datoene for denne arbeidspakken må eventuelt beregnes på nytt etter å ha byttet fra manual til automatisk planlegging på grunn av relasjoner med andre arbeidspakker." diff --git a/config/locales/crowdin/js-pl.yml b/config/locales/crowdin/js-pl.yml index 84bda290c18a..ad7bda0dedd9 100644 --- a/config/locales/crowdin/js-pl.yml +++ b/config/locales/crowdin/js-pl.yml @@ -656,6 +656,8 @@ pl: new_notifications: message: "Masz nowe powiadomienia." link_text: "Kliknij tutaj, aby je załadować." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Możesz zmodyfikować ustawienia powiadomień, aby upewnić się, że nigdy nie przegapisz ważnej aktualizacji.' title: "Ustawienia powiadomień" @@ -1046,6 +1048,12 @@ pl: not_found: "Nie ma takiego widoku" duplicate_query_title: "Nazwa tego widoku już istnieje. Zmienić mimo to?" text_no_results: "Nie znaleziono żadnych pasujących widoków." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Daty tego pakietu roboczego są automatycznie odejmowane od jego elementów podrzędnych. Włącz funkcję Planowanie ręczne, aby ustawić daty." is_switched_from_manual_to_automatic: "Po przełączeniu planowania z ręcznego na automatyczne konieczne może być ponowne obliczenie dat tego pakietu roboczego ze względu na jego powiązania z innymi pakietami roboczymi." diff --git a/config/locales/crowdin/js-pt-BR.yml b/config/locales/crowdin/js-pt-BR.yml index 0d0e805d19b4..3c2be90426b7 100644 --- a/config/locales/crowdin/js-pt-BR.yml +++ b/config/locales/crowdin/js-pt-BR.yml @@ -653,6 +653,8 @@ pt-BR: new_notifications: message: "Há novas notificações." link_text: "Clique aqui para carregá-las." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Você pode modificar suas configurações de notificação para se certificar de nunca perder nenhuma atualização importante.' title: "Configurações de notificação" @@ -1043,6 +1045,12 @@ pt-BR: not_found: "Esta visão não existe" duplicate_query_title: "O nome desta visão já existe. Modificar assim mesmo?" text_no_results: "Nenhuma visão correspondente foi encontrada." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "As datas deste pacote de trabalho são deduzidas automaticamente de seus filhos. Ative o 'Planejamento manual' para definir as datas." is_switched_from_manual_to_automatic: "As datas deste pacote de trabalho podem precisar ser recalculadas após a alteração de planejamento manual para automático devido a relações com outros pacotes de trabalho." diff --git a/config/locales/crowdin/js-pt-PT.yml b/config/locales/crowdin/js-pt-PT.yml index 6171ba3ac1bb..e8a4b900feba 100644 --- a/config/locales/crowdin/js-pt-PT.yml +++ b/config/locales/crowdin/js-pt-PT.yml @@ -654,6 +654,8 @@ pt-PT: new_notifications: message: "Há novas notificações." link_text: "Clique aqui para carregá-las." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Pode modificar as suas definições de notificações para garantir que nunca perde uma atualização importante.' title: "Definições das notificações" @@ -1044,6 +1046,12 @@ pt-PT: not_found: "Não existe tal visualização" duplicate_query_title: "O nome desta visualização já existe. Mudar de qualquer forma?" text_no_results: "Não foram encontradas visualizações correspondentes." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "As datas deste pacote de trabalho são deduzidas automaticamente dos seus filhos. Ative o 'Agendamento manual' para definir as datas." is_switched_from_manual_to_automatic: "As datas deste pacote de trabalho podem precisar de ser recalculadas após mudar de agendamento manual para automático, devido a relações com outros pacotes de trabalho." diff --git a/config/locales/crowdin/js-ro.yml b/config/locales/crowdin/js-ro.yml index efc80359e78d..75c834f3eea3 100644 --- a/config/locales/crowdin/js-ro.yml +++ b/config/locales/crowdin/js-ro.yml @@ -326,7 +326,7 @@ ro: filter: noneSelection: "(nimic)" selection_mode: - notification: "Faceți click pe oricare dintre pachetele de lucru pentru a crea o legătură. Apăsați Escape pentru a anula." + notification: "Dă clic pe oricare dintre pachetele de lucru pentru a crea o legătură. Apasă Escape pentru a anula." zoom: in: "Mărire" out: "Micșorare" @@ -654,6 +654,8 @@ ro: new_notifications: message: "Există notificări noi." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Poți modifica setările de notificare pentru a te asigura că nu pierzi niciodată o actualizare importantă.' title: "Setări notificare" @@ -798,36 +800,36 @@ ro: typeahead_placeholder: Căutarea de posibili observatori relation_labels: parent: "Părinte" - children: "Fii" + children: "Copii" relates: "În relație cu" duplicates: "Dublează" duplicated: "Dublat de" blocks: "Blochează" blocked: "Blocat de" precedes: "Precede" - follows: "Urmează după" + follows: "Urmează" includes: "Include" partof: "Parte din" requires: "Necesită" required: "Cerut de" - relation_type: "tipul de relaţie" + relation_type: "tip relație" relations_hierarchy: parent_headline: "Părinte" - hierarchy_headline: "Arată ierarhia" - children_headline: "Fii" + hierarchy_headline: "Ierarhie" + children_headline: "Copii" relation_buttons: set_parent: "Setează părinte" - change_parent: "Modificare părinte" - remove_parent: "Elimina părinte" - hierarchy_indent: "Ierarhia de indentare" - hierarchy_outdent: "Ierarhie ieșită din comun" + change_parent: "Modifică părinte" + remove_parent: "Elimină părinte" + hierarchy_indent: "Indentare ierarhie" + hierarchy_outdent: "Elimină ierarhia" group_by_wp_type: "Grupează după tipul packetului de lucru" group_by_relation_type: "Grupează dupa tipul legăturii" add_parent: "Adaugă părinte existent" - add_new_child: "Crează un nou copil" - create_new: "Creați un nou" - add_existing: "Adăugați Existent" - add_existing_child: "Adaugă un copil existent" + add_new_child: "Creează copil nou" + create_new: "Creează nou" + add_existing: "Adaugă existent" + add_existing_child: "Adaugă copil existent" remove_child: "Elimină copil" add_new_relation: "Crează o nouă relație" add_existing_relation: "Adăugarea unei relații existente" @@ -837,12 +839,12 @@ ro: add_follower: "Adaugă urmăritor" show_relations: "Arată relațiile" add_predecessor: "Adăugați predecesorul" - remove: "Eliminare relaţie" + remove: "Eliminare relație" save: "Salvează relația" abort: "Anulează" relations_autocomplete: placeholder: "Tastează pentru a căuta" - parent_placeholder: "Alegeți un nou părinte sau apăsați Escape pentru a anula." + parent_placeholder: "Alege un nou părinte sau apasă Escape pentru a anula." autocompleter: placeholder: "Tastează pentru a căuta" notFoundText: "Niciun articol găsit" @@ -1044,6 +1046,12 @@ ro: not_found: "Vezi" duplicate_query_title: "Numele acestei vizualizări există deja. Să-l schimbăm oricum?" text_no_results: "Nu au fost găsite vizualizări corespunzătoare." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Datele acestui pachet de lucru sunt deduse automat din copiii săi. Activați \"Programare manuală\" pentru a stabili datele." is_switched_from_manual_to_automatic: "Este posibil ca datele acestui pachet de lucru să trebuiască să fie recalculate după trecerea de la programarea manuală la cea automată din cauza relațiilor cu alte pachete de lucru." @@ -1151,7 +1159,7 @@ ro: notice_bad_request: "Cerere invalidă." relations: empty: Nu există relații - remove: Eliminare relaţie + remove: Elimină relație inplace: button_edit: "%{attribute}: Editare" button_save: "%{attribute}: Salvează" diff --git a/config/locales/crowdin/js-ru.yml b/config/locales/crowdin/js-ru.yml index 6de785d8871c..705a5132fb67 100644 --- a/config/locales/crowdin/js-ru.yml +++ b/config/locales/crowdin/js-ru.yml @@ -655,6 +655,8 @@ ru: new_notifications: message: "Есть новые уведомления." link_text: "Нажмите здесь, чтобы загрузить их." + reminders: + note: "Примечание: \"%{note}\"" settings: change_notification_settings: 'Измените настройки уведомлений , чтобы не пропустить важное обновление.' title: "Настройки уведомлений" @@ -697,8 +699,8 @@ ru: teaser_text: "С уведомлениями о дате вы будете уведомлены о датах начала или окончания предстоящих дат, чтобы вы никогда не пропустили или не забыли важный срок." overdue: Когда просрочено project_specific: - title: "Настройки уведомлений проекта" - description: "Эти настройки специфического проекта переопределяют параметры по умолчанию выше." + title: "Настройки уведомлений для конкретного проекта" + description: "Эти настройки для конкретного проекта переопределяют параметры по умолчанию." add: "Добавить настройку для проекта" already_selected: "Этот проект уже выбран" remove: "Удалить настройки проекта" @@ -1045,6 +1047,12 @@ ru: not_found: "Нет такого представления" duplicate_query_title: "Представление с таким именем уже существует. Менять в любом случае?" text_no_results: "Подходящие представления не найдены." + reminders: + button_label: "Установить напоминание" + title: + new: "Установить напоминание" + edit: "Редактировать напоминание" + subtitle: "Вы получите уведомление о данном пакете работ в выбранное время." scheduling: is_parent: "Даты этого пакета работ выводятся автоматически из дочерних пакетов работ. Используйте «Ручной планировщик», чтобы установить даты." is_switched_from_manual_to_automatic: "Даты этого пакета работ могут быть пересчитаны после переключения с ручного на автоматическое планирование из-за связей с другими пакетами работ." @@ -1324,8 +1332,8 @@ ru: last_working_day: "последний рабочий день" last_week: "прошлой недели" last_month: "прошлый месяц" - a_specific_date: "определенная дата" - between_two_specific_dates: "между двумя определенными датами" + a_specific_date: "конкретная дата" + between_two_specific_dates: "между двумя конкретными датами" legends: changes_since: "Изменения с" changes_between: "Изменения между" diff --git a/config/locales/crowdin/js-rw.yml b/config/locales/crowdin/js-rw.yml index 8aa4fa59e174..2dc0f6c46dee 100644 --- a/config/locales/crowdin/js-rw.yml +++ b/config/locales/crowdin/js-rw.yml @@ -654,6 +654,8 @@ rw: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ rw: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-si.yml b/config/locales/crowdin/js-si.yml index 949572f239fe..f6046cf8cce9 100644 --- a/config/locales/crowdin/js-si.yml +++ b/config/locales/crowdin/js-si.yml @@ -654,6 +654,8 @@ si: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ si: not_found: "එවැනි මතයක් නොමැත" duplicate_query_title: "මෙම දර්ශනයේ නම දැනටමත් පවතී. කෙසේ හෝ වෙනස් කරන්න?" text_no_results: "ගැලපෙන අදහස් කිසිවක් සොයාගත නොහැකි විය." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-sk.yml b/config/locales/crowdin/js-sk.yml index fc054217ef5b..9f59feed6c6a 100644 --- a/config/locales/crowdin/js-sk.yml +++ b/config/locales/crowdin/js-sk.yml @@ -656,6 +656,8 @@ sk: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1046,6 +1048,12 @@ sk: not_found: "Toto zobrazenie sa nepodarilo nájsť" duplicate_query_title: "Zobrazenie s týmto názvom už existuje. Napriek tomu zmeniť?" text_no_results: "Neboli nájdené žiadne zodpovedajúce zobrazenia." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-sl.yml b/config/locales/crowdin/js-sl.yml index 52b89734fac5..ec4c45615a9c 100644 --- a/config/locales/crowdin/js-sl.yml +++ b/config/locales/crowdin/js-sl.yml @@ -655,6 +655,8 @@ sl: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Nastavitve obvestil" @@ -1045,6 +1047,12 @@ sl: not_found: "Ta pogled ne obstaja" duplicate_query_title: "Ime tega pogleda že obstaja. Se vseeno spremeni?" text_no_results: "Ujemanj ni bilo najdenih." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Datumi tega delovnega paketa so samodejno ugotovljeni od njegovih podrazredov. Za nastavitev datumov aktivirajte 'Ročno razvrščanje'." is_switched_from_manual_to_automatic: "Datumi delovnega paketa se bodo lahko, da morali preračunati po menjavi iz ročnega v samodejno razvrščanje zaradi razmerij z ostalimi delovnimi paketi." diff --git a/config/locales/crowdin/js-sr.yml b/config/locales/crowdin/js-sr.yml index a30f7dd1eee5..a1fcb6be158f 100644 --- a/config/locales/crowdin/js-sr.yml +++ b/config/locales/crowdin/js-sr.yml @@ -655,6 +655,8 @@ sr: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1045,6 +1047,12 @@ sr: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-sv.yml b/config/locales/crowdin/js-sv.yml index 91257c512740..a7d96ee7e36e 100644 --- a/config/locales/crowdin/js-sv.yml +++ b/config/locales/crowdin/js-sv.yml @@ -653,6 +653,8 @@ sv: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1043,6 +1045,12 @@ sv: not_found: "Det finns ingen sådan vy" duplicate_query_title: "Namnet på denna vy finns redan. Ändra ändå?" text_no_results: "Inga matchande vyer hittades." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-th.yml b/config/locales/crowdin/js-th.yml index 1de2400f0e65..b3cbae15ded4 100644 --- a/config/locales/crowdin/js-th.yml +++ b/config/locales/crowdin/js-th.yml @@ -653,6 +653,8 @@ th: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1043,6 +1045,12 @@ th: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-tr.yml b/config/locales/crowdin/js-tr.yml index a21de40e9755..640606a5a619 100644 --- a/config/locales/crowdin/js-tr.yml +++ b/config/locales/crowdin/js-tr.yml @@ -653,6 +653,8 @@ tr: new_notifications: message: "Yeni bildirimler var" link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Önemli bir güncellemeyi asla kaçırmamak için bildirim ayarlarınızı değiştirebilirsiniz.' title: "Bildirim ayarları" @@ -1043,6 +1045,12 @@ tr: not_found: "Böyle bir görünüm bulunmamakta" duplicate_query_title: "Bu isimde bir görünüm var. Yinede devam edilsin mi?" text_no_results: "Eşleşen görünüm bulunamadı." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Bu çalışma paketinin tarihleri otomatik olarak çocuklarından çıkarılır. Tarihleri ayarlamak için 'Manuel zamanlama'yı etkinleştirin." is_switched_from_manual_to_automatic: "Bu çalışma paketinin tarihlerinin, diğer çalışma paketleriyle olan ilişkiler nedeniyle manuelden otomatik zamanlamaya geçtikten sonra yeniden hesaplanması gerekebilir." diff --git a/config/locales/crowdin/js-uk.yml b/config/locales/crowdin/js-uk.yml index 7b903b95cfdf..4492998ceef0 100644 --- a/config/locales/crowdin/js-uk.yml +++ b/config/locales/crowdin/js-uk.yml @@ -656,6 +656,8 @@ uk: new_notifications: message: "Немає нових сповіщень." link_text: "Натисніть тут, щоб завантажити." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Ви можете змінити налаштування сповіщень, щоб ніколи не пропускати важливі оновлення.' title: "Налаштування сповіщень" @@ -1046,6 +1048,12 @@ uk: not_found: "Такого погляду немає" duplicate_query_title: "Ім'я цього перегляду вже існує. Змінити все одно?" text_no_results: "Не знайдено відповідних переглядів." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Дати цього пакета робіт автоматично виводяться з його дочірніх елементів. Активуйте «Ручне планування», щоб установити ці дати." is_switched_from_manual_to_automatic: "Можливо, дати цього пакета робіт знадобиться перерахувати після переходу з ручного на автоматичне планування через зв’язок з іншими пакетами робіт." diff --git a/config/locales/crowdin/js-uz.yml b/config/locales/crowdin/js-uz.yml index e325531bcd08..033c3bd5bcf7 100644 --- a/config/locales/crowdin/js-uz.yml +++ b/config/locales/crowdin/js-uz.yml @@ -654,6 +654,8 @@ uz: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" @@ -1044,6 +1046,12 @@ uz: not_found: "There is no such view" duplicate_query_title: "Name of this view already exists. Change anyway?" text_no_results: "No matching views were found." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "The dates of this work package are automatically deduced from its children. Activate 'Manual scheduling' to set the dates." is_switched_from_manual_to_automatic: "The dates of this work package may need to be recalculated after switching from manual to automatic scheduling due to relationships with other work packages." diff --git a/config/locales/crowdin/js-vi.yml b/config/locales/crowdin/js-vi.yml index 8ade428d7d10..8e82b9e4f409 100644 --- a/config/locales/crowdin/js-vi.yml +++ b/config/locales/crowdin/js-vi.yml @@ -653,6 +653,8 @@ vi: new_notifications: message: "Có thông báo mới." link_text: "Nhấp vào đây để tải chúng." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'Bạn có thể thay đổi cài đặt thông báo của mình để đảm bảo không bỏ lỡ cập nhật quan trọng nào.' title: "Cài đặt thông báo" @@ -1043,6 +1045,12 @@ vi: not_found: "Không có chế độ xem như vậy" duplicate_query_title: "Tên của chế độ xem này đã tồn tại. Thay đổi bất chấp?" text_no_results: "Không tìm thấy chế độ xem phù hợp." + reminders: + button_label: "Set reminder" + title: + new: "Set reminder" + edit: "Edit reminder" + subtitle: "You will receive a notification for this work package at the chosen time." scheduling: is_parent: "Ngày của gói công việc này được suy ra tự động từ các con của nó. Kích hoạt 'Lên lịch thủ công' để đặt ngày." is_switched_from_manual_to_automatic: "Ngày của gói công việc này có thể cần phải được tính toán lại sau khi chuyển từ lên lịch thủ công sang tự động do mối quan hệ với các gói công việc khác." diff --git a/config/locales/crowdin/js-zh-CN.yml b/config/locales/crowdin/js-zh-CN.yml index c8ab6f352bd9..4149d199be1f 100644 --- a/config/locales/crowdin/js-zh-CN.yml +++ b/config/locales/crowdin/js-zh-CN.yml @@ -652,6 +652,8 @@ zh-CN: new_notifications: message: "有新的通知。" link_text: "点击此处加载。" + reminders: + note: "注:\"%{note}\"" settings: change_notification_settings: '您可以修改您的通知设置,以确保您不会错过重要的更新。' title: "通知设置" @@ -1042,6 +1044,12 @@ zh-CN: not_found: "无此视图" duplicate_query_title: "此视图的名称已存在。仍要更改?" text_no_results: "未找到匹配的视图。" + reminders: + button_label: "设置提醒" + title: + new: "设置提醒" + edit: "编辑提醒" + subtitle: "您将在所选时间收到此工作包的通知。" scheduling: is_parent: "此工作包的日期会自动从其子项推导出。可激活“手动计划”来设置日期。" is_switched_from_manual_to_automatic: "由于与其他工作包的关系,在从手动计划切换为自动计划后,此工作包的日期可能需要重新计算。" diff --git a/config/locales/crowdin/js-zh-TW.yml b/config/locales/crowdin/js-zh-TW.yml index 8c004948167c..966e4351e29d 100644 --- a/config/locales/crowdin/js-zh-TW.yml +++ b/config/locales/crowdin/js-zh-TW.yml @@ -619,7 +619,7 @@ zh-TW: prioritized: "已優先" dateAlert: "日期提醒" shared: "參與" - reminder: "Reminder" + reminder: "提醒" date_alerts: milestone_date: "里程碑日期" overdue: "逾期" @@ -651,6 +651,8 @@ zh-TW: new_notifications: message: "您有新的通知" link_text: "點擊此處加載。" + reminders: + note: "備註: \"%{note}\"" settings: change_notification_settings: '您可以修改 通知設定,以確保您不會錯過重要更新。' title: "通知設定" @@ -1041,6 +1043,12 @@ zh-TW: not_found: "無此查詢" duplicate_query_title: "此版面的名稱已存在。確定改變?" text_no_results: "找不到符合的版面。" + reminders: + button_label: "設定提醒" + title: + new: "設定提醒" + edit: "編輯提醒" + subtitle: "您會在選擇的時間收到此工作項目的通知。" scheduling: is_parent: "此工作包的日期會自動從其子項推導出。可啟用“手動計劃”來設置日期。" is_switched_from_manual_to_automatic: "由於與其他工作包的關係,在從手動計劃切換為自動計劃後,此工作包的日期可能需要重新計算。" diff --git a/config/locales/crowdin/ka.yml b/config/locales/crowdin/ka.yml index 2671120892d9..8097fff82620 100644 --- a/config/locales/crowdin/ka.yml +++ b/config/locales/crowdin/ka.yml @@ -855,6 +855,9 @@ ka: lag: "Lag" from: "სამუშაო პაკეტი" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ ka: login: "მომხმარებლის სახელი" mail: "ელფოსტა" name: "სახელი" + note: "Note" password: "პაროლი" priority: "პრიორიტეტი" project: "პროექტი" @@ -1529,6 +1533,7 @@ ka: button_print: "ბეჭდვა" button_quote: "ციტატა" button_remove: წაშლა + button_remove_reminder: "Remove reminder" button_rename: "გადარქმევა" button_replace: "ჩანაცვლება" button_revoke: "გაუქმება" @@ -1539,6 +1544,7 @@ ka: button_save_as: "შენახვა, როგორც" button_apply_changes: "ცვლილებების გადატარება" button_save_back: "შენახვა და დაბრუნება" + button_set_reminder: "Set reminder" button_show: "ჩვენება" button_sort: "დალაგება" button_submit: "გადაცემა" @@ -1744,12 +1750,12 @@ ka: direction: მარცხნიდან ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ ka: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ ka: responsible: "ანგარიშვალდებული" shared: "გაზიარებული" watched: "მეთვალყურე" + reminder: "Reminder" facets: unread: "წაუკითხავი" unread_title: "წაუკითხავის ჩვენება" @@ -2245,6 +2253,7 @@ ka: label_delete: "Delete" label_deleted: "წაშლილია" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(ცარიელი)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ ka: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "გარემო" label_estimates_and_progress: "Estimates and progress" label_equals: "არის" @@ -2630,6 +2638,7 @@ ka: label_this_month: "ეს თვე" label_this_week: "ამ კვირაში " label_this_year: "ამ წელში" + label_time: "Time" label_time_entry_plural: "დახარჯული დრო" label_time_entry_activity_plural: "Spent time activities" label_title: "სათაური" @@ -3782,6 +3791,12 @@ ka: edit_description: "Can view, comment and edit this work package." view: "ხედი" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 მომხმარებელი" diff --git a/config/locales/crowdin/kk.yml b/config/locales/crowdin/kk.yml index d6264eb84ceb..650c06210754 100644 --- a/config/locales/crowdin/kk.yml +++ b/config/locales/crowdin/kk.yml @@ -855,6 +855,9 @@ kk: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ kk: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ kk: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ kk: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ kk: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ kk: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ kk: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ kk: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ kk: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ kk: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3782,6 +3791,12 @@ kk: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/ko.yml b/config/locales/crowdin/ko.yml index c3a7c64772c8..1bfe2fab834f 100644 --- a/config/locales/crowdin/ko.yml +++ b/config/locales/crowdin/ko.yml @@ -846,6 +846,9 @@ ko: lag: "지연" from: "작업 패키지" to: "관련 패키지" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "주소" role: @@ -1414,6 +1417,7 @@ ko: login: "사용자 이름" mail: "이메일" name: "이름" + note: "Note" password: "암호" priority: "우선 순위" project: "프로젝트" @@ -1510,6 +1514,7 @@ ko: button_print: "인쇄" button_quote: "인용" button_remove: 제거 + button_remove_reminder: "Remove reminder" button_rename: "이름 바꾸기" button_replace: "교체하기" button_revoke: "취소" @@ -1520,6 +1525,7 @@ ko: button_save_as: "다른 이름으로 저장" button_apply_changes: "변경 사항 적용" button_save_back: "저장하고 돌아가기" + button_set_reminder: "Set reminder" button_show: "표시" button_sort: "분류" button_submit: "제출" @@ -1707,12 +1713,12 @@ ko: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "다음과 같은 기타 추가 기능으로 양식 구성을 사용자 지정하세요." add_groups: "새로운 특성 그룹 추가" rename_groups: "특성 그룹 이름 바꾸기" - project_filters: - description_html: "사용자 지정 필드의 필터링 및 정렬은 Enterprise Edition의 추가 기능입니다." enumeration_activities: "시간 추적 활동" enumeration_work_package_priorities: "작업 패키지 우선 순위" enumeration_reported_project_statuses: "보고된 프로젝트 상태" @@ -1745,6 +1751,7 @@ ko: error_pdf_export_too_many_columns: "PDF 내보내기에 대해 너무 많은 열을 선택했습니다. 열 수를 줄이십시오." error_pdf_failed_to_export: "PDF 내보내기를 저장할 수 없습니다: %{error}" error_token_authenticity: "교차 사이트 요청 위조 토큰을 확인할 수 없습니다. 여러 브라우저나 탭에서 데이터 제출을 시도하셨습니까? 모든 탭을 닫고 다시 시도하세요." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "작업 패키지가 없거나 이 프로젝트에 속하지 않습니다." error_work_package_id_not_found: "작업 패키지를 찾을 수 없습니다." error_must_be_project_member: "은(는) 프로젝트 멤버여야 합니다." @@ -2038,6 +2045,7 @@ ko: responsible: "담당" shared: "공유됨" watched: "주시자" + reminder: "Reminder" facets: unread: "읽지 않음" unread_title: "읽지 않은 항목 표시" @@ -2208,6 +2216,7 @@ ko: label_delete: "Delete" label_deleted: "삭제됨" label_deleted_custom_field: "(삭제된 사용자 지정 필드)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(삭제된 옵션)" label_empty_element: "(비어 있음)" label_missing_or_hidden_custom_option: "(값이 없거나 액세스 권한이 없음)" @@ -2244,7 +2253,6 @@ ko: label_enterprise_active_users: "예약 활성 사용자 %{current}/%{limit}명" label_enterprise_edition: "Enterprise Edition" label_enterprise_support: "엔터프라이즈 지원" - label_enterprise_addon: "Enterprise 추가 기능" label_environment: "환경" label_estimates_and_progress: "견적 및 진행률" label_equals: "일치함" @@ -2593,6 +2601,7 @@ ko: label_this_month: "이번 달" label_this_week: "이번 주" label_this_year: "올해" + label_time: "Time" label_time_entry_plural: "소비한 시간" label_time_entry_activity_plural: "소요 시간 활동" label_title: "제목" @@ -3739,6 +3748,12 @@ ko: edit_description: "이 작업 패키지 보기, 코멘트 작성 및 편집을 할 수 있습니다." view: "보기" view_description: "이 작업 패키지를 볼 수 있습니다." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "사용자 0명" diff --git a/config/locales/crowdin/lt.yml b/config/locales/crowdin/lt.yml index 5b5cd914e578..e9b2ebf5254f 100644 --- a/config/locales/crowdin/lt.yml +++ b/config/locales/crowdin/lt.yml @@ -868,6 +868,9 @@ lt: lag: "Vėlavimas" from: "Darbų paketas" to: "Susijusių darbų paketas" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1466,6 +1469,7 @@ lt: login: "Naudotojas" mail: "El. paštas" name: "Vardas" + note: "Note" password: "Slaptažodis" priority: "Pirmenybė" project: "Projektas" @@ -1562,6 +1566,7 @@ lt: button_print: "Spausdinti" button_quote: "Cituoti" button_remove: Pašalinti + button_remove_reminder: "Remove reminder" button_rename: "Pervardinti" button_replace: "Pakeisti" button_revoke: "Atšaukti" @@ -1572,6 +1577,7 @@ lt: button_save_as: "Įrašyti kaip" button_apply_changes: "Pritaikyti pakeitimus" button_save_back: "Įrašyti ir grįžti atgal" + button_set_reminder: "Set reminder" button_show: "Rodyti" button_sort: "Rūšiuoti" button_submit: "Siųsti" @@ -1813,12 +1819,12 @@ lt: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Pritaikyti sau formos konfigūraciją su šiais naujais priedais:" add_groups: "Pridėti naujas atributų grupes" rename_groups: "Pervadinti atributų grupes" - project_filters: - description_html: "Filtravimas ir rikiavimas pagal pritaikytus laukus yra tik Enterprise versijos priedas." enumeration_activities: "Laiko sekimo veiklos" enumeration_work_package_priorities: "Darbų paketo prioritetai" enumeration_reported_project_statuses: "Pranešta projekto būsena" @@ -1851,6 +1857,7 @@ lt: error_pdf_export_too_many_columns: "PDF eksportavimui pasirinkta per daug stulpelių. Prašome sumažinti stulpelių skaičių." error_pdf_failed_to_export: "PDF eksportas negali būti išsaugotas: %{error}" error_token_authenticity: "Neįmanoma patikrinti Cross-Site Request Forgery žetono. Gal bandėte nusiųsti duomenis iš kelių naršyklių ar kortelių? Prašome uždaryti visas korteles ir pabandyti dar kartą." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Darbų paketas nerastas arba nepriklauso šiam projektui" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "turi būti projekto narys" @@ -2144,6 +2151,7 @@ lt: responsible: "Atsakingas" shared: "Bendrinta" watched: "Stebėtojas" + reminder: "Reminder" facets: unread: "Neskaitytas" unread_title: "Rodyti neperskaitytus" @@ -2314,6 +2322,7 @@ lt: label_delete: "Delete" label_deleted: "panaikintas" label_deleted_custom_field: "(panaikintas vartotojo laukas)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(panaikintas nustatymas)" label_empty_element: "(tuščia)" label_missing_or_hidden_custom_option: "(trūksta reikšmės arba prieigos teisių)" @@ -2350,7 +2359,6 @@ lt: label_enterprise_active_users: "%{current}/%{limit} aktyviai naudojami naudotojai" label_enterprise_edition: "Enterprise versija" label_enterprise_support: "„Enterprise“ palaikymas" - label_enterprise_addon: "Enterprise priedas" label_environment: "Aplinka" label_estimates_and_progress: "Įvertinimai ir eiga" label_equals: "yra" @@ -2699,6 +2707,7 @@ lt: label_this_month: "šis mėnuo" label_this_week: "ši savaitė" label_this_year: "šiemet" + label_time: "Time" label_time_entry_plural: "Praleista laiko" label_time_entry_activity_plural: "Praleisto laiko veiklos" label_title: "Pavadinimas" @@ -3853,6 +3862,12 @@ lt: edit_description: "Gali žiūrėti, komentuoti ir keisti šį darbo paketą." view: "Peržiūrėti" view_description: "Gali žiūrėti šį darbo paketą." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 naudotojų" diff --git a/config/locales/crowdin/lv.yml b/config/locales/crowdin/lv.yml index c5ba4f0a6c72..9da54c6a3d55 100644 --- a/config/locales/crowdin/lv.yml +++ b/config/locales/crowdin/lv.yml @@ -863,6 +863,9 @@ lv: lag: "Lag" from: "Darba pieteikums" to: "Saistītie pieteikuma tipi" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1451,6 +1454,7 @@ lv: login: "Username" mail: "E-Pasts" name: "Nosaukums" + note: "Note" password: "Parole" priority: "Prioritāte" project: "Projekts" @@ -1547,6 +1551,7 @@ lv: button_print: "Drukāt" button_quote: "Citēt" button_remove: Noņemt + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1557,6 +1562,7 @@ lv: button_save_as: "Saglabāt kā" button_apply_changes: "Apply changes" button_save_back: "Saglabāt un atpakaļ" + button_set_reminder: "Set reminder" button_show: "Rādīt" button_sort: "Sort" button_submit: "Publicēt" @@ -1780,12 +1786,12 @@ lv: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Pieteikumu prioritātes" enumeration_reported_project_statuses: "Reported project status" @@ -1818,6 +1824,7 @@ lv: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2111,6 +2118,7 @@ lv: responsible: "Accountable" shared: "Shared" watched: "Sekotājs" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2281,6 +2289,7 @@ lv: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2317,7 +2326,6 @@ lv: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2666,6 +2674,7 @@ lv: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Pavadīts laiks" label_time_entry_activity_plural: "Spent time activities" label_title: "Virsraksts" @@ -3821,6 +3830,12 @@ lv: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/mn.yml b/config/locales/crowdin/mn.yml index 6bd1113e2a64..ccfbae4b21b1 100644 --- a/config/locales/crowdin/mn.yml +++ b/config/locales/crowdin/mn.yml @@ -335,7 +335,7 @@ mn: favored: "Favorite projects" archived: "Archived projects" shared: "Shared project lists" - my_lists: "My project lists" + my_lists: "Миний төслийн жагсаалт" new: placeholder: "New project list" delete_modal: @@ -362,7 +362,7 @@ mn: actions: label_enable_single: "Active in this project, click to disable" label_disable_single: "Inactive in this project, click to enable" - remove_from_project: "Remove from project" + remove_from_project: "Төслөөс устгах" label_enable_all: "Enable all" label_disable_all: "Disable all" is_required_blank_slate: @@ -855,6 +855,9 @@ mn: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1331,8 +1334,8 @@ mn: placeholder_user: "Placeholder user" project: "Project" project_query: - one: "Project list" - other: "Project lists" + one: "Төслийн жагсаалт" + other: "Төслийн жагсаалтууд" query: "Custom query" role: one: "Role" @@ -1413,7 +1416,7 @@ mn: default_columns: "Default columns" description: "Description" derived_due_date: "Derived finish date" - derived_estimated_hours: "Total work" + derived_estimated_hours: "Нийт ажил" derived_start_date: "Derived start date" display_sums: "Display Sums" due_date: "Finish date" @@ -1433,6 +1436,7 @@ mn: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ mn: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ mn: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ mn: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ mn: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ mn: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2230,7 +2238,7 @@ mn: label_custom_field_default_type: "Empty type" label_custom_style: "Design" label_custom_style_description: "Choose how OpenProject looks to you with themes, select your default colors to use in the app and how exports look like." - label_dashboard: " Хянах самбар" + label_dashboard: "Хянах самбар" label_database_version: "PostgreSQL version" label_date: "Date" label_date_and_time: "Date and time" @@ -2245,6 +2253,7 @@ mn: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ mn: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2347,7 +2355,7 @@ mn: label_index_by_title: "Index by title" label_information: "Information" label_information_plural: "Information" - label_installation_guides: "Installation guides" + label_installation_guides: "Суулгах зааварууд" label_integer: "Integer" label_internal: "Internal" label_introduction_video: "Introduction video" @@ -2630,6 +2638,7 @@ mn: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -2792,7 +2801,7 @@ mn: more_to_see: one: "There is 1 more work package with notifications." other: "There are %{count} more work packages with notifications." - open_in_browser: "Open in browser" + open_in_browser: "Хөтөч дээр нээх" reason: watched: "Watched" assigned: "Assigned" @@ -3014,7 +3023,7 @@ mn: permission_add_work_package_notes: "Add notes" permission_add_work_packages: "Add work packages" permission_add_messages: "Post messages" - permission_add_project: "Create projects" + permission_add_project: "Төсөл үүсгэх" permission_add_work_package_attachments: "Add attachments" permission_add_work_package_attachments_explanation: "Allows adding attachments without Edit work packages permission" permission_archive_project: "Archive project" @@ -3032,7 +3041,7 @@ mn: permission_commit_access: "Read/write access to repository (commit)" permission_copy_projects: "Copy projects" permission_copy_work_packages: "Copy work packages" - permission_create_backup: "Create backups" + permission_create_backup: "Нөөцлөлт үүсгэх" permission_delete_work_package_watchers: "Delete watchers" permission_delete_work_packages: "Delete work packages" permission_delete_messages: "Delete messages" @@ -3782,6 +3791,12 @@ mn: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml index 53a962b992c0..a58047184913 100644 --- a/config/locales/crowdin/ms.yml +++ b/config/locales/crowdin/ms.yml @@ -845,6 +845,9 @@ ms: lag: "Lag" from: "Pakej kerja" to: "Pakej kerja yang berkaitan" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1413,6 +1416,7 @@ ms: login: "Nama pengguna" mail: "E-mel" name: "Nama" + note: "Note" password: "Kata Laluan" priority: "Keutamaan" project: "Projek" @@ -1509,6 +1513,7 @@ ms: button_print: "Cetak" button_quote: "Petikan" button_remove: Keluarkan + button_remove_reminder: "Remove reminder" button_rename: "Namakan semula" button_replace: "Ganti" button_revoke: "Batalkan" @@ -1519,6 +1524,7 @@ ms: button_save_as: "Simpan sebagai" button_apply_changes: "Guna pakai perubahan" button_save_back: "Simpan dan kembali" + button_set_reminder: "Set reminder" button_show: "Paparkan" button_sort: "Susun" button_submit: "Hantar" @@ -1706,12 +1712,12 @@ ms: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Menyuaikan borang konfigurasi dengan segala jenis tambahan ini:" add_groups: "Tambah kumpulan atribut baharu" rename_groups: "Nama semula kumpulan atribut" - project_filters: - description_html: "Menyaring dan menyusun ruang tersuai adalah tambahan edisi Enterprise." enumeration_activities: "Aktiviti penjejakan masa" enumeration_work_package_priorities: "Keutamaan pakej kerja" enumeration_reported_project_statuses: "Status projek yang dilaporkan" @@ -1744,6 +1750,7 @@ ms: error_pdf_export_too_many_columns: "Terlalu banyak kolum dipilih untuk eksport PDF. Sila kurangkan bilangan kolum." error_pdf_failed_to_export: "Eksport PDF tidak dapat disimpan: %{error}" error_token_authenticity: "Tidak dapat mengesahkan token Cross-Site Request Forgery. Adakah anda sedang mencuba untuk menghantar data di pelbagai pelayar atau tab? Sila tutup semua tab dan cuba lagi." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Pakej kerja tidak ditemui atau tidak tergolong dalam projek ini" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "perlu menjadi ahli projek" @@ -2037,6 +2044,7 @@ ms: responsible: "Bertanggungjawab" shared: "Telah dikongsi" watched: "Pemerhati" + reminder: "Reminder" facets: unread: "Belum dibaca" unread_title: "Paparkan yang belum dibaca" @@ -2207,6 +2215,7 @@ ms: label_delete: "Delete" label_deleted: "dipadam" label_deleted_custom_field: "(ruang tersuai yang telah dipadam)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(pilihan yang telah dipadam)" label_empty_element: "(kosong)" label_missing_or_hidden_custom_option: "(nilai yang hilang atau kurang kebenaran untuk mengakses)" @@ -2243,7 +2252,6 @@ ms: label_enterprise_active_users: "%{current}/%{limit} pengguna aktif yang ditempah" label_enterprise_edition: "Edisi Enterprise" label_enterprise_support: "sokongan Enterprise" - label_enterprise_addon: "Tambahan Enterprise" label_environment: "Persekitaran" label_estimates_and_progress: "Anggaran dan perkembangan" label_equals: "ialah" @@ -2592,6 +2600,7 @@ ms: label_this_month: "bulan ini" label_this_week: "minggu ini" label_this_year: "tahun ini" + label_time: "Time" label_time_entry_plural: "Masa yang dihabiskan" label_time_entry_activity_plural: "Aktiviti masa yang diluangkan" label_title: "Tajuk" @@ -3740,6 +3749,12 @@ ms: edit_description: "Boleh lihat, komen dan edit pakej kerja ini." view: "Lihat" view_description: "Boleh papar pakej kerja ini." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 pengguna" diff --git a/config/locales/crowdin/ne.yml b/config/locales/crowdin/ne.yml index 27725fa30261..1b387bc28a35 100644 --- a/config/locales/crowdin/ne.yml +++ b/config/locales/crowdin/ne.yml @@ -855,6 +855,9 @@ ne: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ ne: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ ne: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "रद्द गर्नुहोस्" @@ -1539,6 +1544,7 @@ ne: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ ne: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "समय ट्र्याकिंग गतिविधिहरू" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ ne: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ ne: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ ne: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ ne: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ ne: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3782,6 +3791,12 @@ ne: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/nl.yml b/config/locales/crowdin/nl.yml index 831caad7f754..ee056e70a846 100644 --- a/config/locales/crowdin/nl.yml +++ b/config/locales/crowdin/nl.yml @@ -852,6 +852,9 @@ nl: lag: "Vertraging" from: "Werkpakket" to: "Verwante werkpakket" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1430,6 +1433,7 @@ nl: login: "Gebruikersnaam" mail: "E-mail" name: "Naam" + note: "Note" password: "Wachtwoord" priority: "Prioriteit" project: "Project" @@ -1526,6 +1530,7 @@ nl: button_print: "Afdrukken" button_quote: "Citeer" button_remove: Verwijder + button_remove_reminder: "Remove reminder" button_rename: "Naam wijzigen" button_replace: "Vervang" button_revoke: "Intrekken" @@ -1536,6 +1541,7 @@ nl: button_save_as: "Opslaan als" button_apply_changes: "Veranderingen doorvoeren" button_save_back: "Opslaan en terug" + button_set_reminder: "Set reminder" button_show: "Toon" button_sort: "Sorteren" button_submit: "Verzenden" @@ -1741,12 +1747,12 @@ nl: direction: LTR ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Toevoegen van nieuwe attribuutgroepen" rename_groups: "Attribuutgroepen hernoemen" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Activiteiten voor het bijhouden van tijd" enumeration_work_package_priorities: "Werkpakket prioriteiten" enumeration_reported_project_statuses: "Gerapporteerde projectstatus" @@ -1779,6 +1785,7 @@ nl: error_pdf_export_too_many_columns: "Te veel kolommen geselecteerd voor het exporteren naar PDF. Beperk het aantal kolommen." error_pdf_failed_to_export: "De pdf export kan niet worden opgeslagen:%{error}" error_token_authenticity: "Niet in staat om de Cross-Site Request Forgery token te valideren. Heeft u geprobeert gegevens op meerdere browsers of tabbladen wilt indienen? Sluit alle tabbladen en probeer het opnieuw." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Het werkpakket werd niet gevonden of maakt geen deel uit van dit project" error_work_package_id_not_found: "Het werkpakket is niet gevonden." error_must_be_project_member: "moet een project lid zijn" @@ -2072,6 +2079,7 @@ nl: responsible: "Verantwoording afleggen" shared: "Gedeeld" watched: "Kijker" + reminder: "Reminder" facets: unread: "Ongelezen" unread_title: "Toon ongelezen" @@ -2242,6 +2250,7 @@ nl: label_delete: "Delete" label_deleted: "verwijderd" label_deleted_custom_field: "(verwijderde aangepast veld)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(verwijderde optie)" label_empty_element: "(leeg)" label_missing_or_hidden_custom_option: "(ontbrekende waarde of ontbrekende machtigingen voor toegang)" @@ -2278,7 +2287,6 @@ nl: label_enterprise_active_users: "%{current}/%{limit} gereserveerd actieve gebruikers" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Ondernemingsondersteuning" - label_enterprise_addon: "Enterprise add-on" label_environment: "Omgeving" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2627,6 +2635,7 @@ nl: label_this_month: "Deze maand" label_this_week: "deze week" label_this_year: "Dit jaar" + label_time: "Time" label_time_entry_plural: "Bestede tijd" label_time_entry_activity_plural: "Spent time activities" label_title: "Titel" @@ -3777,6 +3786,12 @@ nl: edit_description: "Kan dit werkpakket bekijken, becommentariëren en bewerken." view: "Weergeven" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/no.yml b/config/locales/crowdin/no.yml index 022e011e9400..70306aaeebf8 100644 --- a/config/locales/crowdin/no.yml +++ b/config/locales/crowdin/no.yml @@ -854,6 +854,9 @@ lag: "Forsinkelse" from: "Arbeidspakke" to: "Relatert arbeidspakke" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1432,6 +1435,7 @@ login: "Brukernavn" mail: "E-post" name: "Navn" + note: "Note" password: "Passord" priority: "Prioritet" project: "Prosjekt" @@ -1528,6 +1532,7 @@ button_print: "Skriv ut" button_quote: "Sitèr" button_remove: Fjern + button_remove_reminder: "Remove reminder" button_rename: "Endre navn" button_replace: "Erstatt" button_revoke: "Tilbakekall" @@ -1538,6 +1543,7 @@ button_save_as: "Lagre som" button_apply_changes: "Bruk endringer" button_save_back: "Lagre og tilbake" + button_set_reminder: "Set reminder" button_show: "Vis" button_sort: "Sortèr" button_submit: "Lagre" @@ -1743,12 +1749,12 @@ direction: LTR ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Tilpass skjemakonfigurasjonen med disse ekstra utvidelsene:" add_groups: "Legg til nye attributtgrupper" rename_groups: "Endre attributtgrupper" - project_filters: - description_html: "Filtrering og sortering på egendefinerte felter er en utvidelse i Enterprise feltet." enumeration_activities: "Tidregistrering aktiviteter" enumeration_work_package_priorities: "Prioritering av arbeidspakker" enumeration_reported_project_statuses: "Rapportert prosjektstatus" @@ -1781,6 +1787,7 @@ error_pdf_export_too_many_columns: "For mange kolonner valgt for PDF eksport. Reduser antall kolonner." error_pdf_failed_to_export: "PDF-eksporten kunne ikke lagres: %{error}" error_token_authenticity: "Kan ikke bekrefte Cross-Site Request Forgery token. Har du prøvd å sende inn data i flere nettlesere eller faner? Vennligst lukk alle fanene og prøv igjen." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Arbeidspakken ble ikke funnet eller tilhører ikke dette prosjektet" error_work_package_id_not_found: "Arbeidspakken ble ikke funnet." error_must_be_project_member: "må være prosjektmedlem" @@ -2074,6 +2081,7 @@ responsible: "Ansvarlig" shared: "Delt" watched: "Overvåker" + reminder: "Reminder" facets: unread: "Ulest" unread_title: "Vis ulest" @@ -2244,6 +2252,7 @@ label_delete: "Delete" label_deleted: "slettet" label_deleted_custom_field: "(slettet egendefinert felt)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(slettet alternativ)" label_empty_element: "(tom)" label_missing_or_hidden_custom_option: "(manglende verdi eller manglende rettigheter)" @@ -2280,7 +2289,6 @@ label_enterprise_active_users: "%{current}/%{limit} bookede brukere" label_enterprise_edition: "Enterprise Edition" label_enterprise_support: "Bedriftsstøtte" - label_enterprise_addon: "Enterprise utvidelse" label_environment: "Miljø" label_estimates_and_progress: "Estimater og fremdrift" label_equals: "er" @@ -2629,6 +2637,7 @@ label_this_month: "denne måneden" label_this_week: "denne uken" label_this_year: "dette året" + label_time: "Time" label_time_entry_plural: "Tid brukt" label_time_entry_activity_plural: "Brukt tid aktivitet" label_title: "Tittel" @@ -3781,6 +3790,12 @@ edit_description: "Kan vise, kommentere og redigere denne arbeidspakken." view: "Vis" view_description: "Kan se denne arbeidspakken." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 brukere" diff --git a/config/locales/crowdin/pl.yml b/config/locales/crowdin/pl.yml index 3f897f60fb13..535ee2e6465f 100644 --- a/config/locales/crowdin/pl.yml +++ b/config/locales/crowdin/pl.yml @@ -868,6 +868,9 @@ pl: lag: "Opóźnienie" from: "Zadanie" to: "Powiązanie zadania" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "ADRES URL" role: @@ -1466,6 +1469,7 @@ pl: login: "Nazwa użytkownika" mail: "Adres e-mail" name: "Nazwa" + note: "Note" password: "Hasło" priority: "Priorytet" project: "Projekt" @@ -1562,6 +1566,7 @@ pl: button_print: "Drukuj" button_quote: "Cytat" button_remove: Usuń + button_remove_reminder: "Remove reminder" button_rename: "Zmień nazwę" button_replace: "Zastąp" button_revoke: "Unieważnij" @@ -1572,6 +1577,7 @@ pl: button_save_as: "Zapisz jako" button_apply_changes: "Zastosuj zmiany" button_save_back: "Zapisz i wróć" + button_set_reminder: "Set reminder" button_show: "Pokaż" button_sort: "Sortowanie" button_submit: "Prześlij" @@ -1813,12 +1819,12 @@ pl: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Dostosuj konfigurację formularza za pomocą tych dodatków:" add_groups: "Dodaj nowe grupy atrybutów" rename_groups: "Zmień grupy atrybutów" - project_filters: - description_html: "Filtrowanie i sortowanie pól niestandardowych jest dodatkiem dla wersji Enterprise." enumeration_activities: "Działania śledzenia czasu" enumeration_work_package_priorities: "Priorytety pakietów roboczych" enumeration_reported_project_statuses: "Status zgłoszonego projektu" @@ -1851,6 +1857,7 @@ pl: error_pdf_export_too_many_columns: "Wybrano zbyt dużo kolumn do eksportu PDF. Zmniejsz liczbę kolumn." error_pdf_failed_to_export: "Nie można było zapisać eksportu PDF: %{error}" error_token_authenticity: "Nie można zweryfikować tokenu Cross-Site Request Forgery. Czy podjęto próbę przesłania danych w wielu przeglądarkach lub z wielu kart? Zamknij wszystkie karty i spróbuj ponownie." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Pakiet roboczy nie został znaleziony lub nie należy do tego projektu" error_work_package_id_not_found: "Nie znaleziono pakietu roboczego." error_must_be_project_member: "musi być członkiem projektu" @@ -2144,6 +2151,7 @@ pl: responsible: "Osoba odpowiedzialna" shared: "Udostępniono" watched: "Obserwator" + reminder: "Reminder" facets: unread: "Nieprzeczytane" unread_title: "Pokaż nieprzeczytane" @@ -2314,6 +2322,7 @@ pl: label_delete: "Delete" label_deleted: "Usunięty" label_deleted_custom_field: "(usunięte pole niestandardowe)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opcja usunięta)" label_empty_element: "(pusty)" label_missing_or_hidden_custom_option: "(brakująca wartość lub brak uprawnień do dostępu)" @@ -2350,7 +2359,6 @@ pl: label_enterprise_active_users: "%{current}/%{limit} zarejestrowanych aktywnych użytkowników" label_enterprise_edition: "Wersja Enterprise" label_enterprise_support: "Wsparcie Enterprise" - label_enterprise_addon: "Dodatek wersji Enterprise" label_environment: "Środowisko" label_estimates_and_progress: "Szacunki i postęp" label_equals: "jest" @@ -2699,6 +2707,7 @@ pl: label_this_month: "ten miesiąc" label_this_week: "ten tydzień" label_this_year: "ten rok" + label_time: "Time" label_time_entry_plural: "Czas pracy" label_time_entry_activity_plural: "Czas spędzony na aktywności" label_title: "Tytuł" @@ -3854,6 +3863,12 @@ pl: edit_description: "Może wyświetlać, komentować i edytować ten pakiet roboczy." view: "Wyświetlanie" view_description: "Może wyświetlić ten pakiet roboczy." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 użytkowników" diff --git a/config/locales/crowdin/pt-BR.yml b/config/locales/crowdin/pt-BR.yml index 0cf2c28f2eb1..6b3ba51dd18d 100644 --- a/config/locales/crowdin/pt-BR.yml +++ b/config/locales/crowdin/pt-BR.yml @@ -852,6 +852,9 @@ pt-BR: lag: "Atraso" from: "Pacote de trabalho" to: "Pacote de trabalho relacionado" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1430,6 +1433,7 @@ pt-BR: login: "Nome de usuário" mail: "E-mail" name: "Nome" + note: "Note" password: "Senha" priority: "Prioridade" project: "Projeto" @@ -1526,6 +1530,7 @@ pt-BR: button_print: "Imprimir" button_quote: "Citar" button_remove: Remover + button_remove_reminder: "Remove reminder" button_rename: "Renomear" button_replace: "Substituir" button_revoke: "Revogar" @@ -1536,6 +1541,7 @@ pt-BR: button_save_as: "Salvar como" button_apply_changes: "Aplicar as alterações" button_save_back: "Salvar e voltar" + button_set_reminder: "Set reminder" button_show: "Mostrar" button_sort: "Ordenar" button_submit: "Enviar" @@ -1741,12 +1747,12 @@ pt-BR: direction: da esquerda para a direita ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Personalize a configuração do formulário com estes complementos adicionais:" add_groups: "Adicionar novos grupos de atributos" rename_groups: "Renomear grupos de atributos" - project_filters: - description_html: "Filtrar e ordenar em campos personalizados é um complemento da edição Enterprise." enumeration_activities: "Atividades de controle de tempo" enumeration_work_package_priorities: "Prioridades do pacote de trabalho" enumeration_reported_project_statuses: "Situação de projeto comunicada" @@ -1779,6 +1785,7 @@ pt-BR: error_pdf_export_too_many_columns: "Muitas colunas selecionadas para a exportação para PDF. Reduza o número de colunas." error_pdf_failed_to_export: "Não foi possível salvar a exportação do PDF: %{error}" error_token_authenticity: "Não foi possível verificar o token de Falsificação de Solicitação Entre Sites. Você tentou enviar dados em vários navegadores ou abas? Por favor, feche todas as abas e tente novamente." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "O pacote de trabalho não foi encontrado ou não pertence a este projeto" error_work_package_id_not_found: "O pacote de trabalho não foi encontrado." error_must_be_project_member: "deve ser membro do projeto" @@ -2072,6 +2079,7 @@ pt-BR: responsible: "Responsável" shared: "Compartilhado" watched: "Observador" + reminder: "Reminder" facets: unread: "Não lido" unread_title: "Exibir não lidos" @@ -2242,6 +2250,7 @@ pt-BR: label_delete: "Delete" label_deleted: "excluído" label_deleted_custom_field: "(campo personalizado excluído)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opção excluída)" label_empty_element: "(vazio)" label_missing_or_hidden_custom_option: "(algum valor faltando ou falta permissões para acessar)" @@ -2278,7 +2287,6 @@ pt-BR: label_enterprise_active_users: "%{current}/%{limit} usuários ativos reservados" label_enterprise_edition: "Edição Enterprise" label_enterprise_support: "Suporte corporativo" - label_enterprise_addon: "Complemento empresarial" label_environment: "Ambiente" label_estimates_and_progress: "Estimativas e progresso" label_equals: "é" @@ -2627,6 +2635,7 @@ pt-BR: label_this_month: "este mês" label_this_week: "esta semana" label_this_year: "este ano" + label_time: "Time" label_time_entry_plural: "Tempo gasto" label_time_entry_activity_plural: "Tempo investido em atividades" label_title: "Título" @@ -3777,6 +3786,12 @@ pt-BR: edit_description: "Pode visualizar, comentar e editar este pacote de trabalho." view: "Ver" view_description: "Pode visualizar este pacote de trabalho." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 usuários" diff --git a/config/locales/crowdin/pt-PT.yml b/config/locales/crowdin/pt-PT.yml index 498e52bd940e..a4ef0c348048 100644 --- a/config/locales/crowdin/pt-PT.yml +++ b/config/locales/crowdin/pt-PT.yml @@ -852,6 +852,9 @@ pt-PT: lag: "Atraso" from: "Pacote de trabalho" to: "Tarefas Relacionadas" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1430,6 +1433,7 @@ pt-PT: login: "Nome do Utilizador" mail: "E-mail" name: "Nome" + note: "Note" password: "Senha" priority: "Prioridade" project: "Projecto" @@ -1526,6 +1530,7 @@ pt-PT: button_print: "Imprimir" button_quote: "Citar" button_remove: Remover + button_remove_reminder: "Remove reminder" button_rename: "Alterar o nome" button_replace: "Substituir" button_revoke: "Revogar" @@ -1536,6 +1541,7 @@ pt-PT: button_save_as: "Guardar como" button_apply_changes: "Aplicar alterações" button_save_back: "Salvar e voltar" + button_set_reminder: "Set reminder" button_show: "Mostrar" button_sort: "Ordenar" button_submit: "Enviar" @@ -1741,12 +1747,12 @@ pt-PT: direction: lTR ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Personalize a configuração do formulário com estes complementos adicionais:" add_groups: "Adicionar novos grupos de atributos" rename_groups: "Mudar o nome de grupos de atributos" - project_filters: - description_html: "Filtrar e ordenar os campos personalizados é um complemento da edição Enterprise." enumeration_activities: "Atividades de controlo de tempo" enumeration_work_package_priorities: "Prioridades de tarefas" enumeration_reported_project_statuses: "Estado do projeto reportado" @@ -1779,6 +1785,7 @@ pt-PT: error_pdf_export_too_many_columns: "Demasiadas colunas selecionadas para a exportação PDF. Reduza o número de colunas." error_pdf_failed_to_export: "Não foi possível guardar a exportação de PDF: %{error}" error_token_authenticity: "Não é possível verificar o token de Cross-Site Request Forgery. Tentou enviar dados em vários navegadores ou abas? Feche todas as abas e tente novamente." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "A tarefa não foi encontrada ou não pertence a este projecto" error_work_package_id_not_found: "O pacote de trabalho não foi encontrado." error_must_be_project_member: "deve ser membro do projeto" @@ -2072,6 +2079,7 @@ pt-PT: responsible: "Responsável" shared: "Partilhado" watched: "Observador" + reminder: "Reminder" facets: unread: "Não lidas" unread_title: "Mostrar não lidas" @@ -2242,6 +2250,7 @@ pt-PT: label_delete: "Delete" label_deleted: "eliminado" label_deleted_custom_field: "(campo personalizado apagado)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opção eliminada)" label_empty_element: "(vazio)" label_missing_or_hidden_custom_option: "(faltam valores ou permissões para acessar)" @@ -2278,7 +2287,6 @@ pt-PT: label_enterprise_active_users: "%{current}/%{limit} utilizadores ativos reservados" label_enterprise_edition: "Edição Enterprise" label_enterprise_support: "Suporte Enterprise" - label_enterprise_addon: "Suplemento Enterprise" label_environment: "Ambiente" label_estimates_and_progress: "Estimativas e progresso" label_equals: "é" @@ -2627,6 +2635,7 @@ pt-PT: label_this_month: "este mês" label_this_week: "esta semana" label_this_year: "este ano" + label_time: "Time" label_time_entry_plural: "Tempo usado" label_time_entry_activity_plural: "Tempo despendido em atividades" label_title: "Título" @@ -3776,6 +3785,12 @@ pt-PT: edit_description: "Pode ver, comentar e editar este pacote de trabalho." view: "Ver" view_description: "Pode ver este pacote de trabalho." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 utilizadores" diff --git a/config/locales/crowdin/ro.yml b/config/locales/crowdin/ro.yml index 6706f7d7746c..54dd683d9bbd 100644 --- a/config/locales/crowdin/ro.yml +++ b/config/locales/crowdin/ro.yml @@ -310,7 +310,7 @@ ro: overviews: "Prezentare generală proiect" queries: "Pachete de lucru: vizualizări salvate" wiki_page_attachments: "Pagini wiki: atașamente" - work_package_attachments: "Pachete de lucru: anexe" + work_package_attachments: "Pachete de lucru: atașamente" work_package_categories: "Pachete de lucru: categorii" work_package_file_links: "Pachete de lucru: legături de fișiere" work_package_shares: "Pachete de lucru: partajări" @@ -371,7 +371,7 @@ ro: types: no_results_title_text: În acest moment nu există tipuri disponibile. form: - enable_type_in_project: 'Activare tip %{type}' + enable_type_in_project: 'Activează tip %{type}' versions: no_results_title_text: În acest moment nu există versiuni pentru acest proiect. no_results_content_text: Creează versiune nouă @@ -514,7 +514,7 @@ ro: placeholder_users: right_to_manage_members_missing: > Nu aveți permisiunea de a șterge utilizatorul de tip placeholder. Nu aveți dreptul de a gestiona membrii pentru toate proiectele din care face parte utilizatorul de tip placeholder. - delete_tooltip: "Ștergeți utilizatorul de tip placeholder" + delete_tooltip: "Șterge utilizator placeholder" deletion_info: heading: "Ștergeți utilizatorul de tip placeholder %{name}" data_consequences: > @@ -617,7 +617,7 @@ ro: none_could_be_saved: "Niciunul dintre pachetele de lucru %{total} nu poate fi actualizat." x_out_of_y_could_be_saved: "%{failing} din %{total} pachete de lucru nu pot fi actualizate în timp ce %{success} poate fi actualizat." selected_because_descendants: "While %{selected} work packages were selected, in total %{total} work packages are affected which includes descendants." - descendant: "descendent de selectat" + descendant: "descendent al selectatului" move: no_common_statuses_exists: "Nu există o stare disponibilă pentru toate pachetele de lucru selectate. Starea acestora nu poate fi modificată." unsupported_for_multiple_projects: "Mutarea/copierea în masă nu este suportată pentru pachete de lucru din proiecte multiple" @@ -650,57 +650,57 @@ ro: index: action_bar_title: "Add relations to other work packages to create a link between them." no_results_title_text: There are currently no relations available. - blankslate_heading: "No relations" + blankslate_heading: "Fără relații" blankslate_description: "This work package does not have any relations yet." - label_add_x: "Add %{x}" - label_edit_x: "Edit %{x}" + label_add_x: "Adaugă %{x}" + label_edit_x: "Editează %{x}" label_add_description: "Add description" lag: subject: "Lag" title: "Lag (in days)" - caption: "The gap in number of working days in between the two work packages" + caption: "Diferența în numărul de zile lucrătoare dintre cele două pachete de lucru" relations: - label_relates_singular: "related to" - label_relates_plural: "related to" - label_relates_to_singular: "related to" - label_relates_to_plural: "related to" - relates_description: "Creates a visible link between the two work packages with no additional effect" - relates_to_description: "Creates a visible link between the two work packages with no additional effect" - label_precedes_singular: "successor (after)" - label_precedes_plural: "successors (after)" - precedes_description: "The related work package necessarily needs to start after this one finishes" - label_follows_singular: "predecessor (before)" - label_follows_plural: "predecessors (before)" - follows_description: "The related work package necessarily needs to finish before this one can start" - label_child_singular: "child" - label_child_plural: "children" + label_relates_singular: "asociat cu" + label_relates_plural: "asociat cu" + label_relates_to_singular: "asociat cu" + label_relates_to_plural: "asociat cu" + relates_description: "Creează o legătură vizibilă între cele două pachete de lucru fără niciun efect suplimentar" + relates_to_description: "Creează o legătură vizibilă între cele două pachete de lucru fără niciun efect suplimentar" + label_precedes_singular: "succesor (după)" + label_precedes_plural: "succesor (după)" + precedes_description: "Pachetul de lucru asociat trebuie neapărat să înceapă după finalizarea acestuia" + label_follows_singular: "predecesor (înainte)" + label_follows_plural: "predecesor (înainte)" + follows_description: "Pachetul de lucru asociat trebuie neapărat să înceapă după finalizarea acestuia" + label_child_singular: "copil" + label_child_plural: "copii" child_description: "Makes the related work package a sub-item of the current (parent) work package" - label_blocks_singular: "blocks" - label_blocks_plural: "blocks" - blocks_description: "The related work package cannot be closed until this one is closed first" - label_blocked_singular: "blocked by" - label_blocked_plural: "blocked by" - label_blocked_by_singular: "blocked by" - label_blocked__by_plural: "blocked by" - blocked_description: "This work package cannot be closed until the related one is closed first" - blocked_by_description: "This work package cannot be closed until the related one is closed first" - label_duplicates_singular: "duplicates" - label_duplicates_plural: "duplicates" - duplicates_description: "This is a copy of the related work package" - label_duplicated_singular: "duplicated by" - label_duplicated_plural: "duplicated by" - label_duplicated_by_singular: "duplicated by" - label_duplicated_by_plural: "duplicated by" - duplicated_by_description: "The related work package is a copy of this" - duplicated_description: "The related work package is a copy of this" - label_includes_singular: "includes" - label_includes_plural: "includes" - includes_description: "Marks the related work package as including this one with no additional effect" - label_partof_singular: "part of" - label_partof_plural: "part of" - label_part_of_singular: "part of" - label_part_of_plural: "part of" - partof_description: "Marks the related work package as being part of this one with no additional effect" + label_blocks_singular: "blochează" + label_blocks_plural: "blochează" + blocks_description: "Pachetul de lucru asociat nu poate fi închis până când acesta nu este închis mai întâi" + label_blocked_singular: "blocat de" + label_blocked_plural: "blocat de" + label_blocked_by_singular: "blocat de" + label_blocked__by_plural: "blocat de" + blocked_description: "Pachetul de lucru asociat nu poate fi închis până când acesta nu este închis mai întâi" + blocked_by_description: "Pachetul de lucru asociat nu poate fi închis până când acesta nu este închis mai întâi" + label_duplicates_singular: "dublează" + label_duplicates_plural: "dublează" + duplicates_description: "Aceasta este o copie a pachetului de lucru asociat" + label_duplicated_singular: "dublat de" + label_duplicated_plural: "dublat de" + label_duplicated_by_singular: "dublat de" + label_duplicated_by_plural: "dublat de" + duplicated_by_description: "Pachetul de lucru asociat este o copie a acestuia" + duplicated_description: "Pachetul de lucru asociat este o copie a acestuia" + label_includes_singular: "include" + label_includes_plural: "include" + includes_description: "Marchează pachetul de lucru asociat ca incluzând acesta, fără niciun efect suplimentar" + label_partof_singular: "parte din" + label_partof_plural: "parte din" + label_part_of_singular: "parte din" + label_part_of_plural: "parte din" + partof_description: "Marchează pachetul de lucru asociat ca incluzând acesta, fără niciun efect suplimentar" part_of_description: "Marks the related work package as being part of this one with no additional effect" label_requires_singular: "requires" label_requires_plural: "requires" @@ -863,6 +863,9 @@ ro: lag: "Lag" from: "Pachet de lucru" to: "Pachet de lucru asociat" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1451,6 +1454,7 @@ ro: login: "Utilizator" mail: "E-mail" name: "Nume" + note: "Note" password: "Parolă" priority: "Prioritate" project: "Proiect" @@ -1547,6 +1551,7 @@ ro: button_print: "Tipărește" button_quote: "Citare" button_remove: Eliminare + button_remove_reminder: "Remove reminder" button_rename: "Redenumire" button_replace: "Înlocuiește" button_revoke: "Revocă" @@ -1557,6 +1562,7 @@ ro: button_save_as: "Salvează ca" button_apply_changes: "Aplică modificările" button_save_back: "Salvează și înapoi" + button_set_reminder: "Set reminder" button_show: "Afişare" button_sort: "Sortare" button_submit: "Trimitere" @@ -1780,12 +1786,12 @@ ro: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Personalizați configurația formularului cu aceste add-on-uri suplimentare:" add_groups: "Adăugarea de noi grupuri de atribute" rename_groups: "Redenumirea grupurilor de atribute" - project_filters: - description_html: "Filtrarea și sortarea pe câmpuri personalizate este un supliment al ediției Enterprise." enumeration_activities: "Activități de urmărire timp activate" enumeration_work_package_priorities: "Priorități pentru pachetele de lucru" enumeration_reported_project_statuses: "Stările proiectului raportat" @@ -1818,6 +1824,7 @@ ro: error_pdf_export_too_many_columns: "Prea multe coloane selectate pentru exportul PDF. Vă rugăm să reduceți numărul de coloane." error_pdf_failed_to_export: "Exportul pdf nu poate fi salvat: %{error}" error_token_authenticity: "Nu se poate verifica tokenul Cross-Site Request Forgery. Ați încercat să trimiteți datele pe mai multe browsere sau tab-uri? Vă rugăm să închideți toate filele și să încercați din nou." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Pachetul de lucru nu a fost găsit sau nu aparține acestui proiect" error_work_package_id_not_found: "Pachetul de lucru nu a fost găsit." error_must_be_project_member: "trebuie să fie membru al proiectului" @@ -2106,16 +2113,17 @@ ro: notifications: reasons: assigned: "Executant" - dateAlert: "Alertă de dată" + dateAlert: "Alertă dată" mentioned: "Menţionat" responsible: "Responsabil" shared: "Partajat" watched: "Observator" + reminder: "Reminder" facets: unread: "Necitite" unread_title: "Afișare necitite" all: "Toate" - all_title: "Afișare toate" + all_title: "Afișează toate" menu: by_project: "Necitite după proiect" by_reason: "Motiv" @@ -2170,7 +2178,7 @@ ro: label_ical_access_key_revoke: "Revocă" label_add_column: "Adaugă coloană" label_applied_status: "Stare aplicată" - label_archive_project: "Proiect de arhivă" + label_archive_project: "Arhivează proiect" label_ascending: "Crescător" label_assigned_to_me_work_packages: "Pachete de lucru atribuite mie" label_associated_revisions: "Revizii asociate" @@ -2281,6 +2289,7 @@ ro: label_delete: "Delete" label_deleted: "șters" label_deleted_custom_field: "(câmp personalizat șters)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(opțiune eliminată)" label_empty_element: "(gol)" label_missing_or_hidden_custom_option: "(valoare lipsă sau lipsa permisiunilor de acces)" @@ -2317,7 +2326,6 @@ ro: label_enterprise_active_users: "%{current}/%{limit} numărul de utilizatori activi rezervați" label_enterprise_edition: "Ediția Enterprise" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Mediu" label_estimates_and_progress: "Estimări și progrese" label_equals: "este" @@ -2444,7 +2452,7 @@ ro: label_membership_plural: "Memberships" label_membership_added: "Membru adăugat" label_membership_updated: "Membru actualizat" - label_menu: "Menu" + label_menu: "Meniu" label_menu_badge: pre_alpha: "pre-alpha" alpha: "alfa" @@ -2553,7 +2561,7 @@ ro: label_project: "Proiect" label_project_activity: "Activitate proiect" label_project_attribute_plural: "Atributele proiectului" - label_project_attribute_manage_link: "Manage project attributes" + label_project_attribute_manage_link: "Gestionează atribute proiect" label_project_count: "Număr total de proiecte" label_project_copy_notifications: "Trimitere notificări e-mail în timpul copierii proiectului" label_project_latest: "Ultimele proiecte" @@ -2563,8 +2571,8 @@ ro: label_project_new: "Proiect nou" label_project_plural: "Proiecte" label_project_list_plural: "Listă proiecte" - label_project_attributes_plural: "Atributele proiectului" - label_project_custom_field_plural: "Atributele proiectului" + label_project_attributes_plural: "Atribute proiect" + label_project_custom_field_plural: "Atribute proiect" label_project_settings: "Setările proiectului" label_project_attributes_settings: "Project attributes settings" label_project_storage_plural: "File Storages" @@ -2666,6 +2674,7 @@ ro: label_this_month: "luna curentă" label_this_week: "săptămâna curentă" label_this_year: "anul curent" + label_time: "Time" label_time_entry_plural: "Timp consumat" label_time_entry_activity_plural: "Activități timp consumat" label_title: "Titlu" @@ -3054,7 +3063,7 @@ ro: permission_add_project: "Create projects" permission_add_work_package_attachments: "Adaugă fișiere" permission_add_work_package_attachments_explanation: "Allows adding attachments without Edit work packages permission" - permission_archive_project: "Proiect arhivat" + permission_archive_project: "Arhivare proiect" permission_create_user: "Create users" permission_manage_user: "Editează utilizatori" permission_manage_placeholder_user: "Creați, editați și ștergeți utilizatori de tip placeholder" @@ -3518,7 +3527,7 @@ ro: other: "Altele" passwords: "Parole" project_attributes: - heading: "Atributele proiectului" + heading: "Atribute proiect" label_new_attribute: "Atribut proiect" label_new_section: "Secțiune" label_edit_section: "Editează titlul" @@ -3820,6 +3829,12 @@ ro: edit_description: "Can view, comment and edit this work package." view: "Vizualizează" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/ru.seeders.yml b/config/locales/crowdin/ru.seeders.yml index faa5a996758a..a57c7fbefa62 100644 --- a/config/locales/crowdin/ru.seeders.yml +++ b/config/locales/crowdin/ru.seeders.yml @@ -244,7 +244,7 @@ ru: wiki: title: Спринт 1 content: | - ### Встреча по планированию спринта + ### Совещание по планированию спринта _Пожалуйста, документируйте здесь темы на встречу по планированию спринта_ @@ -288,7 +288,7 @@ ru: * Время (3 ч). * После просмотра спринта, будет модерироваться Scrum Master. - * Команда обсуждает весну: что пошло хорошо, что должно быть улучшено, чтобы быть более продуктивным для следующего спринта или даже весело. + * Команда обсуждает спринт: что пошло хорошо, что должно быть улучшено, чтобы быть более продуктивным для следующего спринта или даже весело. item_3: name: Спринт 2 categories: diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml index f598e9fd5659..d49252a81cd0 100644 --- a/config/locales/crowdin/ru.yml +++ b/config/locales/crowdin/ru.yml @@ -416,7 +416,7 @@ ru: one: "Однако, %{shared_work_packages_link} также был предоставлен этому пользователю." few: "Однако, %{shared_work_packages_link} так же были предоставлены этому пользователю." many: "Однако, %{shared_work_packages_link} так же были предоставлены этому пользователю." - other: "Однако, %{shared_work_packages_link} также был предоставлен этому пользователю." + other: "Однако, %{shared_work_packages_link} так же был предоставлен этому пользователю." however_work_packages_shared_with_group_html: one: "Однако, %{shared_work_packages_link} также был предоставлен этой группе." few: "Однако, %{shared_work_packages_link} так же были предоставлены этой группе." @@ -568,7 +568,7 @@ ru: Установите этот флажок, чтобы пометить пакеты работ как доступные только для чтения. Никакие атрибуты не могут быть изменены за исключением статуса.
- Примечание: Будут применены унаследованные значения (например, элементов предков или потомков). + Примечание: Будут применены унаследованные значения (например, от дочерних или родительских пакетов работ). index: no_results_title_text: В данный момент статусы пакетов работ отсутствуют. no_results_content_text: Добавить новый статус @@ -681,7 +681,7 @@ ru: follows_description: "Соответствующий пакет работ обязательно должен быть завершен до того, как начнется этот пакет" label_child_singular: "дочерний пакет работ" label_child_plural: "дочерние пакеты работ" - child_description: "Makes the related work package a sub-item of the current (parent) work package" + child_description: "Делает связанный пакет работ дочерним текущему (родительскому) пакету работ" label_blocks_singular: "блоки" label_blocks_plural: "блоки" blocks_description: "Связанный пакет работ не может быть закрыт до тех пор, пока не будет закрыт этот пакет" @@ -870,6 +870,9 @@ ru: lag: "Задержка" from: "Пакет работ" to: "Похожий пакет работ" + reminder: + remind_at_date: "Дата" + remind_at_time: "Время" repository: url: "URL" role: @@ -908,7 +911,7 @@ ru: comments_sorting: "Показывать комментарии" impaired: "Режим отображения для людей с ограниченными возможностями" time_zone: "Часовой пояс" - auto_hide_popups: "Автоматически скрывать успешные уведомления" + auto_hide_popups: "Автоматически скрывать уведомления об успешных действиях" warn_on_leaving_unsaved: "При покидании рабочего пакета предупреждать о не сохраненных изменениях" theme: "Режим" mode_guideline: "Некоторые режимы перезаписывают пользовательские цвета темы для удобства и удобочитаемости. Для полной пользовательской темы выберите светлый режим." @@ -1077,7 +1080,7 @@ ru: blank: "является обязательным. Пожалуйста, выберите имя." not_unique: "уже используется. Пожалуйста, выберите другое имя." meeting: - error_conflict: "Невозможно сохранить, потому что встреча была обновлена кем-то другим за это время. Пожалуйста, перезагрузите страницу." + error_conflict: "Невозможно сохранить, потому что совещание было обновлено кем-то другим за это время. Пожалуйста, перезагрузите страницу." notifications: at_least_one_channel: "Нужно указать хотя бы один канал для отправки уведомлений." attributes: @@ -1297,8 +1300,8 @@ ru: reused: one: "уже использовался ранее. Пожалуйста, укажите другое значение." few: "уже использовался ранее. Пожалуйста, укажите отличающийся пароль от %{count} использованных ранее." - many: "уже использовались ранее. Пожалуйста, укажите значения отличающиеся от %{count}." - other: "уже использовалось ранее. Пожалуйста, укажите значения отличающиеся от ваших последних %{count}." + many: "уже использовался ранее. Пожалуйста, укажите отличающийся пароль от %{count} использованных ранее." + other: "уже использовался ранее. Пожалуйста, укажите пароль отличающийся от использованных ранее %{count}." match: confirm: "Подтвердите новый пароль." description: "«Подтвержденный пароль» должен совпадать с введенным «новым паролем»." @@ -1468,6 +1471,7 @@ ru: login: "Имя пользователя" mail: "Электронная почта" name: "Имя" + note: "Заметка" password: "Пароль" priority: "Приоритет" project: "Проект" @@ -1564,6 +1568,7 @@ ru: button_print: "Печать" button_quote: "Цитата" button_remove: Удалить + button_remove_reminder: "Удалить напоминание" button_rename: "Переименовать" button_replace: "Заменить" button_revoke: "Отозвать" @@ -1574,6 +1579,7 @@ ru: button_save_as: "Сохранить как" button_apply_changes: "Применить изменения" button_save_back: "Сохранить и вернуться" + button_set_reminder: "Установить напоминание" button_show: "Показать" button_sort: "Сортировать" button_submit: "Отправить" @@ -1815,12 +1821,12 @@ ru: direction: Слева направо ee: upsale: + title: "Корпоративное дополнение" + link_title: "Дополнительная информация" form_configuration: description: "Настройте конфигурацию формы с помощью этих дополнительных дополнений:" add_groups: "Добавить новую группу атрибутов" rename_groups: "Переименовать группу атрибутов" - project_filters: - description_html: "Фильтрация и сортировка по настраиваемым полям - это функция корпоративной версии." enumeration_activities: "Отслеживание времени" enumeration_work_package_priorities: "Приоритеты пакета работ" enumeration_reported_project_statuses: "Перечень отчетов о статусах проекта" @@ -1853,6 +1859,7 @@ ru: error_pdf_export_too_many_columns: "Для экспорта в PDF-файл выбрано слишком много столбцов. Пожалуйста, сократите количество столбцов." error_pdf_failed_to_export: "Не удалось сохранить экспорт в PDF: %{error}" error_token_authenticity: "Не удалось проверить CSRF-токен. Возможно, вы попытались отправить данные сразу из нескольких браузеров или вкладок. Закройте все вкладки и попробуйте снова." + error_reminder_not_found: "Напоминание не было найдено или о нем уже было сообщено." error_work_package_not_found_in_project: "Пакет работ не найден или не принадлежит к этому проекту" error_work_package_id_not_found: "Пакет работ не найден." error_must_be_project_member: "должен быть участник проекта" @@ -1889,7 +1896,7 @@ ru: reply: Отвечено time_entry: "Время подключения отредактировано" wiki_page: "Wiki-страница отредактирована" - work_package_closed: "Комплекс работ закрыт" + work_package_closed: "Пакет работ закрыт" work_package_edit: "Пакет работ отредактирован" work_package_note: "Добавлено примечание к пакету работ" title: @@ -2146,6 +2153,7 @@ ru: responsible: "Ответственный" shared: "Общий доступ" watched: "Наблюдатель" + reminder: "Напоминания" facets: unread: "Непрочтено" unread_title: "Показать непрочитанные" @@ -2162,7 +2170,7 @@ ru: assigned: "Вы были назначены %{work_package}" subscribed: "Вы подписались на %{work_package}" mentioned: "Вы были назначены %{work_package}" - responsible: "Вы отвечаете за %{work_package}" + responsible: "Вы стали ответственным в %{work_package}" watched: "Вы просматриваете %{work_package}" label_accessibility: "Спец. возможности" label_account: "Учетная запись" @@ -2232,8 +2240,8 @@ ru: label_backup_code: "Код резервного копирования" label_basic_details: "Основные сведения" label_between: "между" - label_blocked_by: "заблокировано" - label_blocks: "блоки" + label_blocked_by: "блокируется" + label_blocks: "блокирует" label_blog: "Блог" label_forums_locked: "Заблокирован" label_forum_new: "Новый форум" @@ -2295,7 +2303,7 @@ ru: label_created_by: "Создано %{user}" label_current_status: "Текущий статус" label_current_version: "Текущий этап" - label_custom_field_add_no_type: "Добавьте это поле в тип комплекса работ" + label_custom_field_add_no_type: "Добавьте это поле в тип пакета работ" label_custom_field_new: "Новое настраиваемое поле" label_custom_field_plural: "Пользовательские поля" label_custom_field_default_type: "Пустой тип" @@ -2316,6 +2324,7 @@ ru: label_delete: "Удалить" label_deleted: "Удалено" label_deleted_custom_field: "(удалено настраиваемое поле)" + label_deleted_custom_item: "(удалено)" label_deleted_custom_option: "(удалённая опция)" label_empty_element: "(пусто)" label_missing_or_hidden_custom_option: "(отсутствует значение или недостаточно прав для доступа)" @@ -2336,7 +2345,7 @@ ru: label_downloads_abbr: "D/L" label_duplicated_by: "Дублируется" label_duplicate: "дублировать" - label_duplicates: "Дубликаты" + label_duplicates: "Дублирует" label_edit: "Правка" label_edit_x: "Правка: %{x}" label_enable_multi_select: "Разрешен множественный выбор" @@ -2352,7 +2361,6 @@ ru: label_enterprise_active_users: "%{current}/%{limit} забронировано активных пользователей" label_enterprise_edition: "Корпоративная версия" label_enterprise_support: "Поддержка корпоративной версии" - label_enterprise_addon: "Корпоративное дополнение" label_environment: "Переменные среды" label_estimates_and_progress: "Оценки и прогресс" label_equals: "—" @@ -2553,7 +2561,7 @@ ru: label_overall_activity: "Общая деятельность" label_overview: "Обзор" label_page_title: "Заголовок страницы" - label_part_of: "часть" + label_part_of: "является частью" label_password_lost: "Забыли пароль?" label_password_rule_lowercase: "Нижний регистр" label_password_rule_numeric: "Числовые символы" @@ -2642,7 +2650,7 @@ ru: label_repository_root: "Корень хранилища" label_repository_plural: "Репозитории" label_required: "требуется" - label_requires: "требуется" + label_requires: "требует выполнения" label_result_plural: "Результаты" label_revision: "Редакция" label_revision_id: "Редакция %{value}" @@ -2701,6 +2709,7 @@ ru: label_this_month: "в этом месяце" label_this_week: "на этой неделе" label_this_year: "в этом году" + label_time: "Время" label_time_entry_plural: "Затраченное время" label_time_entry_activity_plural: "Потраченное время" label_title: "Заголовок" @@ -2726,7 +2735,7 @@ ru: label_user_anonymous: "Анонимно" label_user_mail_option_all: "Для любого события на моих проектах" label_user_mail_option_none: "Нет событий" - label_user_mail_option_only_assigned: "Только для тех, к которым я причастен" + label_user_mail_option_only_assigned: "Только для тех, которые мне поручены" label_user_mail_option_only_my_events: "Только для тех, в которых я наблюдатель или участник" label_user_mail_option_only_owner: "Только для тех, которыми я владею" label_user_mail_option_selected: "Для любого события, но только для выбранных проектов" @@ -2738,7 +2747,7 @@ ru: label_version_new: "Новый этап" label_version_edit: "Изменить версию" label_version_plural: "Этапы" - label_version_sharing_descendants: "С подпроэктами" + label_version_sharing_descendants: "С подпроектами" label_version_sharing_hierarchy: "С иерархией проектов" label_version_sharing_none: "Не используется другими" label_version_sharing_system: "Во всех проектах" @@ -2775,11 +2784,11 @@ ru: label_work_package_hierarchy: "Иерархия пакета работ" label_work_package_new: "Новый пакет работ" label_work_package_edit: "Редактирование пакета работ %{name}" - label_work_package_plural: "Комплекс работ" + label_work_package_plural: "Пакет работ" label_work_package_status: "Статус пакета работ" label_work_package_status_new: "Новый статус" label_work_package_status_plural: "Статусы пакета работ" - label_work_package_types: "Типы рабочих пакетов" + label_work_package_types: "Типы пакетов работ" label_work_package_tracking: "Отслеживание пакета работ" label_work_package_view_all: "Посмотреть все пакеты работ" label_workflow: "Рабочий поток" @@ -3124,21 +3133,21 @@ ru: permission_edit_project: "Редактировать проект" permission_edit_project_attributes: "Редактирование атрибутов проекта" permission_edit_reportings: "Редактировать отчеты" - permission_edit_time_entries: "Редактировать журналы времени для других пользователей" + permission_edit_time_entries: "Править трудозатраты других пользователей" permission_edit_timelines: "Редактировать графики" permission_edit_wiki_pages: "Редактировать wiki-страницы" permission_export_work_packages: "Экспорт пакетов работ" permission_export_wiki_pages: "Экспорт wiki-страниц" permission_list_attachments: "Отобразить список прикреплённых файлов" - permission_log_own_time: "Регистрировать свое время" - permission_log_time: "Журнал времени для других пользователей" + permission_log_own_time: "Журналировать свои трудозатраты" + permission_log_time: "Журналировать трудозатраты других пользователей" permission_manage_forums: "Управление форумами" permission_manage_categories: "Управление категориями пакета работ" permission_manage_dashboards: "Управление панелями инструментов" permission_manage_work_package_relations: "Управление связями пакета работ" permission_manage_members: "Управление участниками" permission_manage_news: "Управление новостями" - permission_manage_project_activities: "Управление проектной деятельностью" + permission_manage_project_activities: "Активировать виды деятельности в проектах" permission_manage_public_queries: "Управление общими представлениями" permission_manage_repository: "Управление репозиторием" permission_manage_subtasks: "Управление иерархиями пакетов работ" @@ -3318,7 +3327,7 @@ ru: oauth_application_details_link_text: "Перейти на страницу настроек" setup_documentation_details: "Если вам нужна помощь в настройке нового хранилища файлов, пожалуйста, проверьте документацию: " setup_documentation_details_link_text: "Настройка файловых хранилищ" - show_warning_details: "Для использования этого хранилища файлов не забудьте активировать модуль и определенное хранилище в настройках проекта каждого желаемого проекта." + show_warning_details: "Для использования этого хранилища файлов не забудьте активировать модуль и конкретное хранилище в настройках проекта каждого желаемого проекта." subversion: existing_title: "Существующий репозиторий Subversion" existing_introduction: "Если у вас есть существующий репозиторий Subversion, вы можете связать его с OpenProject для доступа к нему из приложения." @@ -3423,12 +3432,12 @@ ru: setting_work_package_done_ratio: "Режим расчета прогресса" setting_work_package_done_ratio_field: "На основе трудозатрат" setting_work_package_done_ratio_field_caption_html: >- - % Завершения может быть свободно установлен на любое значение. Если Вы опционально введете значение для параметра Работа, то автоматически будет выведено значение Оставшаяся работа. + % Завершено может быть свободно установлен на любое значение. Если Вы опционально введете значение для параметра Предполагаемое время, то автоматически будет выведено значение Оставшиеся часы. setting_work_package_done_ratio_status: "На основе статуса" setting_work_package_done_ratio_status_caption_html: >- С каждым статусом связано значение % Завершения. Изменение статуса приведет к изменению % Завершения. setting_work_package_done_ratio_explanation_html: > - В режиме На основе трудозатрат для параметра % Завершения можно свободно установить любое значение. Если вы дополнительно введете значение «Работа», «Оставшаяся работа» будет получена автоматически. В режиме На основе статуса с каждым статусом связано значение % Завершения. Изменение статуса приведет к изменению % Завершения. + В режиме На основе трудозатрат для параметра % Завершено можно свободно установить любое значение. Если вы дополнительно введете значение «Предполагаемое время», «Оставшиеся часы» будут получены автоматически. В режиме На основе статуса с каждым статусом связано значение % Завершено. Изменение статуса приведет к изменению % Завершено. setting_work_package_properties: "Свойства пакета работ" setting_work_package_startdate_is_adddate: "Использовать текущую дату как дату начала для новых пакетов работ" setting_work_packages_projects_export_limit: "Ограничение экспорта пакетов работ / проектов" @@ -3447,10 +3456,10 @@ ru: setting_password_min_length: "Минимальная длина" setting_password_min_adhered_rules: "Минимальное количество необходимых классов" setting_per_page_options: "Количество объектов на страницу" - setting_percent_complete_on_status_closed: "% Завершения, когда статус закрыт" + setting_percent_complete_on_status_closed: "% Завершено, когда статус закрыт" setting_percent_complete_on_status_closed_no_change: "Без изменений" setting_percent_complete_on_status_closed_no_change_caption_html: >- - Значение % Завершения не изменится, даже если пакет работ будет закрыт. + Значение % Завершено не изменится, даже если пакет работ будет закрыт. setting_percent_complete_on_status_closed_set_100p: "Автоматически устанавливается на 100%" setting_percent_complete_on_status_closed_set_100p_caption: >- Закрытый пакет работ считается завершенным. @@ -3477,13 +3486,13 @@ ru: setting_sys_api_enabled: "Разрешить веб-сервис управления репозиторием" setting_sys_api_description: "Веб-сервис управления репозиторием обеспечивает интеграцию и авторизацию пользователя для доступа к репозиторию." setting_time_format: "Время" - setting_total_percent_complete_mode: "Расчет общего % Завершения полной иерархии" + setting_total_percent_complete_mode: "Расчёт общего % Завершено по всей иерархии" setting_total_percent_complete_mode_work_weighted_average: "Взвешенное по работе" setting_total_percent_complete_mode_work_weighted_average_caption_html: >- - Общий % Завершения будет взвешен по Работе каждого пакета работ в иерархии. Пакеты работ без Работы будут игнорироваться. + Общий % Завершено будет рассчитан как средневзвешенное значение по Предполагаемому времени каждого пакета работ в иерархии. Пакеты работ без Предполагаемого времени будут игнорироваться. setting_total_percent_complete_mode_simple_average: "Среднее арифметическое" setting_total_percent_complete_mode_simple_average_caption_html: >- - Работа игнорируется, и Общий % Завершения будет средним арифметическим значением % Завершения пакетов работ в иерархии. + Предполагаемое время игнорируется, и Общий % Завершено будет средним арифметическим от значений % Завершено пакетов работ в иерархии. setting_accessibility_mode_for_anonymous: "Разрешить режим доступа людей с ограниченными возможностями для анонимных пользователей" setting_user_format: "Формат имени пользователя" setting_user_default_timezone: "Часовой пояс пользователя по умолчанию" @@ -3611,7 +3620,7 @@ ru: text_custom_field_hint_activate_per_project: > Помните, что настраиваемые поля тоже нужно включать в каждом проекте по отдельности. text_custom_field_hint_activate_per_project_and_type: > - Настраиваемые поля нужно включать для каждого типа комплекса работ и для каждого проекта в отдельности. + Настраиваемые поля нужно включать для каждого типа пакета работ и для каждого проекта в отдельности. text_wp_status_read_only_html: > Корпоративная версия добавит эти дополнительные дополнения для полей статусов пакетов работ:
text_project_custom_field_html: > @@ -3855,6 +3864,12 @@ ru: edit_description: "Может просматривать, комментировать и редактировать этот пакет работ." view: "Просматривать" view_description: "Может просматривать этот пакет работ." + reminders: + label_remind_at: "Дата" + note_placeholder: "Причина установки напоминания" + success_creation_message: "Напоминание установлено. Вы получите уведомление о данном пакете работ в выбранное время." + success_update_message: "Напоминание успешно обновлено." + success_deletion_message: "Напоминание успешно удалено." sharing: count: zero: "0 пользователей" diff --git a/config/locales/crowdin/rw.yml b/config/locales/crowdin/rw.yml index 74151ba2acb3..6578d92e67e6 100644 --- a/config/locales/crowdin/rw.yml +++ b/config/locales/crowdin/rw.yml @@ -855,6 +855,9 @@ rw: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ rw: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ rw: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ rw: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ rw: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ rw: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ rw: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ rw: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ rw: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ rw: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3782,6 +3791,12 @@ rw: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/si.yml b/config/locales/crowdin/si.yml index 8bfb7f03cea4..31623c142dc5 100644 --- a/config/locales/crowdin/si.yml +++ b/config/locales/crowdin/si.yml @@ -855,6 +855,9 @@ si: lag: "Lag" from: "වැඩ පැකේජය" to: "අදාළ වැඩ පැකේජය" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "සැ. නි." role: @@ -1433,6 +1436,7 @@ si: login: "පරිශීලක නාමය" mail: "ඊ-තැපැල්" name: "නම" + note: "Note" password: "මුරපදය" priority: "ප්රමුඛතාව" project: "ව්යාපෘති" @@ -1529,6 +1533,7 @@ si: button_print: "මුද්රණය" button_quote: "උපුටා" button_remove: ඉවත් කරන්න + button_remove_reminder: "Remove reminder" button_rename: "නැවත නම් කරන්න" button_replace: "ප්රතිස්ථාපනය කරන්න" button_revoke: "අවලංගු" @@ -1539,6 +1544,7 @@ si: button_save_as: "ලෙස සුරකින්න" button_apply_changes: "Apply changes" button_save_back: "සුරකින්න සහ නැවත" + button_set_reminder: "Set reminder" button_show: "පෙන්වන්න" button_sort: "වර්ග" button_submit: "ඉදිරිපත් කරන්න" @@ -1744,12 +1750,12 @@ si: direction: LTR ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "නව ගුණාංග කණ්ඩායම් එකතු කරන්න" rename_groups: "ගුණාංග කණ්ඩායම් නැවත නම් කරන්න" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "කාලය සොයා ගැනීමේ ක්රියාකාරකම්" enumeration_work_package_priorities: "වැඩ පැකේජ ප්රමුඛතා" enumeration_reported_project_statuses: "වාර්තා කරන ලද ව්යාපෘති තත්ත්වය" @@ -1782,6 +1788,7 @@ si: error_pdf_export_too_many_columns: "PDF අපනයනය සඳහා තෝරාගෙන ඇති තීරු බොහොමයක්. කරුණාකර තීරු ගණන අඩු කරන්න." error_pdf_failed_to_export: "PDF අපනයනය සුරැකිය නොහැකි විය: %{error}" error_token_authenticity: "හරස් අඩවි ඉල්ලීම් ව්යාජ ටෝකනය සත්යාපනය කිරීමට නොහැකි විය. ඔබ බහු බ්රව්සර් හෝ ටැබ් මත දත්ත ඉදිරිපත් කිරීමට උත්සාහ කළාද? කරුණාකර සියලුම ටැබ් වසා නැවත උත්සාහ කරන්න." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "වැඩ පැකේජය සොයාගත නොහැකි හෝ මෙම ව්යාපෘතියට අයත් නොවේ" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "ව්යාපෘති සාමාජිකයෙකු විය යුතුය" @@ -2075,6 +2082,7 @@ si: responsible: "වගවීම" shared: "Shared" watched: "මුරකරු" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ si: label_delete: "Delete" label_deleted: "මකා දැමූ" label_deleted_custom_field: "(මකා දමන ලද අභිරුචි ක්ෂේත්රය)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(හිස්)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ si: label_enterprise_active_users: "%{current}/%{limit} වෙන් කර ඇති සක්රීය පරිශීලකයින්" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "පරිසරය" label_estimates_and_progress: "Estimates and progress" label_equals: "වේ" @@ -2630,6 +2638,7 @@ si: label_this_month: "මෙම මාසය" label_this_week: "මේ සතියේ" label_this_year: "මේ වසරේ" + label_time: "Time" label_time_entry_plural: "වැය කළ කාලය" label_time_entry_activity_plural: "Spent time activities" label_title: "මාතෘකාව" @@ -3782,6 +3791,12 @@ si: edit_description: "Can view, comment and edit this work package." view: "දැක්ම" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/sk.yml b/config/locales/crowdin/sk.yml index 4ff614a92a52..e847dd507cee 100644 --- a/config/locales/crowdin/sk.yml +++ b/config/locales/crowdin/sk.yml @@ -871,6 +871,9 @@ sk: lag: "Lag" from: "Pracovný balíček" to: "Súvisiaci pracovný balíček" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL adresa" role: @@ -1469,6 +1472,7 @@ sk: login: "Používateľské meno" mail: "E-mail" name: "Názov" + note: "Note" password: "Heslo" priority: "Priorita" project: "Projekt" @@ -1565,6 +1569,7 @@ sk: button_print: "Tlač" button_quote: "Citovať" button_remove: Vymazať + button_remove_reminder: "Remove reminder" button_rename: "Premenovať" button_replace: "Nahradiť" button_revoke: "Odvolať" @@ -1575,6 +1580,7 @@ sk: button_save_as: "Uložiť ako" button_apply_changes: "Apply changes" button_save_back: "Uloženie a návrat" + button_set_reminder: "Set reminder" button_show: "Ukázať" button_sort: "Zoradiť" button_submit: "Odoslať" @@ -1816,12 +1822,12 @@ sk: direction: zľava doprava ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Pridajte nové skupiny atribútov" rename_groups: "Premenovať skupiny atribútov" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Priority Pracovného balíka" enumeration_reported_project_statuses: "Nahlásený stav projektu" @@ -1854,6 +1860,7 @@ sk: error_pdf_export_too_many_columns: "Vybraných príliš veľa stĺpcov pre export do PDF. Znížte počet stĺpcov." error_pdf_failed_to_export: "PDF export nie je možné uložiť: %{error}" error_token_authenticity: "Nepodarilo sa overiť Token medzi lokalitami. Ak ste sa pokúsili uložiť údaje na viaceré karty alebo prehliadače, zatvorte ich a opätovne načítajte túto stránku a skúste to znova." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Pracovný balíček nebol nájdený alebo nepatrí k tomuto projektu" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "musíte byť členom projektu" @@ -2147,6 +2154,7 @@ sk: responsible: "Zodpovedný" shared: "Shared" watched: "Pozorovateľ" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2317,6 +2325,7 @@ sk: label_delete: "Delete" label_deleted: "odstránené" label_deleted_custom_field: "(odstrániť vlastné pole)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(prázdny)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2353,7 +2362,6 @@ sk: label_enterprise_active_users: "%{current}/%{limit} rezervovaných aktívnych užívateľov" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Prostredie" label_estimates_and_progress: "Estimates and progress" label_equals: "je" @@ -2702,6 +2710,7 @@ sk: label_this_month: "Tento mesiac" label_this_week: "tento týždeň" label_this_year: "Tento rok" + label_time: "Time" label_time_entry_plural: "Strávený čas" label_time_entry_activity_plural: "Spent time activities" label_title: "Nadpis" @@ -3859,6 +3868,12 @@ sk: edit_description: "Can view, comment and edit this work package." view: "Zobraziť" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/sl.yml b/config/locales/crowdin/sl.yml index 1531319f3905..36f22c107f9e 100644 --- a/config/locales/crowdin/sl.yml +++ b/config/locales/crowdin/sl.yml @@ -868,6 +868,9 @@ sl: lag: "Lag" from: "Zahtevek" to: "Soroden zahtevek" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1466,6 +1469,7 @@ sl: login: "Uporabniško ime" mail: "E-pošta" name: "Ime" + note: "Note" password: "Geslo" priority: "Prioriteta" project: "Projekt" @@ -1562,6 +1566,7 @@ sl: button_print: "Natisni" button_quote: "Citiraj" button_remove: Odstrani + button_remove_reminder: "Remove reminder" button_rename: "Preimenuj" button_replace: "Zamenjaj" button_revoke: "Prekliči" @@ -1572,6 +1577,7 @@ sl: button_save_as: "Shrani kot" button_apply_changes: "Apply changes" button_save_back: "Shrani in nazaj" + button_set_reminder: "Set reminder" button_show: "Pokaži" button_sort: "Razvrsti" button_submit: "Potrdi" @@ -1813,12 +1819,12 @@ sl: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Dodajte nove skupine atributov" rename_groups: "Preimenujte skupine atributov" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Dejavnosti spremljanja časa" enumeration_work_package_priorities: "Prednostne naloge delovnega paketa" enumeration_reported_project_statuses: "Poročano stanje projekta" @@ -1851,6 +1857,7 @@ sl: error_pdf_export_too_many_columns: "Za izvoz PDF je izbranih preveč stolpcev. Zmanjšajte število stolpcev." error_pdf_failed_to_export: "Izvoza PDF ni bilo mogoče shraniti: %{error}" error_token_authenticity: "Ni mogoče preveriti žetona ponarejanja zahteve na več mestih. Ste poskušali predložiti podatke v več brskalnikih ali zavihkih? Zaprite vse zavihke in poskusite znova.\n" + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Delovnega paketa/ zahtevka ni bilo mogoče najti ali ne spada v ta projekt" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "mora biti član projekta" @@ -2144,6 +2151,7 @@ sl: responsible: "Odgovorni" shared: "Shared" watched: "Opazovalec" + reminder: "Reminder" facets: unread: "Neprebrano" unread_title: "Pokaži neprebrano" @@ -2314,6 +2322,7 @@ sl: label_delete: "Delete" label_deleted: "Izbrisano" label_deleted_custom_field: "(izbrisano polje po meri)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(izbrisana možnost)" label_empty_element: "(prazno)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2350,7 +2359,6 @@ sl: label_enterprise_active_users: "%{current} /%{limit} rezervirani aktivni uporabniki" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Okolje" label_estimates_and_progress: "Estimates and progress" label_equals: "je" @@ -2699,6 +2707,7 @@ sl: label_this_month: "Ta mesec" label_this_week: "ta teden" label_this_year: "to leto" + label_time: "Time" label_time_entry_plural: "Porabljen čas" label_time_entry_activity_plural: "Spent time activities" label_title: "Naslov" @@ -3856,6 +3865,12 @@ sl: edit_description: "Can view, comment and edit this work package." view: "Ogled" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/sr.yml b/config/locales/crowdin/sr.yml index 33b6ce7293f2..64d3af8884cb 100644 --- a/config/locales/crowdin/sr.yml +++ b/config/locales/crowdin/sr.yml @@ -863,6 +863,9 @@ sr: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1451,6 +1454,7 @@ sr: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1547,6 +1551,7 @@ sr: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1557,6 +1562,7 @@ sr: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1780,12 +1786,12 @@ sr: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1818,6 +1824,7 @@ sr: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2111,6 +2118,7 @@ sr: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2281,6 +2289,7 @@ sr: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2317,7 +2326,6 @@ sr: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2666,6 +2674,7 @@ sr: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3821,6 +3830,12 @@ sr: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/sv.yml b/config/locales/crowdin/sv.yml index 69cd219e6932..8be74eafa698 100644 --- a/config/locales/crowdin/sv.yml +++ b/config/locales/crowdin/sv.yml @@ -854,6 +854,9 @@ sv: lag: "Lag" from: "Arbetspaket" to: "Relaterat arbetspaketet" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1432,6 +1435,7 @@ sv: login: "Användarnamn" mail: "E-post" name: "Namn" + note: "Note" password: "Lösenord" priority: "Prioritet" project: "Projekt" @@ -1528,6 +1532,7 @@ sv: button_print: "Skriv ut" button_quote: "Citat" button_remove: Ta bort + button_remove_reminder: "Remove reminder" button_rename: "Ändra namn" button_replace: "Ersätt" button_revoke: "Återkalla" @@ -1538,6 +1543,7 @@ sv: button_save_as: "Spara som" button_apply_changes: "Apply changes" button_save_back: "Spara och återgå" + button_set_reminder: "Set reminder" button_show: "Visa" button_sort: "Sortera" button_submit: "Skicka" @@ -1743,12 +1749,12 @@ sv: direction: Från vänster till höger ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Lägg till nya attributgrupper" rename_groups: "Byt namn på attributgrupper" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Arbetspaketsprioritering" enumeration_reported_project_statuses: "Rapporterad projektstatus" @@ -1781,6 +1787,7 @@ sv: error_pdf_export_too_many_columns: "För många kolumner har markerats för PDF-export. Vänlogen minska antalet kolumner." error_pdf_failed_to_export: "PDF-exporten kunde inte sparas: %{error}" error_token_authenticity: "Det gick inte att verifiera Forgery token. Försökte du skicka data på flera webbläsare eller flikar? Stäng alla flikar och försök igen." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Arbetspaketet hittades inte eller hör inte till detta projekt" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "måste vara projektmedlem" @@ -2074,6 +2081,7 @@ sv: responsible: "Huvudansvarig" shared: "Shared" watched: "Bevakare" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2244,6 +2252,7 @@ sv: label_delete: "Delete" label_deleted: "raderad" label_deleted_custom_field: "(raderat anpassat fält)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(tom)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2280,7 +2289,6 @@ sv: label_enterprise_active_users: "%{current}/%{limit} tilldelade aktiva användare" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Miljö" label_estimates_and_progress: "Estimates and progress" label_equals: "är" @@ -2629,6 +2637,7 @@ sv: label_this_month: "denna månad" label_this_week: "denna vecka" label_this_year: "i år" + label_time: "Time" label_time_entry_plural: "Förbrukad tid" label_time_entry_activity_plural: "Spent time activities" label_title: "Titel" @@ -3778,6 +3787,12 @@ sv: edit_description: "Can view, comment and edit this work package." view: "Vy" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 användare" diff --git a/config/locales/crowdin/th.yml b/config/locales/crowdin/th.yml index e622c7886da5..7bc18e323832 100644 --- a/config/locales/crowdin/th.yml +++ b/config/locales/crowdin/th.yml @@ -847,6 +847,9 @@ th: lag: "Lag" from: "ชุดภารกิจ" to: "ชุดภารกิจที่เกี่ยวข้อง" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1415,6 +1418,7 @@ th: login: "Username" mail: "อีเมล" name: "ชื่อ" + note: "Note" password: "รหัสผ่าน" priority: "ระดับความสำคัญ" project: "โครงการ" @@ -1511,6 +1515,7 @@ th: button_print: "Print" button_quote: "อ้างถึง" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "เปลี่ยนชื่อ" button_replace: "Replace" button_revoke: "Revoke" @@ -1521,6 +1526,7 @@ th: button_save_as: "บันทึกเป็น" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "แสดง" button_sort: "เรียงลำดับ" button_submit: "ส่งข้อมูล" @@ -1708,12 +1714,12 @@ th: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "ระดับความสำคัญของชุดภารกิจ" enumeration_reported_project_statuses: "สถานะโครงการที่รายงานแล้ว" @@ -1746,6 +1752,7 @@ th: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "ไม่พบชุดภารกิจ หรือชุดภารกิจไม่ได้เป็นของโครงการนี้" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "ต้องเป็นสมาชิกโครงการ" @@ -2039,6 +2046,7 @@ th: responsible: "Accountable" shared: "Shared" watched: "ผู้ดูข้อมูล" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2209,6 +2217,7 @@ th: label_delete: "Delete" label_deleted: "ถูกลบ" label_deleted_custom_field: "(ฟิลด์ที่กำหนดเองที่ถูกลบ)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(ว่าง)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2245,7 +2254,6 @@ th: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "สภาพแวดล้อม" label_estimates_and_progress: "Estimates and progress" label_equals: "เป็น" @@ -2594,6 +2602,7 @@ th: label_this_month: "เดือนนี้" label_this_week: "สัปดาห์นี้" label_this_year: "ปีนี้" + label_time: "Time" label_time_entry_plural: "เวลาที่ใช้" label_time_entry_activity_plural: "Spent time activities" label_title: "ชื่อเรื่อง" @@ -3743,6 +3752,12 @@ th: edit_description: "Can view, comment and edit this work package." view: "ดู" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml index 6f5afcef90d4..d3bf8c9876d9 100644 --- a/config/locales/crowdin/tr.yml +++ b/config/locales/crowdin/tr.yml @@ -853,6 +853,9 @@ tr: lag: "Gecikme" from: "İş paketi" to: "İlgili iş paketi" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1431,6 +1434,7 @@ tr: login: "Kullanıcı adı" mail: "Eposta" name: "İsim" + note: "Note" password: "Parola" priority: "Öncelik" project: "Proje" @@ -1527,6 +1531,7 @@ tr: button_print: "Yazdır" button_quote: "Alıntı" button_remove: Kaldır + button_remove_reminder: "Remove reminder" button_rename: "Yeniden adlandır" button_replace: "Değiştir" button_revoke: "İptal etmek" @@ -1537,6 +1542,7 @@ tr: button_save_as: "Farklı Kaydet" button_apply_changes: "Değişiklikleri uygula" button_save_back: "Kaydet ve geri dön" + button_set_reminder: "Set reminder" button_show: "Göster" button_sort: "Sırala" button_submit: "Gönder" @@ -1742,12 +1748,12 @@ tr: direction: soldan sağa ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Bu ek eklentilerle form yapılandırmasını özelleştirin:" add_groups: "Yeni öznitelik grubu ekleyin" rename_groups: "Öznitelik grubunun adını değiştirin" - project_filters: - description_html: "Özel alanlarda filtreleme ve sıralama, bir Enterprise sürümü eklentisidir." enumeration_activities: "Zaman izleme faaliyetleri" enumeration_work_package_priorities: "İş paketi öncelikleri" enumeration_reported_project_statuses: "Bildirilen proje durumları" @@ -1780,6 +1786,7 @@ tr: error_pdf_export_too_many_columns: "PDF Dışa Aktarma için çok fazla sütun seçili. Sütun sayısını azaltın." error_pdf_failed_to_export: "PDF çıktısı kaydedilemedi: %{error}" error_token_authenticity: "Siteler Arası İstek Sahteciliği belirteci doğrulanamadı. Birden fazla tarayıcı veya sekme hakkında veri göndermeyi denediniz mi? Lütfen tüm sekmeleri kapatın ve tekrar deneyin" + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Iş paketi bulunamadı veya bu projeye ait değil" error_work_package_id_not_found: "İş paketi bulunamadı." error_must_be_project_member: "projesi üyesi olmalıdır" @@ -2073,6 +2080,7 @@ tr: responsible: "Sorumlu" shared: "Shared" watched: "Takipçi" + reminder: "Reminder" facets: unread: "okunmamış" unread_title: "Okunmayanları göster" @@ -2243,6 +2251,7 @@ tr: label_delete: "Delete" label_deleted: "silindi" label_deleted_custom_field: "(özel alan silindi)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(silinen seçenek)" label_empty_element: "(boş)" label_missing_or_hidden_custom_option: "(eksik değer veya erişim izinleri eksik)" @@ -2279,7 +2288,6 @@ tr: label_enterprise_active_users: "%{current}/%{limit} aktif kullanıcı rezervasyonu" label_enterprise_edition: "Enterprise sürüm" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Ortam" label_estimates_and_progress: "Estimates and progress" label_equals: "şuysa" @@ -2628,6 +2636,7 @@ tr: label_this_month: "bu ay" label_this_week: "bu hafta" label_this_year: "bu yıl" + label_time: "Time" label_time_entry_plural: "Harcanan zaman" label_time_entry_activity_plural: "Spent time activities" label_title: "Başlık" @@ -3777,6 +3786,12 @@ tr: edit_description: "Can view, comment and edit this work package." view: "Göster" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/uk.yml b/config/locales/crowdin/uk.yml index 70a9d6a50678..68c36de7fee2 100644 --- a/config/locales/crowdin/uk.yml +++ b/config/locales/crowdin/uk.yml @@ -864,6 +864,9 @@ uk: lag: "Затримка" from: "Пакет робіт" to: "Пов'язаний робочий пакет" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "Посилання" role: @@ -1462,6 +1465,7 @@ uk: login: "Ім'я користувача" mail: "Електронна пошта" name: "Ім’я" + note: "Note" password: "Пароль" priority: "Пріоритет" project: "Проект" @@ -1558,6 +1562,7 @@ uk: button_print: "Друкувати" button_quote: "Цитата" button_remove: Видалити + button_remove_reminder: "Remove reminder" button_rename: "Перейменувати" button_replace: "Замінити" button_revoke: "Скасувати" @@ -1568,6 +1573,7 @@ uk: button_save_as: "Зберегти як" button_apply_changes: "Застосувати зміни" button_save_back: "Зберегти та повернутися назад" + button_set_reminder: "Set reminder" button_show: "Показати" button_sort: "Сортувати" button_submit: "Підтвердити" @@ -1809,12 +1815,12 @@ uk: direction: зліва направо ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Налаштуйте конфігурацію форми за допомогою цих додаткових доповнень:" add_groups: "Додати нові групи атрибутів" rename_groups: "Перейменувати групи атрибутів" - project_filters: - description_html: "Фільтрування і сортування за користувацькими полями доступне як доповнення версії Enterprise." enumeration_activities: "Дії щодо відстеження часу" enumeration_work_package_priorities: "Пріоритети робочого пакету" enumeration_reported_project_statuses: "Повідомлення про статус проекту" @@ -1847,6 +1853,7 @@ uk: error_pdf_export_too_many_columns: "Для експорту PDF-файлу вибрано занадто багато стовпців. Скоротіть кількість стовпців." error_pdf_failed_to_export: "Експорт PDF не вдалося зберегти: %{error}" error_token_authenticity: "Неможливо підтвердити маркер підробки для запиту між сайтами. Чи спробували ви надіслати дані для кількох веб-переглядачів або вкладок? Закрийте всі вкладки та повторіть спробу." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Робочий пакет не був знайдений або не належить до цього проекту" error_work_package_id_not_found: "Пакет робіт не знайдено." error_must_be_project_member: "повинен бути учасником проекту" @@ -2140,6 +2147,7 @@ uk: responsible: "Відповідальний" shared: "У спільному доступі" watched: "Спостерігач" + reminder: "Reminder" facets: unread: "Непрочитані" unread_title: "Показати непрочитані" @@ -2310,6 +2318,7 @@ uk: label_delete: "Delete" label_deleted: "вилучено " label_deleted_custom_field: "(видалено спеціальне поле)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(параметр видалення)" label_empty_element: "(пусто)" label_missing_or_hidden_custom_option: "(відсутнє значення або бракує дозволів для доступу)" @@ -2346,7 +2355,6 @@ uk: label_enterprise_active_users: "%{current}/%{limit} зареєстровано активних користувачів" label_enterprise_edition: "Версія Enterprise" label_enterprise_support: "Корпоративна підтримка" - label_enterprise_addon: "Доповнення версії Enterprise" label_environment: "Навколишнє середовище" label_estimates_and_progress: "Оцінки й прогрес виконання" label_equals: "є" @@ -2695,6 +2703,7 @@ uk: label_this_month: "цього місяця" label_this_week: "цього тижня" label_this_year: "цей рік" + label_time: "Time" label_time_entry_plural: "Трудовитрати" label_time_entry_activity_plural: "Завдання з обліком часу" label_title: "Назва" @@ -3850,6 +3859,12 @@ uk: edit_description: "Може переглядати, коментувати й редагувати цей пакет робіт." view: "Перегляд" view_description: "Може переглядати цей пакет робіт." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 користувачів" diff --git a/config/locales/crowdin/uz.yml b/config/locales/crowdin/uz.yml index 27ade628627b..215adb91cc82 100644 --- a/config/locales/crowdin/uz.yml +++ b/config/locales/crowdin/uz.yml @@ -855,6 +855,9 @@ uz: lag: "Lag" from: "Work package" to: "Related work package" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "URL" role: @@ -1433,6 +1436,7 @@ uz: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1529,6 +1533,7 @@ uz: button_print: "Print" button_quote: "Quote" button_remove: Remove + button_remove_reminder: "Remove reminder" button_rename: "Rename" button_replace: "Replace" button_revoke: "Revoke" @@ -1539,6 +1544,7 @@ uz: button_save_as: "Save as" button_apply_changes: "Apply changes" button_save_back: "Save and back" + button_set_reminder: "Set reminder" button_show: "Show" button_sort: "Sort" button_submit: "Submit" @@ -1744,12 +1750,12 @@ uz: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" enumeration_reported_project_statuses: "Reported project status" @@ -1782,6 +1788,7 @@ uz: error_pdf_export_too_many_columns: "Too many columns selected for the PDF export. Please reduce the number of columns." error_pdf_failed_to_export: "The PDF export could not be saved: %{error}" error_token_authenticity: "Unable to verify Cross-Site Request Forgery token. Did you try to submit data on multiple browsers or tabs? Please close all tabs and try again." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "The work package was not found or does not belong to this project" error_work_package_id_not_found: "The work package was not found." error_must_be_project_member: "must be project member" @@ -2075,6 +2082,7 @@ uz: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2245,6 +2253,7 @@ uz: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2281,7 +2290,6 @@ uz: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" @@ -2630,6 +2638,7 @@ uz: label_this_month: "this month" label_this_week: "this week" label_this_year: "this year" + label_time: "Time" label_time_entry_plural: "Spent time" label_time_entry_activity_plural: "Spent time activities" label_title: "Title" @@ -3782,6 +3791,12 @@ uz: edit_description: "Can view, comment and edit this work package." view: "View" view_description: "Can view this work package." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 users" diff --git a/config/locales/crowdin/vi.yml b/config/locales/crowdin/vi.yml index e167a120bdb2..c9d402cd9bc8 100644 --- a/config/locales/crowdin/vi.yml +++ b/config/locales/crowdin/vi.yml @@ -849,6 +849,9 @@ vi: lag: "Kết quả chậm" from: "Gói công việc" to: "Work package liên quan" + reminder: + remind_at_date: "Date" + remind_at_time: "Time" repository: url: "Đường dẫn (URL)" role: @@ -1417,6 +1420,7 @@ vi: login: "Tên người dùng" mail: "Thư điện tử" name: "Tên" + note: "Note" password: "Mật khẩu" priority: "Ưu tiên" project: "Dự án" @@ -1513,6 +1517,7 @@ vi: button_print: "In" button_quote: "Trích dẫn" button_remove: Xoá + button_remove_reminder: "Remove reminder" button_rename: "Đổi tên" button_replace: "Thay thế" button_revoke: "Thu hồi" @@ -1523,6 +1528,7 @@ vi: button_save_as: "Lưu thành" button_apply_changes: "Áp dụng thay đổi" button_save_back: "Lưu và trở lại" + button_set_reminder: "Set reminder" button_show: "Hiện" button_sort: "Sắp xếp" button_submit: "Gửi" @@ -1710,12 +1716,12 @@ vi: direction: ltr ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Tùy chỉnh cấu hình mẫu với các tiện ích bổ sung sau:" add_groups: "Thêm 1 nhóm thuộc tính" rename_groups: "Đổi tên nhóm thuộc tính" - project_filters: - description_html: "Lọc và sắp xếp trên các trường tùy chỉnh là một tiện ích bổ sung của phiên bản Enterprise." enumeration_activities: "Theo dõi hoạt động" enumeration_work_package_priorities: "Độ ưu tiên của work package" enumeration_reported_project_statuses: "Tình trạng dự án đã báo cáo" @@ -1748,6 +1754,7 @@ vi: error_pdf_export_too_many_columns: "Quá nhiều cột được chọn cho xuất PDF. Vui lòng giảm số lượng cột." error_pdf_failed_to_export: "Xuất PDF không thể được lưu: %{error}" error_token_authenticity: "Không thể xác minh token Cross-Site Request Forgery. Bạn có cố gắng gửi dữ liệu trên nhiều trình duyệt hoặc tab không? Vui lòng đóng tất cả các tab và thử lại." + error_reminder_not_found: "The reminder was not found or was already notified about." error_work_package_not_found_in_project: "Work package không được tìm thấy hoặc không thuộc về dự án này" error_work_package_id_not_found: "Không tìm thấy gói công việc." error_must_be_project_member: "phải là thành viên dự án" @@ -2041,6 +2048,7 @@ vi: responsible: "Có trách nhiệm" shared: "Được chia sẻ" watched: "Quan sát viên" + reminder: "Reminder" facets: unread: "Chưa đọc" unread_title: "Hiện chưa đọc" @@ -2211,6 +2219,7 @@ vi: label_delete: "Delete" label_deleted: "đã xóa" label_deleted_custom_field: "(đã xóa các mục tùy chỉnh)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(tùy chọn đã xóa)" label_empty_element: "(rỗng)" label_missing_or_hidden_custom_option: "(giá trị thiếu hoặc không có quyền truy cập)" @@ -2247,7 +2256,6 @@ vi: label_enterprise_active_users: "%{current}/%{limit} người dùng đang hoạt động đã đặt chỗ" label_enterprise_edition: "Phiên bản doanh nghiệp" label_enterprise_support: "Hỗ trợ doanh nghiệp" - label_enterprise_addon: "Tiện ích mở rộng doanh nghiệp" label_environment: "Môi trường" label_estimates_and_progress: "Ước lượng và tiến độ" label_equals: "là" @@ -2596,6 +2604,7 @@ vi: label_this_month: "tháng này" label_this_week: "tuần này" label_this_year: "năm này" + label_time: "Time" label_time_entry_plural: "Thời gian đã tiêu tốn" label_time_entry_activity_plural: "Hoạt động thời gian đã tiêu tốn" label_title: "Tiêu đề" @@ -3744,6 +3753,12 @@ vi: edit_description: "Có thể xem, nhận xét và chỉnh sửa gói công việc này." view: "Xem" view_description: "Có thể xem gói công việc này." + reminders: + label_remind_at: "Date" + note_placeholder: "Why are you setting this reminder?" + success_creation_message: "Reminder set successfully. You will receive a notification for this work package at the chosen time." + success_update_message: "Reminder updated successfully." + success_deletion_message: "Reminder deleted successfully." sharing: count: zero: "0 người dùng" diff --git a/config/locales/crowdin/zh-CN.yml b/config/locales/crowdin/zh-CN.yml index b6240c337f31..23fe7e16b37b 100644 --- a/config/locales/crowdin/zh-CN.yml +++ b/config/locales/crowdin/zh-CN.yml @@ -653,7 +653,7 @@ zh-CN: follows_description: "相关工作包必须在本工作包启动前完成" label_child_singular: "子节点" label_child_plural: "子节点" - child_description: "Makes the related work package a sub-item of the current (parent) work package" + child_description: "使相关工作包成为当前(父) 工作包的子项目" label_blocks_singular: "阻止" label_blocks_plural: "阻止" blocks_description: "在本工作包结束之前,相关工作包不能关闭" @@ -842,6 +842,9 @@ zh-CN: lag: "延迟" from: "工作包" to: "相关的工作包" + reminder: + remind_at_date: "日期" + remind_at_time: "时间" repository: url: "URL" role: @@ -1410,6 +1413,7 @@ zh-CN: login: "用户名" mail: "电子邮件" name: "名称" + note: "备注" password: "密码" priority: "优先级" project: "项目" @@ -1506,6 +1510,7 @@ zh-CN: button_print: "打印" button_quote: "引用" button_remove: 移除 + button_remove_reminder: "删除提醒" button_rename: "重命名" button_replace: "替换" button_revoke: "撤消" @@ -1516,6 +1521,7 @@ zh-CN: button_save_as: "另存为" button_apply_changes: "应用更改" button_save_back: "保存并返回" + button_set_reminder: "设置提醒" button_show: "显示" button_sort: "排序" button_submit: "提交" @@ -1703,12 +1709,12 @@ zh-CN: direction: 从左向右 ee: upsale: + title: "企业附加组件" + link_title: "更多信息" form_configuration: description: "使用以下附加组件自定义表单配置:" add_groups: "添加新属性组" rename_groups: "重命名属性组" - project_filters: - description_html: "自定义字段的过滤和排序是企业版附加组件。" enumeration_activities: "时间跟踪活动" enumeration_work_package_priorities: "工作包优先级" enumeration_reported_project_statuses: "报告的项目状态" @@ -1741,6 +1747,7 @@ zh-CN: error_pdf_export_too_many_columns: "选择 PDF 导出的列太多。请减少列数。" error_pdf_failed_to_export: "无法保存被导出的 PDF 文件:%{error}" error_token_authenticity: "无法验证跨站请求伪造令牌。您是否曾尝试在多个浏览器或选项卡上提交数据?请关闭所有选项卡并重试。" + error_reminder_not_found: "未找到提醒或已收到相关提醒的通知。" error_work_package_not_found_in_project: "工作包找不到或不属于此项目" error_work_package_id_not_found: "工作包未找到" error_must_be_project_member: "必须是项目成员" @@ -2034,6 +2041,7 @@ zh-CN: responsible: "负责人" shared: "共享" watched: "关注人" + reminder: "提醒" facets: unread: "未读" unread_title: "显示未读信息" @@ -2204,6 +2212,7 @@ zh-CN: label_delete: "删除" label_deleted: "已删除" label_deleted_custom_field: "(删除自定义字段)" + label_deleted_custom_item: "(删除项目)" label_deleted_custom_option: "(删除的选项)" label_empty_element: "(空)" label_missing_or_hidden_custom_option: "(缺少值或缺少访问权限)" @@ -2240,7 +2249,6 @@ zh-CN: label_enterprise_active_users: "%{current}/%{limit} 已预订的活跃用户" label_enterprise_edition: "企业版" label_enterprise_support: "企业支持" - label_enterprise_addon: "企业版附加组件" label_environment: "环境" label_estimates_and_progress: "预估和进度" label_equals: "是" @@ -2589,6 +2597,7 @@ zh-CN: label_this_month: "这个月" label_this_week: "这一周" label_this_year: "这一年" + label_time: "时间" label_time_entry_plural: "已耗工时" label_time_entry_activity_plural: "花费时间的活动" label_title: "标题" @@ -3732,6 +3741,12 @@ zh-CN: edit_description: "可以查看、评论和编辑此工作包。" view: "查看" view_description: "可以查看此工作包。" + reminders: + label_remind_at: "日期" + note_placeholder: "您为什么要设置此提醒?" + success_creation_message: "提醒设置成功。您将在所选时间收到此工作包的通知。" + success_update_message: "提醒更新成功。" + success_deletion_message: "提醒已成功删除。" sharing: count: zero: "0 个用户" diff --git a/config/locales/crowdin/zh-TW.yml b/config/locales/crowdin/zh-TW.yml index 4f3decd6c414..0fea08b1b753 100644 --- a/config/locales/crowdin/zh-TW.yml +++ b/config/locales/crowdin/zh-TW.yml @@ -490,12 +490,12 @@ zh-TW: groups: member_in_these_groups: "此用戶當前是以下群組的成員:" no_results_title_text: 這個使用者目前不是任何群組的成員 - summary_with_more: Member of %{names} and %{count_link}. - more: "%{count} more" - summary: Member of %{names}. + summary_with_more: '%{names} 和 %{count_link}的成員。' + more: "其餘 %{count} 項" + summary: '%{names}的成員。' memberships: no_results_title_text: 這個使用者目前不是任何專案的成員 - open_profile: "Open profile" + open_profile: "開啟個人資料" page: text: "文字" placeholder_users: @@ -637,9 +637,9 @@ zh-TW: label_edit_x: "編輯:%{x}" label_add_description: "新增說明" lag: - subject: "Lag" - title: "Lag (in days)" - caption: "The gap in number of working days in between the two work packages" + subject: "延遲" + title: "延遲(天數)" + caption: "兩個工作項目之間的工作天數差距" relations: label_relates_singular: "相關於" label_relates_plural: "相關於" @@ -647,15 +647,15 @@ zh-TW: label_relates_to_plural: "相關於" relates_description: "在兩個工作項目之間建立可見的連結,沒有額外影響" relates_to_description: "在兩個工作項目之間建立可見的連結,沒有額外影響" - label_precedes_singular: "繼承(後)" - label_precedes_plural: "繼承(後)" + label_precedes_singular: "後置任務(FS)" + label_precedes_plural: "後置任務(FS)" precedes_description: "相關的工作項目必須在完成後才開始執行" - label_follows_singular: "繼承(前)" - label_follows_plural: "繼承(前)" + label_follows_singular: "前置任務(SF)" + label_follows_plural: "前置任務(SF)" follows_description: "在這個工作項目開始之前,相關的工作必須先完成" label_child_singular: "子項目" label_child_plural: "子項目" - child_description: "Makes the related work package a sub-item of the current (parent) work package" + child_description: "使相關工作成為目前(父)工作項目的子項目" label_blocks_singular: "區塊" label_blocks_plural: "區塊" blocks_description: "在本工作項目結束之前,關聯工作無法結束" @@ -844,6 +844,9 @@ zh-TW: lag: "延遲" from: "工作項目" to: "相關的工作項目" + reminder: + remind_at_date: "日期" + remind_at_time: "時間" repository: url: "URL" role: @@ -932,7 +935,7 @@ zh-TW: messages: accepted: "必須被接受" after: "必須在 %{date} 之後" - after_today: "must be in the future." + after_today: "必須是未來時間。" after_or_equal_to: "必須在 %{date} 以後" before: "必須在 %{date} 之前" before_or_equal_to: "必須在 %{date} 以前" @@ -979,7 +982,7 @@ zh-TW: not_an_integer: "不是整數" not_an_iso_date: "不是有效日期。所需格式:YYYY-MM-DD。" not_same_project: "不屬於相同的專案" - datetime_must_be_in_future: "must be in the future." + datetime_must_be_in_future: "必須是未來時間。" odd: "必須是奇數" regex_match_failed: "與正則表達式 %{expression} 不匹配。" regex_invalid: "不能被相關聯的正則運算式驗證。" @@ -1412,6 +1415,7 @@ zh-TW: login: "使用者帳號" mail: "電子郵件" name: "名稱" + note: "備註" password: "密碼" priority: "優先等級" project: "專案" @@ -1508,6 +1512,7 @@ zh-TW: button_print: "列印" button_quote: "引言" button_remove: 刪除 + button_remove_reminder: "移除提醒" button_rename: "重新命名" button_replace: "取代" button_revoke: "撤銷" @@ -1518,6 +1523,7 @@ zh-TW: button_save_as: "另存為" button_apply_changes: "套用設定" button_save_back: "儲存並返回" + button_set_reminder: "設定提醒" button_show: "顯示" button_sort: "排序" button_submit: "提交" @@ -1705,12 +1711,12 @@ zh-TW: direction: 由左至右 ee: upsale: + title: "企業版附加元件" + link_title: "更多資訊" form_configuration: description: "使用以下附加組件自定義表單配置:" add_groups: "增加新的屬性群組" rename_groups: "重新命名屬性群组" - project_filters: - description_html: "自訂過濾條件和排序是企業版功能" enumeration_activities: "時間追蹤活動" enumeration_work_package_priorities: "工作項目優先等級" enumeration_reported_project_statuses: "報告的專案狀態" @@ -1743,6 +1749,7 @@ zh-TW: error_pdf_export_too_many_columns: "為 PDF 匯出選擇的列太多。請減少列數。" error_pdf_failed_to_export: "無法另存 pdf 匯出: %{error}" error_token_authenticity: "無法驗證跨網域請求權杖(Token)。你是不是試圖在多個瀏覽器或者分頁上傳送資料?請關閉所有的分頁後再試一次。" + error_reminder_not_found: "未找到提醒內容或已收到相關通知。" error_work_package_not_found_in_project: "工作項目找不到或是不屬於這個專案" error_work_package_id_not_found: "無此工作項目" error_must_be_project_member: "必須是專案的成員" @@ -2036,6 +2043,7 @@ zh-TW: responsible: "負責人" shared: "參與" watched: "監看者" + reminder: "提醒" facets: unread: "未讀" unread_title: "顯示未讀" @@ -2203,9 +2211,10 @@ zh-TW: label_default: "預設" label_delete_user: "刪除使用者" label_delete_project: "刪除專案" - label_delete: "Delete" + label_delete: "删除" label_deleted: "刪除線" label_deleted_custom_field: "(已刪除的客製欄位)" + label_deleted_custom_item: "(刪除項目)" label_deleted_custom_option: "(刪除的選項)" label_empty_element: "(空)" label_missing_or_hidden_custom_option: "(缺少值或缺少訪問權限)" @@ -2242,7 +2251,6 @@ zh-TW: label_enterprise_active_users: "%{current}/%{limit} 已預訂的活動使用者" label_enterprise_edition: "企業版" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "企業版附加插件" label_environment: "環境" label_estimates_and_progress: "預估和進度" label_equals: "是" @@ -2528,7 +2536,7 @@ zh-TW: label_reporting: "報表" label_reporting_plural: "報表" label_repository: "版本庫" - label_repository_remove: "Remove repository" + label_repository_remove: "移除儲存庫" label_repository_root: "版本庫根目錄" label_repository_plural: "Repositories" label_required: "必要" @@ -2591,6 +2599,7 @@ zh-TW: label_this_month: "本月" label_this_week: "本週" label_this_year: "今年" + label_time: "時間" label_time_entry_plural: "耗時" label_time_entry_activity_plural: "耗時活動" label_title: "標題" @@ -2626,7 +2635,7 @@ zh-TW: label_user_settings: "使用者設定" label_users_settings: "使用者設定" label_version_new: "新增版本" - label_version_edit: "Edit version" + label_version_edit: "編輯版本" label_version_plural: "版本" label_version_sharing_descendants: "與子專案" label_version_sharing_hierarchy: "有專案階層" @@ -2930,7 +2939,7 @@ zh-TW: notice_successful_connection: "連接成功" notice_successful_create: "建立成功" notice_successful_delete: "刪除成功" - notice_successful_cancel: "Successful cancellation." + notice_successful_cancel: "取消成功" notice_successful_update: "更新成功" notice_successful_update_custom_fields_added_to_project: | 更新成功。相關類型之專案,此客製欄位會自動啟動。看更多。 @@ -3038,7 +3047,7 @@ zh-TW: permission_select_project_modules: "選擇專案的模組" permission_share_work_packages: "參與工作項目" permission_manage_types: "選擇類型" - permission_manage_own_reminders: "Create own reminders" + permission_manage_own_reminders: "建立自己的提醒事項" permission_view_project: "檢視專案" permission_view_changesets: "在 OpenProject 檢視版本庫修訂" permission_view_commit_author_statistics: "檢視 Commit 的作者統計資訊" @@ -3738,6 +3747,12 @@ zh-TW: edit_description: "可以查看,留言與編輯此工作項目" view: "檢視" view_description: "查看此工作項目" + reminders: + label_remind_at: "日期" + note_placeholder: "為什麼要設定這個提醒?" + success_creation_message: "提醒設定成功。您會在選定的時間收到此工作項目的通知。" + success_update_message: "提醒成功更新" + success_deletion_message: "提醒已成功刪除。" sharing: count: zero: "0個用戶" diff --git a/config/locales/en.yml b/config/locales/en.yml index bcc880bf268e..e42776da9bd1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1522,6 +1522,7 @@ en: login: "Username" mail: "Email" name: "Name" + note: "Note" password: "Password" priority: "Priority" project: "Project" @@ -1853,12 +1854,12 @@ en: ee: upsale: + title: "Enterprise add-on" + link_title: "More information" form_configuration: description: "Customize the form configuration with these additional add-ons:" add_groups: "Add new attribute groups" rename_groups: "Rename attributes groups" - project_filters: - description_html: "Filtering and sorting on custom fields is an Enterprise edition add-on." enumeration_activities: "Time tracking activities" enumeration_work_package_priorities: "Work package priorities" @@ -2204,6 +2205,7 @@ en: responsible: "Accountable" shared: "Shared" watched: "Watcher" + reminder: "Reminder" facets: unread: "Unread" unread_title: "Show unread" @@ -2375,6 +2377,7 @@ en: label_delete: "Delete" label_deleted: "deleted" label_deleted_custom_field: "(deleted custom field)" + label_deleted_custom_item: "(deleted item)" label_deleted_custom_option: "(deleted option)" label_empty_element: "(empty)" label_missing_or_hidden_custom_option: "(missing value or lacking permissions to access)" @@ -2411,7 +2414,6 @@ en: label_enterprise_active_users: "%{current}/%{limit} booked active users" label_enterprise_edition: "Enterprise edition" label_enterprise_support: "Enterprise support" - label_enterprise_addon: "Enterprise add-on" label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index c5f781fb7d31..16d80a5b2dc6 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -709,6 +709,8 @@ en: new_notifications: message: "There are new notifications." link_text: "Click here to load them." + reminders: + note: "Note: “%{note}”" settings: change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.' title: "Notification settings" diff --git a/docker/dev/nextcloud/README.md b/docker/dev/nextcloud/README.md new file mode 100644 index 000000000000..98a046d12e0c --- /dev/null +++ b/docker/dev/nextcloud/README.md @@ -0,0 +1,15 @@ +A minimal setup to run a Nextcloud inside the TLS-enabled docker development stack. + +# First installation steps + +1. Allow accessing OP through `openproject.local`: + * `docker compose exec --user www-data nextcloud php occ config:system:set allow_local_remote_servers --value 1` +2. Import Dev CA cert into Nextcloud's own certificate store: + * `docker compose cp /path/to/your/OpenProject_Development_Root_CA.crt nextcloud:/tmp/root.crt` + * `docker compose exec nextcloud chown www-data /tmp/root.crt` + * `docker compose exec --user www-data nextcloud php occ security:certificates:import /tmp/root.crt` +3. Following [docs](https://docs.nextcloud.com/server/30/admin_manual/configuration_server/reverse_proxy_configuration.html#defining-trusted-proxies) configure Traefik as trusted proxy + * e.g. add `'trusted_proxies' => ['172.0.0.0/8'],` to `config/config.php` for a pretty broad allowance for most docker services (verify that your `gateway` network uses IPs in the given address range) +4. Download/Activate Nextcloud plugins: + * `integration_openproject` + * `groupfolders` (dependency for certain OP functions) diff --git a/docker/dev/nextcloud/docker-compose.yml b/docker/dev/nextcloud/docker-compose.yml new file mode 100644 index 000000000000..9db2fa4ef1a2 --- /dev/null +++ b/docker/dev/nextcloud/docker-compose.yml @@ -0,0 +1,35 @@ +services: + nextcloud: + image: nextcloud:stable + restart: unless-stopped + networks: + - gateway + volumes: + - nextcloud:/var/www/html + # If you want to use a local version of a plugin, mount a local folder + # more detailed instructions available at https://github.com/nextcloud/integration_openproject/blob/master/docs/setup_via_docker.md + # - ../nextcloud_apps:/var/www/html/custom_apps + labels: + - "traefik.enable=true" + - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.local`)" + - "traefik.http.routers.nextcloud.entrypoints=websecure" + + cron: + image: nextcloud:stable + restart: unless-stopped + volumes: + - nextcloud:/var/www/html + # If you want to use a local version of a plugin, mount a local folder + # more detailed instructions available at https://github.com/nextcloud/integration_openproject/blob/master/docs/setup_via_docker.md + # - ../nextcloud_apps:/var/www/html/custom_apps + networks: + - gateway + entrypoint: /cron.sh + +networks: + gateway: + external: true + name: gateway + +volumes: + nextcloud: diff --git a/docs/api/apiv3/components/examples/storage-create-folder-request-body.yml b/docs/api/apiv3/components/examples/storage-create-folder-request-body.yml new file mode 100644 index 000000000000..dad2d8b2e047 --- /dev/null +++ b/docs/api/apiv3/components/examples/storage-create-folder-request-body.yml @@ -0,0 +1,5 @@ +description: |- + A valid request body to create a new folder on a external storage +value: + name: Uploads + parentId: "200" diff --git a/docs/api/apiv3/components/schemas/storage_folder_write_model.yml b/docs/api/apiv3/components/schemas/storage_folder_write_model.yml new file mode 100644 index 000000000000..bcdef5c9e552 --- /dev/null +++ b/docs/api/apiv3/components/schemas/storage_folder_write_model.yml @@ -0,0 +1,13 @@ +# Schema: StorageFolderWriteModel +--- +type: object +required: + - name + - parentId +properties: + name: + type: string + description: Name of the folder to be created + parentId: + type: string + description: Unique identifier of the parent folder in which the new folder should be created in diff --git a/docs/api/apiv3/openapi-spec.yml b/docs/api/apiv3/openapi-spec.yml index 53c78bf3b7a5..67f025f81ba1 100644 --- a/docs/api/apiv3/openapi-spec.yml +++ b/docs/api/apiv3/openapi-spec.yml @@ -392,6 +392,8 @@ paths: "$ref": "./paths/storage_files.yml" "/api/v3/storages/{id}/files/prepare_upload": "$ref": "./paths/storage_files_prepare_upload.yml" + "/api/v3/storages/{id}/folders": + "$ref": "./paths/storage_folders.yml" "/api/v3/storages/{id}/oauth_client_credentials": "$ref": "./paths/storage_oauth_client_credentials.yml" "/api/v3/storages/{id}/open": @@ -547,6 +549,8 @@ components: $ref: "./components/examples/status_response.yml" StorageNextcloudResponse: $ref: "./components/examples/storage-nextcloud-response.yml" + StorageCreateFolderRequestBody: + $ref: "./components/examples/storage-create-folder-request-body.yml" StorageNextcloudResponseForCreation: $ref: "./components/examples/storage-nextcloud-response-for-creation.yml" StorageNextcloudUnauthorizedResponse: @@ -829,6 +833,8 @@ components: "$ref": "./components/schemas/storage_file_model.yml" StorageFilesModel: "$ref": "./components/schemas/storage_files_model.yml" + StorageFolderWriteModel: + "$ref": "./components/schemas/storage_folder_write_model.yml" StorageFileUploadPreparationModel: "$ref": "./components/schemas/storage_file_upload_preparation_model.yml" StorageFileUploadLinkModel: diff --git a/docs/api/apiv3/paths/storage_folders.yml b/docs/api/apiv3/paths/storage_folders.yml new file mode 100644 index 000000000000..1e22c776775f --- /dev/null +++ b/docs/api/apiv3/paths/storage_folders.yml @@ -0,0 +1,68 @@ +# /api/v3/storages/{id}/folders +--- +post: + summary: Creation of a new folder + operationId: create_storage_folder + tags: + - File links + description: Creates a new folder under the given parent + parameters: + - name: id + description: Storage id + in: path + required: true + schema: + type: integer + example: 1337 + requestBody: + content: + application/json: + schema: + $ref: '../components/schemas/storage_folder_write_model.yml' + examples: + 'Valid example': + $ref: '../components/examples/storage-create-folder-request-body.yml' + responses: + '201': + description: Created + content: + application/hal+json: + schema: + $ref: '../components/schemas/storage_file_model.yml' + '400': + content: + application/hal+json: + schema: + $ref: '../components/schemas/error_response.yml' + example: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:InvalidQuery + message: The given parent is not a directory. + description: |- + Returned if the request is missing a required parameter. + '403': + content: + application/hal+json: + schema: + $ref: '../components/schemas/error_response.yml' + example: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission + message: You are not authorized to access this resource. + description: |- + Returned if the client does not have sufficient permissions. + + **Required permission:** manage file links + '404': + content: + application/hal+json: + schema: + $ref: '../components/schemas/error_response.yml' + example: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + description: |- + Returned if the storage does not exist or the client does not have sufficient permissions to see it. + + **Required permission:** view file links diff --git a/docs/contributions-guide/give-back-to-community/README.md b/docs/contributions-guide/give-back-to-community/README.md index 34ba45efe638..a2fd2768fc89 100644 --- a/docs/contributions-guide/give-back-to-community/README.md +++ b/docs/contributions-guide/give-back-to-community/README.md @@ -15,7 +15,7 @@ OpenProject thrives on the strength and engagement of its Community. Beyond codi > [!IMPORTANT] > By submitting your content, we assume that you grant us permission to publish it on our platforms. If you would like to review the content before it is published, please let us know explicitly, and we will be happy to accommodate your request. -Your unique experience with OpenProject can inspire others and provide valuable feedback to our team. Here are some ideas for sharing your story: +Your unique experience with OpenProject can inspire others and provide valuable feedback to our team. Here are some ideas for sharing your story, preferably in English (or German): - **Written Texts** Create a brief article (0.5–2 pages) that covers the following topics: @@ -31,7 +31,7 @@ Your unique experience with OpenProject can inspire others and provide valuable - **Blog Posts** Write a detailed blog post about your OpenProject journey. You can either: - - Submit your blog post for publication on the OpenProject website. [Contact us](https://www.openproject.org/contact/) for guidelines. + - Submit your blog post for publication on the OpenProject website. - Publish it on your own channels (website, blog, or LinkedIn) and link back to OpenProject. - **Video Contributions** @@ -40,11 +40,14 @@ Your unique experience with OpenProject can inspire others and provide valuable - **Testimonials and Quotes** Share a short testimonial or quote about your experience with OpenProject. If possible, **include a professional photo** of yourself or your team for publication. +[Contact us](https://www.openproject.org/contact/) for guidelines. + ## Support us online Help OpenProject reach more users by engaging with our content and sharing it with your network. -- **Social Media Posts** +- **Social media posts** + - Share your experience with OpenProject on your social channels, including a link to our website. - You can also re-share content from the [OpenProject blog](https://www.openproject.org/blog/) or our official social media accounts. @@ -57,7 +60,7 @@ Help OpenProject reach more users by engaging with our content and sharing it wi [Follow us on Twitter/X](https://twitter.com/openproject) [Follow us on Bluesky](https://bsky.app/profile/openproject.bsky.social) -- **Add a Backlink to Your Website** +- **Add a backlink to your website** Include a link to OpenProject’s website on your blog, portfolio, or company website to help more people discover our tool. - **Write a Review** Share your thoughts about OpenProject on one of our review platforms. [Leave a review ](https://www.openproject.org/reviews/). diff --git a/docs/glossary/README.md b/docs/glossary/README.md index c23fa716d015..82a03e84c3e5 100644 --- a/docs/glossary/README.md +++ b/docs/glossary/README.md @@ -49,7 +49,7 @@ OpenProject offers Attribute help texts that provide additional information for ### Authentication -In OpenProject, authentication is an important element to guarantee a data protected usage. To adapt these authentication settings, you need to have [admin](#admin) rights. Navigate to your username and select -> Administration -> Authentication. At OpenProject, we use [OAuth 2.0](#oauth) as this is the definitive industry standard for online authorization. +In OpenProject, authentication is an important element to guarantee a data protected usage. To adapt these authentication settings, you need to have [admin](#admin) rights. Navigate to your username and select --> Administration --> Authentication. At OpenProject, we use [OAuth 2.0](#oauth) as this is the definitive industry standard for online authorization. **More information on authentication in OpenProject** @@ -122,9 +122,7 @@ A custom action in OpenProject is defined as customizable buttons which trigger ### Custom field -In OpenProject, a custom field is defined as an additional field which can be added to existing fields. Custom fields can be created for the following resources: [work packages](#work-package), [spent time](#time-and-costs), [versions](#versions), [users](#user), and [groups](#group). - -![Custom fields in OpenProject](glossary-openproject-custom-field.png) +In OpenProject, a custom field is defined as an additional field which can be added to existing fields. Custom fields can be created for the following resources: [work packages](#work-package), [spent time](#time-and-costs), [versions](#versions), [users](#user), and [groups](#group). If you want to add a custom field that refers to a project (or several projects), navigate to Administration --> Projects and create a [project attribute](#project-attribute). **More information on custom fields in OpenProject** @@ -360,6 +358,10 @@ The quick context menu in OpenProject opens when you open a [work package table] ## R +## Relations + +In OpenProject, you can set work packages in relation to each other. Some relation types simply create a visible link between the two work packages. Others have an additional effect, e.g. force one work package to be finished before the other one starts (Predecessor). The simpliest way to add a relation between two existing work packages is to click the +Relation button on the Relations tab of one of the work packages. [Read more about work package relations and hierarchies in our user guide](../user-guide/work-packages/work-package-relations-hierarchies/). + ## Repository A repository is defined as a document or source code management system that allows users to manage files and folders via different version control systems (such as Subversion or Git). [Read more about Repository for source code control](../user-guide/repository/). @@ -485,3 +487,9 @@ A list of work packages is considered a view. The containing work packages in an ### WYSIWYG editor WYSIWYG stands for 'What you see is what you get'. A WYSIWYG editor is a content editing interface that allows users to create and edit content so that it visually resembles the final result. In OpenProject, you can use WYSIWYG editors in [wikis](#wiki), [forums](#forum) and [work package](#work-package) descriptions and comments. + +## Z + +### Zen mode + +In OpenProject, Zen mode allows users to focus on a certain page, as all other menu items and elements are hidden, and the page is displayed in full screen. OpenProject offers zen mode for other modules like work packages, boards, Gantt charts, calendars, and project lists. \ No newline at end of file diff --git a/docs/release-notes/15-1-0/README.md b/docs/release-notes/15-1-0/README.md index 4a1f193a647d..b09238ecef6f 100644 --- a/docs/release-notes/15-1-0/README.md +++ b/docs/release-notes/15-1-0/README.md @@ -17,32 +17,37 @@ In these Release Notes, we will give an overview of important feature changes an ### Custom fields of type hierarchy (Enterprise add-on) -Enterprise customers can now use a new type of custom field that allows **multi-level selections**. This makes it easier for users to organize and navigate complex data in structured, multi-level formats within work packages. The new custom fields of the hierarchy type can be added to work packages and then structured into several lower-level values. +Enterprise customers can now use a new type of custom field that allows **multi-level selections in a hierarchial way**. This makes it easier for users to organize and navigate complex data in structured, multi-level formats within work packages. The new custom fields of the hierarchy type can be added to work packages and then structured into several lower-level items. Each custom field of type hierarchy can be given a short name (e.g. B for Berlin). Here's an example of how custom fields of the hierarchy type look like, using the example of a detailed assignment of workspaces: ![Example screenshot of custom fields of type hierarchy, displaying different cities as main offices](openproject-15-1-custom-field-hierarchy.jpg) -[Read all about custom fields in our system admin guide](../../system-admin-guide/custom-fields/). +[Read all about this new type of custom field in our system admin guide](../../system-admin-guide/custom-fields/#hierarchy-custom-field-enterprise-add-on). ### Redesign of the Relations tab in work packages -The Relations tab in work packages has been completely redesigned using Primer design system, including a **new dropdown menu that allows you to directly choose the type of relation**, e.g. if the related work package is a successor and necessarily needs to start after the selected one finishes. +The Relations tab in work packages has been completely redesigned using Primer design system, including a **new dropdown menu that allows you to directly choose the type of relation**, e.g. if the related work package is a successor (earlier called 'Follows') and necessarily needs to start after the selected one finishes. Scroll down to see more types of relations. Additionally, you can now add a description to add further information about the relation. Please note that the description will be displayed on both work packages, below the related other work package. > [!NOTE] -> Important information: With this redesign, **you will no longer be able to create new work packages directly on the Relations tab**. Please tell us if you were using this feature a lot. If it will be missed by many users, we will find a way to bring it back. +> Important information: With this redesign, **you will no longer be able to create new work packages directly on the Relations tab**. We are already working on a solution and plan to release this feature early next year. Thank you for your understanding. ![Screenshot showing the new Relations tab in a work package](openproject-15-1-relations.png) +> [!TIP] +> As a workaround you can [include a table of related work packages to work package forms (Enterprise add-on)](../../system-admin-guide/manage-work-packages/work-package-types/#add-table-of-related-work-packages-to-a-work-package-form-enterprise-add-on). Under this table you can directly create new children work packages or link existing ones. + +![A table of related work packages in OpenProject](open_project_admin_related_wp_table.png) + [Read all about work package relations and hierarchies in our user guide](../../user-guide/work-packages/work-package-relations-hierarchies/). ### Redesign of the Meetings index page -The index page of the Meetings module has been redesigned with Primer as well, making it easier to read and have a more modern look. You see your list of meetings in some kind of table view, with the columns being: Title, Date and time, Duration, and Location. +The index page of the Meetings module has been redesigned with Primer as well, making it easier to read and adding a more modern look. You see your list of meetings in column view, with the columns being: Title, Date and time, Duration, and Location. -The + Meeting button in the top right corner now offers a dropdown menu where you can directly choose whether you want to add a dynamic or classic meeting. +The + Meeting button in the top right corner now offers a dropdown menu where you can directly choose whether you want to add a dynamic or a classic meeting. Here's an example screenshot of the redesigned Meetings index page: @@ -52,7 +57,7 @@ Here's an example screenshot of the redesigned Meetings index page: ### Manual page breaks in PDF work package exports -With our work package export feature, people can generate good-looking PDFs. Sometimes, however, the page break comes at an inconvenient place. With version 15.1, users can now force a manual page break in the work package description. This ensures, for example, that a signature can always be inserted on the correct page. +With our work package export feature, people can generate good-looking PDFs. Sometimes, however, the page break comes at an inconvenient place. With version 15.1, users can now force a manual page break in the work package description. This ensures, for example, that a signature can always be inserted on the correct page. Please note that logically, manual page breaks only work if the work package description is part of the PDF export – and not in the PDF export of a work package table if you choose the export type 'Table'. ![Example of a work package description with an employee contract and inserted page breaks](openproject-15-1-page-break-contract-highlighted.png) @@ -60,7 +65,7 @@ With our work package export feature, people can generate good-looking PDFs. Som ### Zen mode for project lists -Zen mode allows users to focus on a certain page, as all other menu items and elements are hidden, and the page is displayed in full screen. OpenProject already offers zen mode for other modules like Work packages, Boards, Gantt charts or Calendar – and with version 15.1 also for project lists. +Zen mode allows users to focus on a certain page, as all other menu items and elements are hidden, and the page is displayed in full screen. OpenProject already offers zen mode for other modules like Work packages, Boards, Gantt charts or Calendars – and with version 15.1 also for project lists. Here is how zen mode for project lists looks like: @@ -74,7 +79,7 @@ Here is how zen mode for project lists looks like: Administrators of automated deployments can now choose to skip the automatically integrated creation of an admin user. This is useful if you have set up an LDAP or SSO integration – such as those used for openDesk environments – and you want to prevent the admin user from logging in. Administrators no longer have to manually disable this automatically created admin user and thus run the risk of forgetting to do so, which would pose a security risk. -Read more about [seeding through environment for OpenProject configuration in our Installation & operations guide](../../installation-and-operations/configuration/#seeding-through-environment) +Read more about [seeding through environment for OpenProject configuration in our Installation & operations guide](../../installation-and-operations/configuration/#seeding-through-environment). @@ -89,20 +94,30 @@ Read more about [seeding through environment for OpenProject configuration in ou - Bugfix: Sorting by custom field has strong impact on performance for the project list \[[#57305](https://community.openproject.org/wp/57305)\] - Bugfix: Absent value for custom field is ordered not consistently at the beginning or end for different formats \[[#57554](https://community.openproject.org/wp/57554)\] - Bugfix: Notification on a mention added to an edited comment is not triggered \[[#58007](https://community.openproject.org/wp/58007)\] -- Bugfix: Sidebar menu should be hidden when page width is reduced \[[#58454](https://community.openproject.org/wp/58454)\] - Bugfix: Info box on new custom field of type hierarchy is permanent \[[#58466](https://community.openproject.org/wp/58466)\] - Bugfix: Item add form disappears after added a new item to a custom field of type hierarchy \[[#58467](https://community.openproject.org/wp/58467)\] - Bugfix: Using multi-select and required options do not work \[[#58635](https://community.openproject.org/wp/58635)\] - Bugfix: HTML files served as plain text \[[#58646](https://community.openproject.org/wp/58646)\] - Bugfix: Performance issues on work\_packages api endpoint \[[#58689](https://community.openproject.org/wp/58689)\] - Bugfix: Breadcrumb of hierarchy items has left margin \[[#58700](https://community.openproject.org/wp/58700)\] +- Bugfix: Missing hint in comment box label \[[#59060](https://community.openproject.org/wp/59060)\] +- Bugfix: Automatic comments to indicate retractions miss a stem (newest on top) \[[#59278](https://community.openproject.org/wp/59278)\] - Bugfix: Add local spacing to inline enterprise banner \[[#59284](https://community.openproject.org/wp/59284)\] - Bugfix: Hierarchy custom fields causing 500 on custom actions \[[#59354](https://community.openproject.org/wp/59354)\] +- Bugfix: Files count badge missing in Files tab (WP full view) \[[#59391](https://community.openproject.org/wp/59391)\] - Bugfix: Signing in after two factor methods have been deleted lead to a 500 error \[[#59408](https://community.openproject.org/wp/59408)\] - Bugfix: User without permission to "Save views" can save changes to work package views \[[#59479](https://community.openproject.org/wp/59479)\] - Bugfix: Double provider showing on OpenID provider list \[[#59510](https://community.openproject.org/wp/59510)\] +- Bugfix: SAML provider not available when migrated with idp\_cert\_fingerprint \[[#59535](https://community.openproject.org/wp/59535)\] - Bugfix: Hierarchy items not correctly displayed if custom field is shown in wp table \[[#59572](https://community.openproject.org/wp/59572)\] -- Bugfix: Buttons not visible on iOS in edit relations modal \[[#59772](https://community.openproject.org/wp/59772)\] +- Bugfix: Export of an unsaved query not working properly \[[#59781](https://community.openproject.org/wp/59781)\] +- Bugfix: No comments possible for shared work packages that were shared with "Comment" permission \[[#59785](https://community.openproject.org/wp/59785)\] +- Bugfix: Missing space between project selector and "include sub-projects"-checkbox \[[#59795](https://community.openproject.org/wp/59795)\] +- Bugfix: Work package create button doesn't work on mobile Web \[[#59828](https://community.openproject.org/wp/59828)\] +- Bugfix: Trailing ' in journal diff parameter activity\_page breaks page \[[#59865](https://community.openproject.org/wp/59865)\] +- Bugfix: Regression: Meeting sorted in reverse order \[[#59908](https://community.openproject.org/wp/59908)\] +- Bugfix: Not possible to update auto-discovered values \[[#59928](https://community.openproject.org/wp/59928)\] +- Bugfix: Form buttons are left aligned and not right aligned in hierarchy items form \[[#59978](https://community.openproject.org/wp/59978)\] - Feature: Work package PDF export: Insert page breaks \[[#44047](https://community.openproject.org/wp/44047)\] - Feature: Zen mode for project lists page \[[#52150](https://community.openproject.org/wp/52150)\] - Feature: Create and edit custom field of type hierarchy \[[#57806](https://community.openproject.org/wp/57806)\] @@ -116,19 +131,20 @@ Read more about [seeding through environment for OpenProject configuration in ou - Feature: Add enterprise gateway to creation of custom fields of type hierarchy \[[#58865](https://community.openproject.org/wp/58865)\] - Feature: Primer: Implement proper mobile behaviour for BoxTable \[[#59248](https://community.openproject.org/wp/59248)\] - Feature: Allow locking of the seeded admin user \[[#59722](https://community.openproject.org/wp/59722)\] +- Feature: Remove feature flag custom\_field\_of\_type\_hierarchy \[[#59864](https://community.openproject.org/wp/59864)\] ## Contributions -A very special thank you goes to our sponsors of this release: Deutsche Bahn for sponsoring custom fields of type hierarchy, and City of Cologne for sponsoring custom fields of type hierarchy as well as zen mode for project lists. +A very special thank you goes to Deutsche Bahn and City of Cologne for sponsoring parts of this release. Your support, alongside the efforts of our amazing Community, helps drive these innovations. Also, a big thanks to our Community members for reporting bugs and helping us identify and provide fixes. Special thanks for reporting and finding bugs go to Bill Bai, Sam Yelman, Knight Chang, Gábor Alexovics, Gregor Buergisser, Andrey Dermeyko, Various Interactive, Clayton Belcher, Александр Татаринцев, and Keno Krewer. Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings! This release we would like to highlight -- [José Helbert Pina](https://crowdin.com/profile/GZTranslations), for a great number of translations into Portuguese. - [Alexander Aleschenko](https://crowdin.com/profile/top4ek), for a great number of translations into Russian. -- [Adam Siemienski](https://crowdin.com/profile/siemienas), for a great number of translations into Polish. +- [José Helbert Pina](https://crowdin.com/profile/GZTranslations), for a great number of translations into Portuguese. +- [BigSeung](https://crowdin.com/profile/BigSeung), for a great number of translations into Korean. Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/15-1-0/open_project_admin_related_wp_table.png b/docs/release-notes/15-1-0/open_project_admin_related_wp_table.png new file mode 100644 index 000000000000..ec45fbf9539f Binary files /dev/null and b/docs/release-notes/15-1-0/open_project_admin_related_wp_table.png differ diff --git a/docs/release-notes/README.md b/docs/release-notes/README.md index 0aa676ccdc3e..c486e0a64f66 100644 --- a/docs/release-notes/README.md +++ b/docs/release-notes/README.md @@ -13,6 +13,13 @@ Stay up to date and get an overview of the new features included in the releases +## 15.1.0 + +Release date: 2024-12-11 + +[Release Notes](15-1-0/) + + ## 15.0.2 Release date: 2024-11-20 diff --git a/docs/security-and-privacy/statement-on-security/README.md b/docs/security-and-privacy/statement-on-security/README.md index 1ec599e5d2ad..3265d43ef7ff 100644 --- a/docs/security-and-privacy/statement-on-security/README.md +++ b/docs/security-and-privacy/statement-on-security/README.md @@ -14,6 +14,13 @@ Automated tests and manual code reviews ensure that these contributions are safe For more information on security and data privacy for OpenProject, please visit: [www.openproject.org/security-and-privacy](https://www.openproject.org/security-and-privacy/). +**security.txt** + +OpenProject uses the `security.txt` standard for defining security policies. +You can find our `security.txt` here: https://www.openproject.org/security.txt + +Please see https://securitytxt.org/ for more information. + ## Security announcements mailing list If you want to receive immediate security notifications via email as we publish them, please sign up to our security mailing list: https://www.openproject.org/security-and-privacy/#mailing-list. diff --git a/docs/system-admin-guide/integrations/README.md b/docs/system-admin-guide/integrations/README.md index b24dcd746fdb..0b6661cb845f 100644 --- a/docs/system-admin-guide/integrations/README.md +++ b/docs/system-admin-guide/integrations/README.md @@ -5,7 +5,7 @@ sidebar_navigation: description: Integration to OpenProject. keywords: projects, integration, Jira --- -# Integrations and community plugins +# Integrations and Community plugins There are various integrations and Community plugins out there. Please [contact us](https://www.openproject.org/contact/) if you want to have your plugin to be added to this list. diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/README.md b/docs/user-guide/work-packages/work-package-relations-hierarchies/README.md index 6696a4e932c1..38df9343c8a1 100644 --- a/docs/user-guide/work-packages/work-package-relations-hierarchies/README.md +++ b/docs/user-guide/work-packages/work-package-relations-hierarchies/README.md @@ -25,12 +25,15 @@ Relations indicate any functional or timely relation (e.g. follows or proceeds, Work package relations indicate that work packages address a similar topic or create status dependencies. To create a relationship between two work packages: -1. Select a work package, click on **Relations** to open the relations tab and click the **+ Create new relations** link. +1. Select a work package, click on **Relations** to open the relations tab and click the **+ Relation** button. 2. Select the type of relationship from the dropdown menu. -3. Enter the ID or name of the work package, to which the relation should be created and choose an entry from the dropdown menu. The autocompleter suggests the work package to be added. -4. Press the Enter key. +3. Enter the ID or name of the work package, to which the relation should be created. The autocomplete will suggest the work package to be added. +4. Enter a description of the relation. It will be visible for both of the related work packages. +5. Press the Enter key and click the **Save** button. -![autocompletion](autocompletion.png) +![autocompletion](openproject_user_guide_wp_add_relations_button.png) + +![Add a related work package in OpenProject](openproject_user_guide_wp_add_relations_form.png) You can select one of the following relations: @@ -38,26 +41,33 @@ You can select one of the following relations: - **Duplicates / Duplicated by** - This option indicates that the work package B duplicates a work package A in one way or another, for example both address the same task. This can be useful if you have the same work package that needs to be a part of a closed and public projects at the same time. The connection in this case is only semantic, the changes you make in work package A will need to be adapted in work package B manually. - **Note**: some changes in statuses will be adjusted automatically for the duplicated work package. Specifically, if the status of a work package A is set to be "closed" (or set to any status that is defined to count as "closed" in the [system settings](../../../system-admin-guide/manage-work-packages/work-package-status/), for example "rejected" often counts as a "closed" status), the status of the work package B will change to "closed". Note that this is direction dependent. Only if the work package A is closed will the work package B be closed as well, not the other way around. +> [!NOTE] +> some changes in statuses will be adjusted automatically for the duplicated work package. Specifically, if the status of a work package A is set to be "closed" (or set to any status that is defined to count as "closed" in the [system settings](../../../system-admin-guide/manage-work-packages/work-package-status/), for example "rejected" often counts as a "closed" status), the status of the work package B will change to "closed". Note that this is direction dependent. Only if the work package A is closed will the work package B be closed as well, not the other way around. - **Blocks / Blocked by** - This option defines status change restrictions between two work packages. If you set a work package A to be blocking work package B, the status of work package B cannot be set to closed or resolved until the work package A is closed. -- **Precedes / Follows** - Defines a chronological relation between two work packages. For example, if you set a work package A to precede a work package B, the start date of B has to be at least a day after the finish date of A. +- **Predecessor (before)/ Successor (after)** - Defines a chronological relation between two work packages. For example, if you set a work package A to precede a work package B, the start date of B has to be at least a day after the finish date of A. Please note: If work package B is in [manual scheduling mode](../../gantt-chart/scheduling/#manual-scheduling-mode), changing the finish date of work package A will have no effect on work package B. +> [!TIP] +> Prior to 15.1, *Predecessor (before)* was called *Precedes*, and *Successor (after)* was called *Follows*. + - **Includes / Part of** - Defines if work package A includes or is part of work package B. This relation type can be used for example when you have a roll-out work package and work packages which should be shown as included without using hierarchical relationships. There is no additional effect. - **Requires / Required by** - Defines if work package A requires or is required by work package B. There is no additional effect. -The selected relation status will be automatically displayed in the work package that you enter. For example if you select "Blocks" in the current work package A and specify work package B, work package B will automatically show that it is "Blocked by" A. +- **Child** - Makes the related a work package a sub-item of the current (parent) work package + +> [!TIP] +> The selected relation status will be automatically displayed in the work package that you enter. For example if you select "Blocks" in the current work package A and specify work package B, work package B will automatically show that it is "Blocked by" A. ### Moving related work packages -The precedes/follows relation is the only one that can constrain or affect the dates of work packages. +The predecessor/successor relation is the only one that can constrain or affect the dates of work packages. -Work packages in a precedes/follows relationship do not need to immediately follow one other; there can be a gap. In this case, you can move either forwards or backwards in time without affecting the other as long as the finish date of the predecessor is before the start date of follower. +Work packages in a predecessor/successor relationship do not need to immediately follow one other; there can be a gap. In this case, you can move either forwards or backwards in time without affecting the other as long as the finish date of the predecessor is before the start date of successor. -A follower cannot be moved to start before the finish date of its predecessor. However, a predecessor can indeed be moved to start or finish _after_ the start date of its follower. When this happens, the follower will be pushed into the future such that it starts the day after the new finish date of the predecessor. +A successor cannot be moved to start before the finish date of its predecessor. However, a predecessor can indeed be moved to start or finish _after_ the start date of its successor. When this happens, the successor will be pushed into the future such that it starts the day after the new finish date of the predecessor. ## Display relations in a work package table (Enterprise add-on) @@ -65,15 +75,15 @@ As a user of [Enterprise on-premises](https://www.openproject.org/enterprise-edi This is useful if you want to get an overview of certain types of relationships between work packages. You can for example see which work packages are blocking other work packages. -To add relation columns, navigate to the upper right corner of the work package table and click on the icon with the three dots. **... insert columns** an type the name of the relation into the search bar. Then select the relation and click on apply. +To add relation columns, navigate to the upper right corner of the work package table and click on the icon with the three dots. Select **Insert columns** and type the name of the relation into the search bar. Then select the relation and click on apply. -![work package add relation as column](work-package-add-relation-as-column.png) +![work package add relation as column](openproject_user_guide_wp_table_configuration.png) The relations column shows the number of relations each work package has for the relation type (e.g. "blocked by"). You can click on the number to display the work packages which have the relation type. -![Relations column](Relations_column.png) +![Relations column](openproject_user_guide_wp_table_configuration_filtered.png) ## Work package hierarchies @@ -81,21 +91,29 @@ Work packages can be structured hierarchically, e.g. in order to break down a la ## Add a child work package -There are **three ways to add or create a child work package**: +There are **four ways to add or create a child work package**: + +1. [Adding a child in the *Relations* tab in a work package's details view](#add-a-child-in-the-relations-tab-in-a-work-packages-details-view) -1. Adding or creating a child in the *Relations* tab in a work package's details view 2. Right-clicking on a work package in the work package table and select "Create new child" + 3. Right-clicking on a work package in the work package table and select "Indent hierarchy" to add it as the child of the work package above it. + ![Add a child in a work package table](openproject_user_guide_wp_table_add_child.png) + +4. You can add a child work package directly under the table of related work packages. To do that you first need to [include a table of related work packages to work package forms (Enterprise add-on)](../../../system-admin-guide/manage-work-packages/work-package-types/#add-table-of-related-work-packages-to-a-work-package-form-enterprise-add-on). + + ![A table of related work packages in OpenProject](open_project_admin_related_wp_table.png) + ### Add a child in the *Relations* tab in a work package's details view -Open a work package and select the tab *Relations*. Click on *+ Create new child* to create a child work package. Alternatively, you can assign an existing child work package with *+ Add existing child*. +Open a work package and select the tab *Relations*. Click on *+ Relation* button, scroll down the list of options and select *Child*. -![User guide hierarchies](User-guide-hierarchies.png) +![Add a child](openproject_user_guide_wp_add_child.png) -Insert the name of the new work package and save the newly created work package by pressing *Enter*. You can make changes to the work package by clicking on the work package ID. +Insert the name of the new work package and save the newly added child work package by clicking *Save* button. -![create work package children](image-20200129144540902.png) +![Select a child work package in OpenProject](openproject_user_guide_wp_add_child_select.png) For more information on the work package creation take a look at the guideline on [creating a work package](../create-work-package). @@ -103,19 +121,19 @@ For more information on the work package creation take a look at the guideline o To edit or remove the parent of a work package open the work package. At the top of the details view of the work package you will see the work package hierarchy. Click on the **edit icon** or **delete icon** to change the work package parent. -![change parent work package](change-parent-work-package.png) +![change parent work package](openproject_user_guide_relations_change_parent.png) ## Display work package hierarchies After adding the parent and child work packages they are listed in the *Relations* tab. Note that only the children are shown in the relations tab and the parent isn't. -![work package relations](image-20200129145033802.png) +![Work package relations displayed in the relations tab in OpenProject](openproject_user_guide_relations_tab.png) Hierarchies can also be displayed from the work package table view. To display work package hierarchies make sure the *Subject* column is displayed. You can activate or deactivate the hierarchy by pressing the icon next to the Subject. -![User guide display hierarchy](User-guide-display-hierarchy.png) +![User guide display hierarchy](openproject_user_guide_wp_hierarchy_icon.png) You can also add a column with information about parent work packages: @@ -123,4 +141,4 @@ You can also add a column with information about parent work packages: 2. Select "Parent" from the drop down menu and click on apply. 3. Now the column with the information about a parent relation is displayed in the work package table. -![select parent as column](select-parent-as-column.png) +![Select parent as column in OpenProject work package tables](openproject_user_guide_wp_table_show_parent.png) diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/Relations_column.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/Relations_column.png deleted file mode 100644 index c36b42e71f38..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/Relations_column.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/User-guide-display-hierarchy.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/User-guide-display-hierarchy.png deleted file mode 100644 index 57342dfd2517..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/User-guide-display-hierarchy.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/User-guide-hierarchies.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/User-guide-hierarchies.png deleted file mode 100644 index 318dd943c212..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/User-guide-hierarchies.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/autocompletion.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/autocompletion.png deleted file mode 100644 index 01ee6855a69e..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/autocompletion.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/change-parent-work-package.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/change-parent-work-package.png deleted file mode 100644 index a792b39dcfef..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/change-parent-work-package.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/image-20200129144540902.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/image-20200129144540902.png deleted file mode 100644 index c0c3435beebe..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/image-20200129144540902.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/image-20200129145033802.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/image-20200129145033802.png deleted file mode 100644 index 71f70fff7f5d..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/image-20200129145033802.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/open_project_admin_related_wp_table.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/open_project_admin_related_wp_table.png new file mode 100644 index 000000000000..ec45fbf9539f Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/open_project_admin_related_wp_table.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_relations_change_parent.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_relations_change_parent.png new file mode 100644 index 000000000000..ef30b3882e02 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_relations_change_parent.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_relations_tab.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_relations_tab.png new file mode 100644 index 000000000000..eaadbadf2650 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_relations_tab.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_child.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_child.png new file mode 100644 index 000000000000..8d80bdd24e93 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_child.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_child_select.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_child_select.png new file mode 100644 index 000000000000..050648046e74 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_child_select.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_relations_button.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_relations_button.png new file mode 100644 index 000000000000..ad5b7c7c0b2b Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_relations_button.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_relations_form.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_relations_form.png new file mode 100644 index 000000000000..52e688357a36 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_add_relations_form.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_hierarchy_icon.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_hierarchy_icon.png new file mode 100644 index 000000000000..e5fb37abfb89 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_hierarchy_icon.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_add_child.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_add_child.png new file mode 100644 index 000000000000..da3aad1acb67 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_add_child.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_configuration.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_configuration.png new file mode 100644 index 000000000000..49c0d8a2bac1 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_configuration.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_configuration_filtered.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_configuration_filtered.png new file mode 100644 index 000000000000..c46bc8373987 Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_configuration_filtered.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_show_parent.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_show_parent.png new file mode 100644 index 000000000000..160f7263b61b Binary files /dev/null and b/docs/user-guide/work-packages/work-package-relations-hierarchies/openproject_user_guide_wp_table_show_parent.png differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/select-parent-as-column.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/select-parent-as-column.png deleted file mode 100644 index 86b42970de01..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/select-parent-as-column.png and /dev/null differ diff --git a/docs/user-guide/work-packages/work-package-relations-hierarchies/work-package-add-relation-as-column.png b/docs/user-guide/work-packages/work-package-relations-hierarchies/work-package-add-relation-as-column.png deleted file mode 100644 index 02e993c1967b..000000000000 Binary files a/docs/user-guide/work-packages/work-package-relations-hierarchies/work-package-add-relation-as-column.png and /dev/null differ diff --git a/frontend/src/app/core/main-menu/main-menu-toggle.service.ts b/frontend/src/app/core/main-menu/main-menu-toggle.service.ts index 6db9707b6dca..f98505cc2413 100644 --- a/frontend/src/app/core/main-menu/main-menu-toggle.service.ts +++ b/frontend/src/app/core/main-menu/main-menu-toggle.service.ts @@ -66,12 +66,18 @@ export class MainMenuToggleService { private changeData = new BehaviorSubject({}); public changeData$ = this.changeData.asObservable(); + private wasHiddenDueToResize = false; + + private wasCollapsedByUser = false; constructor( protected I18n:I18nService, public injector:Injector, readonly deviceService:DeviceService, ) { + this.initializeMenu(); + // Add resize event listener + window.addEventListener('resize', this.onWindowResize.bind(this)); } public initializeMenu():void { @@ -80,45 +86,57 @@ export class MainMenuToggleService { } this.elementWidth = parseInt(window.OpenProject.guardedLocalStorage(this.localStorageKey) as string); - const menuCollapsed = window.OpenProject.guardedLocalStorage(this.localStorageStateKey) as string; + const menuCollapsed = window.OpenProject.guardedLocalStorage(this.localStorageStateKey) === 'true'; + + // Set the initial value of the collapse tracking flag + this.wasCollapsedByUser = menuCollapsed; if (!this.elementWidth) { this.saveWidth(this.mainMenu.offsetWidth); - } else if (menuCollapsed && JSON.parse(menuCollapsed)) { + } else if (menuCollapsed) { this.closeMenu(); } else { this.setWidth(); } - const currentProject:CurrentProjectService = this.injector.get(CurrentProjectService); - if (jQuery(document.body).hasClass('controller-my') && this.elementWidth === 0 || currentProject.id === null) { - this.saveWidth(this.defaultWidth); - } + this.adjustMenuVisibility(); + } - // small desktop version default: hide menu on initialization - this.closeWhenOnSmallDesktop(); + private onWindowResize():void { + this.adjustMenuVisibility(); + } + + private adjustMenuVisibility():void { + if (window.innerWidth >= 1012) { + // On larger screens, reopen the menu if it was hidden only due to screen resizing + if (this.wasHiddenDueToResize && !this.wasCollapsedByUser) { + this.setWidth(this.defaultWidth); + this.wasHiddenDueToResize = false; // Reset the flag since the menu is now shown + } + } else if (this.showNavigation) { + this.closeMenu(); + this.wasHiddenDueToResize = true; // Indicate that the menu was hidden due to resize + } } - // click on arrow or hamburger icon public toggleNavigation(event?:JQuery.TriggeredEvent|Event):void { if (event) { event.stopPropagation(); event.preventDefault(); } - if (!this.showNavigation) { // sidebar is hidden -> show menu - if (this.deviceService.isSmallDesktop) { // small desktop version - this.setWidth(window.innerWidth); - } else { // desktop version - const savedWidth = parseInt(window.OpenProject.guardedLocalStorage(this.localStorageKey) as string); - const widthToSave = savedWidth >= this.elementMinWidth ? savedWidth : this.defaultWidth; + // Update the user collapse flag and clear `wasHiddenDueToResize` + this.wasCollapsedByUser = this.showNavigation; + this.wasHiddenDueToResize = false; // Reset because a manual toggle overrides any resize behavior - this.saveWidth(widthToSave); - } - } else { // sidebar is expanded -> close menu + if (this.showNavigation) { this.closeMenu(); + } else { + this.openMenu(); } + // Save the collapsed state in localStorage + window.OpenProject.guardedLocalStorage(this.localStorageStateKey, String(!this.showNavigation)); // Set focus on first visible main menu item. // This needs to be called after AngularJS has rendered the menu, which happens some when after(!) we leave this // method here. So we need to set the focus after a timeout. @@ -129,48 +147,43 @@ export class MainMenuToggleService { public closeMenu():void { this.setWidth(0); - window.OpenProject.guardedLocalStorage(this.localStorageStateKey, 'true'); jQuery('.searchable-menu--search-input').blur(); } - public closeWhenOnSmallDesktop():void { - if (this.deviceService.isSmallDesktop) { - this.closeMenu(); - window.OpenProject.guardedLocalStorage(this.localStorageStateKey, 'false'); - } - } - - public saveWidth(width?:number):void { - this.setWidth(width); - window.OpenProject.guardedLocalStorage(this.localStorageKey, String(this.elementWidth)); - window.OpenProject.guardedLocalStorage(this.localStorageStateKey, String(this.elementWidth === 0)); + public openMenu():void { + this.setWidth(this.defaultWidth); } - public setWidth(width?:any):void { + public setWidth(width?:number):void { if (width !== undefined) { - // Leave a minimum amount of space for space for the content - const maxMenuWidth = this.deviceService.isSmallDesktop ? window.innerWidth - 120 : window.innerWidth - 520; - if (width > maxMenuWidth) { - this.elementWidth = maxMenuWidth; - } else { - this.elementWidth = width as number; - } + this.elementWidth = width; } + // Apply the width directly to the main menu + this.mainMenu.style.width = `${this.elementWidth}px`; + + // Apply to root CSS variable for any related layout adjustments + this.htmlNode.style.setProperty('--main-menu-width', `${this.elementWidth}px`); + + // Check if menu is open or closed and apply CSS class if needed + this.toggleClassHidden(); this.snapBack(); this.setToggleTitle(); - this.toggleClassHidden(); - this.global.showNavigation = this.showNavigation; - this.htmlNode.style.setProperty('--main-menu-width', `${this.elementWidth}px`); + // Save the width if it's open + if (this.elementWidth > 0) { + window.OpenProject.guardedLocalStorage(this.localStorageKey, String(this.elementWidth)); + } + } - // Send change event when size of menu is changing (menu toggled or resized) - const changeEvent = jQuery.Event('change'); - this.changeData.next(changeEvent); + public saveWidth(width?:number):void { + this.setWidth(width); + window.OpenProject.guardedLocalStorage(this.localStorageKey, String(this.elementWidth)); + window.OpenProject.guardedLocalStorage(this.localStorageStateKey, String(this.elementWidth === 0)); } public get showNavigation():boolean { - return (this.elementWidth >= this.elementMinWidth); + return this.elementWidth >= this.elementMinWidth; } private snapBack():void { @@ -189,6 +202,7 @@ export class MainMenuToggleService { } private toggleClassHidden():void { - this.hideElements.toggleClass('hidden-navigation', !this.showNavigation); + const isHidden = this.elementWidth < this.elementMinWidth; + this.hideElements.toggleClass('hidden-navigation', isHidden); } } diff --git a/frontend/src/app/core/state/in-app-notifications/in-app-notification.model.ts b/frontend/src/app/core/state/in-app-notifications/in-app-notification.model.ts index eeae2b406f04..1a12217b389f 100644 --- a/frontend/src/app/core/state/in-app-notifications/in-app-notification.model.ts +++ b/frontend/src/app/core/state/in-app-notifications/in-app-notification.model.ts @@ -13,7 +13,7 @@ export interface IInAppNotificationHalResourceLinks extends IHalResourceLinks { activity:IHalResourceLink; } -export type IInAppNotificationDetailsAttribute = 'startDate'|'dueDate'|'date'; +export type IInAppNotificationDetailsAttribute = 'startDate'|'dueDate'|'date'|'note'; export interface IInAppNotificationDetailsResource { property:IInAppNotificationDetailsAttribute; diff --git a/frontend/src/app/features/in-app-notifications/center/state/ian-center.service.ts b/frontend/src/app/features/in-app-notifications/center/state/ian-center.service.ts index 0979826f6503..9c41f1a46587 100644 --- a/frontend/src/app/features/in-app-notifications/center/state/ian-center.service.ts +++ b/frontend/src/app/features/in-app-notifications/center/state/ian-center.service.ts @@ -111,7 +111,28 @@ export class IanCenterService extends UntilDestroyedMixin { notifications$ = this .aggregatedCenterNotifications$ .pipe( - map((items) => Object.values(items)), + map((items) => { + return Object.values(items).reduce((acc, workPackageNotificationGroup) => { + const { reminders, others } = workPackageNotificationGroup.reduce((result, notification) => { + if (notification.reason === 'reminder') { + result.reminders.push(notification); + } else { + result.others.push(notification); + } + return result; + }, { reminders: [] as INotification[], others: [] as INotification[] }); + + // Extract reminders into standalone groups so they can be displayed individually + if (reminders.length > 0) { + reminders.forEach((reminder) => acc.push([reminder])); + } + if (others.length > 0) { + acc.push(others); + } + + return acc; + }, [] as INotification[][]); + }), distinctUntilChanged(), ); diff --git a/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.html b/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.html index 16ebc61cac34..1d6adf2d0b30 100644 --- a/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.html +++ b/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.html @@ -1,8 +1,6 @@ -
+
diff --git a/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.sass b/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.sass index 92a4de952732..376f23ed350a 100644 --- a/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.sass +++ b/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.sass @@ -7,11 +7,6 @@ align-items: center color: var(--fgColor-muted) - &--date - @include text-shortener - max-width: 100% - line-height: 1rem - &--container @include text-shortener display: flex diff --git a/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.ts b/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.ts index e6bcd7b9f6d7..3f8c271ce907 100644 --- a/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.ts +++ b/frontend/src/app/features/in-app-notifications/entry/actors-line/in-app-notification-actors-line.component.ts @@ -1,11 +1,8 @@ import { ChangeDetectionStrategy, Component, HostBinding, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { DeviceService } from 'core-app/core/browser/device.service'; +import { I18nService } from 'core-app/core/i18n/i18n.service'; import { INotification } from 'core-app/core/state/in-app-notifications/in-app-notification.model'; import { PrincipalLike } from 'core-app/shared/components/principal/principal-types'; -import { Observable, timer } from 'rxjs'; -import { distinctUntilChanged, map } from 'rxjs/operators'; -import { I18nService } from 'core-app/core/i18n/i18n.service'; -import { TimezoneService } from 'core-app/core/datetime/timezone.service'; -import { DeviceService } from 'core-app/core/browser/device.service'; @Component({ selector: 'op-in-app-notification-actors-line', @@ -24,13 +21,6 @@ export class InAppNotificationActorsLineComponent implements OnInit { // The actor, if any actors:PrincipalLike[] = []; - // Fixed notification time - fixedTime:string; - - // Format relative elapsed time (n seconds/minutes/hours ago) - // at an interval for auto updating - relativeTime$:Observable; - text = { and: this.I18n.t('js.notifications.center.label_actor_and'), and_other_singular: this.I18n.t('js.notifications.center.and_more_users.one'), @@ -41,21 +31,14 @@ export class InAppNotificationActorsLineComponent implements OnInit { loading: this.I18n.t('js.ajax.loading'), placeholder: this.I18n.t('js.placeholders.default'), mark_as_read: this.I18n.t('js.notifications.center.mark_as_read'), - updated_by_at: (age:string):string => this.I18n.t( - 'js.notifications.center.text_update_date_by', - { date: age }, - ), }; constructor( readonly deviceService:DeviceService, private I18n:I18nService, - private timezoneService:TimezoneService, ) { } ngOnInit():void { - this.buildTime(); - // Don't show the actor if the first item is actor-less (date alert) if (this.notification._links.actor) { this.buildActors(); @@ -70,22 +53,6 @@ export class InAppNotificationActorsLineComponent implements OnInit { return this.text.and_other_plural(number); } - private buildTime() { - this.fixedTime = this.timezoneService.formattedDatetime(this.notification.createdAt); - this.relativeTime$ = timer(0, 10000) - .pipe( - map(() => { - const time = this.timezoneService.formattedRelativeDateTime(this.notification.createdAt); - if (this.notification._links.actor) { - return this.text.updated_by_at(time); - } - - return time; - }), - distinctUntilChanged(), - ); - } - private buildActors() { const actors = this .aggregatedNotifications diff --git a/frontend/src/app/features/in-app-notifications/entry/date-alert/in-app-notification-date-alert.component.ts b/frontend/src/app/features/in-app-notifications/entry/date-alert/in-app-notification-date-alert.component.ts index 877f2b592be6..fd4ddb132b61 100644 --- a/frontend/src/app/features/in-app-notifications/entry/date-alert/in-app-notification-date-alert.component.ts +++ b/frontend/src/app/features/in-app-notifications/entry/date-alert/in-app-notification-date-alert.component.ts @@ -6,9 +6,9 @@ import { OnInit, ViewEncapsulation, } from '@angular/core'; -import { INotification } from 'core-app/core/state/in-app-notifications/in-app-notification.model'; -import { I18nService } from 'core-app/core/i18n/i18n.service'; import { TimezoneService } from 'core-app/core/datetime/timezone.service'; +import { I18nService } from 'core-app/core/i18n/i18n.service'; +import { IInAppNotificationDetailsAttribute, INotification } from 'core-app/core/state/in-app-notifications/in-app-notification.model'; import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; import * as moment from 'moment'; import { Moment } from 'moment'; @@ -49,6 +49,7 @@ export class InAppNotificationDateAlertComponent implements OnInit { dueDate: this.I18n.t('js.work_packages.properties.dueDate'), date: this.I18n.t('js.notifications.date_alerts.milestone_date'), due_today: this.I18n.t('js.notifications.date_alerts.property_today'), + note: '', // date alerts do not have notes }; constructor( @@ -71,7 +72,7 @@ export class InAppNotificationDateAlertComponent implements OnInit { } } - private deriveDueDate(value:string, property:'startDate'|'dueDate'|'date') { + private deriveDueDate(value:string, property:IInAppNotificationDetailsAttribute) { const dateValue = this.timezoneService.parseISODate(value).startOf('day'); const today = moment(); this.dateIsPast = dateValue.isBefore(today, 'day'); diff --git a/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.html b/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.html index 14868f1cb424..e0443e0a7520 100644 --- a/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.html +++ b/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.html @@ -88,16 +88,22 @@
- - + /> + + + +
diff --git a/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.ts b/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.ts index 762fdc757304..c7725a20c706 100644 --- a/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.ts +++ b/frontend/src/app/features/in-app-notifications/entry/in-app-notification-entry.component.ts @@ -29,6 +29,7 @@ export class InAppNotificationEntryComponent implements OnInit { workPackage$:Observable|null = null; showDateAlert = false; + hasReminderAlert = false; loading$ = this.storeService.query.selectLoading(); @@ -62,6 +63,7 @@ export class InAppNotificationEntryComponent implements OnInit { const href = this.notification._links.resource?.href; this.workPackageId = href && HalResource.matchFromLink(href, 'work_packages'); + this.hasReminderAlert = this.aggregatedNotifications.some((notification) => notification.reason === 'reminder'); this.showDateAlert = this.hasActiveDateAlert(); this.buildTranslatedReason(); this.buildProject(); diff --git a/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.html b/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.html new file mode 100644 index 000000000000..982ee91f405a --- /dev/null +++ b/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.html @@ -0,0 +1,5 @@ +
+
diff --git a/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.sass b/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.sass new file mode 100644 index 000000000000..547e9c4b48d7 --- /dev/null +++ b/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.sass @@ -0,0 +1,6 @@ +@import "helpers" + +.op-ian-relative-time + @include text-shortener + max-width: 100% + line-height: 1rem diff --git a/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.ts b/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.ts new file mode 100644 index 000000000000..153e658175a7 --- /dev/null +++ b/frontend/src/app/features/in-app-notifications/entry/relative-time/in-app-notification-relative-time.component.ts @@ -0,0 +1,63 @@ +import { + ChangeDetectionStrategy, + Component, + Input, + OnInit, + ViewEncapsulation, +} from '@angular/core'; +import { TimezoneService } from 'core-app/core/datetime/timezone.service'; +import { I18nService } from 'core-app/core/i18n/i18n.service'; +import { INotification } from 'core-app/core/state/in-app-notifications/in-app-notification.model'; +import { Observable, timer } from 'rxjs'; +import { distinctUntilChanged, map } from 'rxjs/operators'; + +@Component({ + selector: 'op-in-app-notification-relative-time', + templateUrl: './in-app-notification-relative-time.component.html', + styleUrls: ['./in-app-notification-relative-time.component.sass'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None, +}) +export class InAppNotificationRelativeTimeComponent implements OnInit { + @Input() notification:INotification; + @Input() hasActorByLine:boolean = true; + + // Fixed notification time + fixedTime:string; + + // Format relative elapsed time (n seconds/minutes/hours ago) + // at an interval for auto updating + relativeTime$:Observable; + + text = { + updated_by_at: (age:string):string => this.I18n.t( + 'js.notifications.center.text_update_date_by', + { date: age }, + ), + }; + + constructor( + private I18n:I18nService, + private timezoneService:TimezoneService, + ) { } + + ngOnInit():void { + this.buildTime(); + } + + private buildTime() { + this.fixedTime = this.timezoneService.formattedDatetime(this.notification.createdAt); + this.relativeTime$ = timer(0, 10000) + .pipe( + map(() => { + const time = this.timezoneService.formattedRelativeDateTime(this.notification.createdAt); + if (this.hasActorByLine && this.notification._links.actor) { + return this.text.updated_by_at(time); + } + + return `${time}.`; + }), + distinctUntilChanged(), + ); + } +} diff --git a/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.html b/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.html new file mode 100644 index 000000000000..1956ae5dfa8f --- /dev/null +++ b/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.html @@ -0,0 +1,8 @@ + + diff --git a/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.sass b/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.sass new file mode 100644 index 000000000000..02f042d770c8 --- /dev/null +++ b/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.sass @@ -0,0 +1,16 @@ +@import "helpers" + +.op-ian-reminder-alert + display: grid + grid-template-columns: auto 1fr + grid-column-gap: $spot-spacing-0_25 + align-items: center + color: var(--fgColor-muted) + + &--note + @include text-shortener + line-height: 1rem + color: var(--fgColor-default) + + > * + flex-shrink: 0 diff --git a/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.ts b/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.ts new file mode 100644 index 000000000000..84392aeabde3 --- /dev/null +++ b/frontend/src/app/features/in-app-notifications/entry/reminder-alert/in-app-notification-reminder-alert.component.ts @@ -0,0 +1,59 @@ +import { + ChangeDetectionStrategy, + Component, + HostBinding, + Input, + OnInit, + ViewEncapsulation, +} from '@angular/core'; +import { I18nService } from 'core-app/core/i18n/i18n.service'; +import { IInAppNotificationDetailsResource, INotification } from 'core-app/core/state/in-app-notifications/in-app-notification.model'; + +@Component({ + selector: 'op-in-app-notification-reminder-alert', + templateUrl: './in-app-notification-reminder-alert.component.html', + styleUrls: ['./in-app-notification-reminder-alert.component.sass'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None, +}) +export class InAppNotificationReminderAlertComponent implements OnInit { + @Input() aggregatedNotifications:INotification[]; + + @HostBinding('class.op-ian-reminder-alert') className = true; + + reminderNote:string; + reminderAlert:INotification; + + constructor( + private I18n:I18nService, + ) { } + + ngOnInit():void { + this.reminderAlert = this.deriveMostRecentReminder(this.aggregatedNotifications); + this.reminderNote = this.extractReminderNoteValue(this.reminderAlert._embedded.details); + } + + private deriveMostRecentReminder(aggregatedNotifications:INotification[]):INotification { + const reminderAlerts = aggregatedNotifications.filter((notification:INotification) => notification.reason === 'reminder'); + + if (reminderAlerts.length > 1) { + const mostRecent = reminderAlerts.reduce((prev:INotification, current:INotification) => { + const prevDate = new Date(prev.createdAt); + const currentDate = new Date(current.createdAt); + return prevDate > currentDate ? prev : current; + }); + return mostRecent; + } + + return reminderAlerts[0]; + } + + private extractReminderNoteValue(details:IInAppNotificationDetailsResource[]):string { + const noteDetail = details.find((detail:IInAppNotificationDetailsResource) => detail.property === 'note'); + if (noteDetail?.value) { + return this.I18n.t('js.notifications.reminders.note', { note: (noteDetail?.value) }); + } + + return ''; + } +} diff --git a/frontend/src/app/features/in-app-notifications/in-app-notifications.module.ts b/frontend/src/app/features/in-app-notifications/in-app-notifications.module.ts index aade9f5cc27e..d921e8f48c78 100644 --- a/frontend/src/app/features/in-app-notifications/in-app-notifications.module.ts +++ b/frontend/src/app/features/in-app-notifications/in-app-notifications.module.ts @@ -1,31 +1,33 @@ -import { NgModule } from '@angular/core'; -import { OpSharedModule } from 'core-app/shared/shared.module'; +import { ScrollingModule } from '@angular/cdk/scrolling'; import { CommonModule } from '@angular/common'; -import { IconModule } from 'core-app/shared/components/icon/icon.module'; +import { NgModule } from '@angular/core'; import { InAppNotificationBellComponent, } from 'core-app/features/in-app-notifications/bell/in-app-notification-bell.component'; -import { - InAppNotificationEntryComponent, -} from 'core-app/features/in-app-notifications/entry/in-app-notification-entry.component'; -import { OpenprojectPrincipalRenderingModule } from 'core-app/shared/components/principal/principal-rendering.module'; -import { ScrollingModule } from '@angular/cdk/scrolling'; +import { IanBellService } from 'core-app/features/in-app-notifications/bell/state/ian-bell.service'; import { InAppNotificationCenterComponent, } from 'core-app/features/in-app-notifications/center/in-app-notification-center.component'; +import { IanCenterService } from 'core-app/features/in-app-notifications/center/state/ian-center.service'; +import { + InAppNotificationsDateAlertsUpsaleComponent, +} from 'core-app/features/in-app-notifications/date-alerts-upsale/ian-date-alerts-upsale.component'; +import { + InAppNotificationEntryComponent, +} from 'core-app/features/in-app-notifications/entry/in-app-notification-entry.component'; import { OpenprojectWorkPackagesModule } from 'core-app/features/work-packages/openproject-work-packages.module'; -import { DynamicModule } from 'ng-dynamic-component'; -import { InAppNotificationStatusComponent } from './entry/status/in-app-notification-status.component'; +import { IconModule } from 'core-app/shared/components/icon/icon.module'; import { OpenprojectContentLoaderModule, } from 'core-app/shared/components/op-content-loader/openproject-content-loader.module'; -import { IanBellService } from 'core-app/features/in-app-notifications/bell/state/ian-bell.service'; +import { OpenprojectPrincipalRenderingModule } from 'core-app/shared/components/principal/principal-rendering.module'; +import { OpSharedModule } from 'core-app/shared/shared.module'; +import { DynamicModule } from 'ng-dynamic-component'; import { InAppNotificationActorsLineComponent } from './entry/actors-line/in-app-notification-actors-line.component'; import { InAppNotificationDateAlertComponent } from './entry/date-alert/in-app-notification-date-alert.component'; -import { - InAppNotificationsDateAlertsUpsaleComponent, -} from 'core-app/features/in-app-notifications/date-alerts-upsale/ian-date-alerts-upsale.component'; -import { IanCenterService } from 'core-app/features/in-app-notifications/center/state/ian-center.service'; +import { InAppNotificationRelativeTimeComponent } from './entry/relative-time/in-app-notification-relative-time.component'; +import { InAppNotificationReminderAlertComponent } from './entry/reminder-alert/in-app-notification-reminder-alert.component'; +import { InAppNotificationStatusComponent } from './entry/status/in-app-notification-status.component'; @NgModule({ declarations: [ @@ -36,6 +38,8 @@ import { IanCenterService } from 'core-app/features/in-app-notifications/center/ InAppNotificationActorsLineComponent, InAppNotificationDateAlertComponent, InAppNotificationsDateAlertsUpsaleComponent, + InAppNotificationRelativeTimeComponent, + InAppNotificationReminderAlertComponent, ], imports: [ OpSharedModule, diff --git a/frontend/src/global_styles/content/_enterprise.sass b/frontend/src/global_styles/content/_enterprise.sass index b1f6e45fcb57..04e10759e463 100644 --- a/frontend/src/global_styles/content/_enterprise.sass +++ b/frontend/src/global_styles/content/_enterprise.sass @@ -55,6 +55,9 @@ .upsale-colored color: $spot-color-feedback-warning-dark +.upsale-border-colored + border-color: $spot-color-feedback-warning-dark + .widget-box--blocks--upsale-title font-weight: 400 font-size: 20px diff --git a/frontend/src/stimulus/controllers/dynamic/chronic-duration.controller.ts b/frontend/src/stimulus/controllers/dynamic/chronic-duration.controller.ts new file mode 100644 index 000000000000..fc0d69c0429a --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/chronic-duration.controller.ts @@ -0,0 +1,68 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + * + */ + +import { Controller } from '@hotwired/stimulus'; +import { outputChronicDuration, parseChronicDuration } from 'core-app/shared/helpers/chronic_duration'; + +export default class ChronicDurationController extends Controller { + private processChangeFn = () => this.onBlur(); + private keyPressedFn = (evt:KeyboardEvent) => this.onKeyPress(evt); + + connect() { + this.element.addEventListener('blur', this.processChangeFn); + this.element.addEventListener('keypress', this.keyPressedFn); + } + + disconnect() { + super.disconnect(); + + this.element.removeEventListener('blur', this.processChangeFn); + this.element.removeEventListener('keypress', this.keyPressedFn); + } + + private onBlur() { + const value = this.element.value; + const hours = parseChronicDuration( + value, + { + defaultUnit: 'hours', ignoreSecondsWhenColonSeperated: true, + }, + ); + + this.element.value = outputChronicDuration(hours, { format: 'hours_only' }) || ''; + } + + private onKeyPress(evt:KeyboardEvent) { + if (evt.key === 'Enter' && evt.currentTarget === this.element) { + this.element.blur(); + } + } +} diff --git a/frontend/src/stimulus/controllers/dynamic/costs/export.controller.ts b/frontend/src/stimulus/controllers/dynamic/costs/export.controller.ts new file mode 100644 index 000000000000..aa744db75469 --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/costs/export.controller.ts @@ -0,0 +1,90 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; +import * as Turbo from '@hotwired/turbo'; +import { HttpErrorResponse } from '@angular/common/http'; + +export default class ExportController extends Controller { + static values = { + jobStatusDialogUrl: String, + }; + + declare jobStatusDialogUrlValue:string; + + jobModalUrl(job_id:string):string { + return this.jobStatusDialogUrlValue.replace('_job_uuid_', job_id); + } + + async showJobModal(job_id:string) { + const response = await fetch(this.jobModalUrl(job_id), { + method: 'GET', + headers: { Accept: 'text/vnd.turbo-stream.html' }, + }); + if (response.ok) { + Turbo.renderStreamMessage(await response.text()); + } else { + throw new Error(response.statusText || 'Invalid response from server'); + } + } + + async requestExport(exportURL:string):Promise { + const response = await fetch(exportURL, { + method: 'GET', + headers: { Accept: 'application/json' }, + credentials: 'same-origin', + }); + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + const result = await response.json() as { job_id:string }; + if (!result.job_id) { + throw new Error('Invalid response from server'); + } + return result.job_id; + } + + get href() { + return this.element.href; + } + + download(evt:CustomEvent) { + evt.preventDefault(); // Don't follow the href + this.requestExport(this.href) + .then((job_id) => this.showJobModal(job_id)) + .catch((error:HttpErrorResponse) => this.handleError(error)); + } + + private handleError(error:HttpErrorResponse) { + void window.OpenProject.getPluginContext().then((pluginContext) => { + pluginContext.services.notifications.addError(error); + }); + } +} diff --git a/frontend/src/stimulus/controllers/dynamic/recurring-meetings/form.controller.ts b/frontend/src/stimulus/controllers/dynamic/recurring-meetings/form.controller.ts new file mode 100644 index 000000000000..64c6e0044bf8 --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/recurring-meetings/form.controller.ts @@ -0,0 +1,32 @@ +import { ApplicationController } from 'stimulus-use'; +import { TurboRequestsService } from 'core-app/core/turbo/turbo-requests.service'; +import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; + +export default class OpRecurringMeetingsFormController extends ApplicationController { + private turboRequests:TurboRequestsService; + private pathHelper:PathHelperService; + + async connect() { + const context = await window.OpenProject.getPluginContext(); + this.turboRequests = context.services.turboRequests; + this.pathHelper = context.services.pathHelperService; + } + + updateFrequencyText():void { + const data = new FormData(this.element as HTMLFormElement); + const urlSearchParams = new URLSearchParams(); + ['start_date', 'start_time_hour', 'frequency', 'interval'].forEach((name) => { + const key = `meeting[${name}]`; + urlSearchParams.append(key, data.get(key) as string); + }); + + void this + .turboRequests + .request( + `${this.pathHelper.staticBase}/recurring_meetings/humanize_schedule?${urlSearchParams.toString()}`, + { + headers: { Accept: 'text/vnd.turbo-stream.html' }, + }, + ); + } +} diff --git a/frontend/src/stimulus/controllers/op-application.controller.ts b/frontend/src/stimulus/controllers/op-application.controller.ts index e1234cc820e9..fa3bb750ff96 100644 --- a/frontend/src/stimulus/controllers/op-application.controller.ts +++ b/frontend/src/stimulus/controllers/op-application.controller.ts @@ -8,11 +8,11 @@ export class OpApplicationController extends ApplicationController { dynamicTargetConnected(target:HTMLElement) { const controllers = (target.dataset.controller as string).split(' '); + const registered = this.application.controllers.map((controller) => controller.identifier); controllers.forEach((controller) => { const path = this.derivePath(controller); - - if (!this.loaded.has(controller)) { + if (!registered.includes(controller) && !this.loaded.has(controller)) { this.loaded.add(controller); void import(/* webpackChunkName: "[request]" */`./dynamic/${path}.controller`) .then((imported:{ default:ControllerConstructor }) => this.application.register(controller, imported.default)) diff --git a/frontend/src/turbo/input-caption-stream-action.ts b/frontend/src/turbo/input-caption-stream-action.ts new file mode 100644 index 000000000000..1746be1b006b --- /dev/null +++ b/frontend/src/turbo/input-caption-stream-action.ts @@ -0,0 +1,24 @@ +import { StreamActions, StreamElement } from '@hotwired/turbo'; + +export function registerInputCaptionStreamAction() { + StreamActions.addInputCaption = function addInputCaptionAction(this:StreamElement) { + const target = document.querySelector(this.target); + if (target) { + const formControl = (target as HTMLElement).closest('.FormControl') as HTMLElement; + + if (this.getAttribute('clean_other_captions') === 'true') { + formControl + .querySelectorAll('.FormControl-caption') + .forEach((caption) => caption.remove()); + } + + const caption = this.getAttribute('caption'); + if (caption && caption !== '') { + const span = document.createElement('span'); + span.className = 'FormControl-caption'; + span.innerText = caption; + formControl.append(span); + } + } + }; +} diff --git a/frontend/src/turbo/setup.ts b/frontend/src/turbo/setup.ts index 0a32ec07b8a0..bec41611609b 100644 --- a/frontend/src/turbo/setup.ts +++ b/frontend/src/turbo/setup.ts @@ -4,6 +4,7 @@ import TurboPower from 'turbo_power'; import { registerDialogStreamAction } from './dialog-stream-action'; import { addTurboEventListeners } from './turbo-event-listeners'; import { registerFlashStreamAction } from './flash-stream-action'; +import { registerInputCaptionStreamAction } from './input-caption-stream-action'; import { addTurboGlobalListeners } from './turbo-global-listeners'; import { applyTurboNavigationPatch } from './turbo-navigation-patch'; import { debugLog, whenDebugging } from 'core-app/shared/helpers/debug_output'; @@ -29,6 +30,7 @@ addTurboEventListeners(); addTurboGlobalListeners(); registerDialogStreamAction(); registerFlashStreamAction(); +registerInputCaptionStreamAction(); // Apply navigational patch // https://github.com/hotwired/turbo/issues/1300 @@ -39,7 +41,9 @@ TurboPower.initialize(Turbo.StreamActions); // Error handling when "Content missing" returned document.addEventListener('turbo:frame-missing', (event:CustomEvent) => { - const { detail: { response, visit } } = event as { detail:{ response:Response, visit:(url:string) => void } }; + const { + detail: { response, visit }, + } = event as { detail:{ response:Response; visit:(url:string) => void } }; event.preventDefault(); visit(response.url); }); diff --git a/lib/api/v3/notifications/notification_representer.rb b/lib/api/v3/notifications/notification_representer.rb index 5b67c4dd9a3d..6984fe235187 100644 --- a/lib/api/v3/notifications/notification_representer.rb +++ b/lib/api/v3/notifications/notification_representer.rb @@ -104,7 +104,7 @@ def _type "Notification" end - self.to_eager_load = %i[actor journal] + self.to_eager_load = %i[actor journal reminder] end end end diff --git a/lib/api/v3/notifications/property_factory/reminder.rb b/lib/api/v3/notifications/property_factory/reminder.rb new file mode 100644 index 000000000000..e8bd4e210c2f --- /dev/null +++ b/lib/api/v3/notifications/property_factory/reminder.rb @@ -0,0 +1,45 @@ +# --copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module API::V3::Notifications::PropertyFactory + module Reminder + extend ::API::V3::Utilities::PathHelper + + module_function + + def for(notification) + return [] unless notification.reminder + + [ + ::API::V3::Values::PropertyGenericRepresenter + .new(::API::V3::Values::PropertyModel.new(:note, notification.reminder.note), + self_link: api_v3_paths.notification_detail(notification.id, 0)) + ] + end + end +end diff --git a/lib/api/v3/values/property_generic_representer.rb b/lib/api/v3/values/property_generic_representer.rb new file mode 100644 index 000000000000..ed814ef2fa38 --- /dev/null +++ b/lib/api/v3/values/property_generic_representer.rb @@ -0,0 +1,33 @@ +# --copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module API::V3::Values + class PropertyGenericRepresenter < PropertyRepresenter + property :value + end +end diff --git a/lib/api/v3/values/schemas/value_schema_factory.rb b/lib/api/v3/values/schemas/value_schema_factory.rb index de98a68e279e..441bb6734729 100644 --- a/lib/api/v3/values/schemas/value_schema_factory.rb +++ b/lib/api/v3/values/schemas/value_schema_factory.rb @@ -29,7 +29,7 @@ module API::V3::Values::Schemas module ValueSchemaFactory extend ::API::V3::Utilities::PathHelper - SUPPORTED = %w(start_date due_date date).freeze + SUPPORTED = %w(start_date due_date date note).freeze module_function @@ -64,10 +64,13 @@ def i18n_for(property) I18n.t("attributes.#{property}") end - def type_for(_property) - # This is but a stub. Currently, only 'start_date' and 'due_date' - # need to be supported so this simple approach works. - "Date" + def type_for(property) + case property + when "start_date", "due_date", "date" + "Date" + when "note" + "String" + end end end end diff --git a/lib/open_project/journal_formatter/custom_field/plain.rb b/lib/open_project/journal_formatter/custom_field/plain.rb index a0ed17f05b27..a7a94fd3dbb9 100644 --- a/lib/open_project/journal_formatter/custom_field/plain.rb +++ b/lib/open_project/journal_formatter/custom_field/plain.rb @@ -93,10 +93,12 @@ def find_user_value(value, _custom_field) def find_item_value(value, _custom_field) ids = value.split(",").map(&:to_i) - CustomField::Hierarchy::Item.where(id: ids).map do |item| - next I18n.t(:label_deleted_custom_option) unless ids.include?(item.id) + items = CustomField::Hierarchy::Item.where(id: ids).index_by(&:id) - item.ancestry_path + ids.map do |id| + next I18n.t(:label_deleted_custom_item) unless items[id] + + items[id].ancestry_path end.join(", ") end diff --git a/lib/open_project/patches/mailer_controller_preview.rb b/lib/open_project/patches/mailer_controller_preview.rb index 04090d2d853f..52fcc99e442f 100644 --- a/lib/open_project/patches/mailer_controller_preview.rb +++ b/lib/open_project/patches/mailer_controller_preview.rb @@ -41,6 +41,6 @@ def extend_content_security_policy end end -OpenProject::Patches.patch_gem_version "rails", "7.1.5" do +OpenProject::Patches.patch_gem_version "rails", "7.1.5.1" do Rails::MailersController.include OpenProject::Patches::MailerControllerCsp end diff --git a/lookbook/previews/open_project/enterprise_edition/banner_component_preview.rb b/lookbook/previews/open_project/enterprise_edition/banner_component_preview.rb new file mode 100644 index 000000000000..a6ce8c932c6d --- /dev/null +++ b/lookbook/previews/open_project/enterprise_edition/banner_component_preview.rb @@ -0,0 +1,79 @@ +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +module OpenProject + module EnterpriseEdition + # @logical_path OpenProject/EnterpriseEdition + class BannerComponentPreview < Lookbook::Preview + # The easiest way to render the banner component is to provide a feature key and + # have the assorted data structures match the expectations. + # The text will be fetched from the i18n files: + # ``` + # en: + # ee: + # # Title used unless it is overwritten for the specific feature + # title: "Enterprise add-on" + # # Title of the link used unless it is overwritten for the specific feature + # link_title: "More information" + # upsale: + # [feature_key]: + # # Title used for this feature only. If this is missing, the default title is used. + # title: "A splendid feature" + # # Could also be description_html if necessary + # description: "This is a splendid feature that you should use. It just might transform your life." + # # Title of the link used for this feature only. If this is missing, the default link title is used. + # title_link: "Even more information" + # ``` + # + # The href is inferred from `OpenProject::Static::Links.enterprise_docs[feature_key][:href]`. + # + # The value of `EnterpriseToken.show_banners?` is used to determine whether the banner should be shown. For this + # example, that value is overwritten as the banner might otherwise not show up in the preview. + def default + render( + ::EnterpriseEdition::BannerComponent + .new(:form_configuration, + skip_render: false) + ) + end + + # The defaults can be completely overwritten. This should be used sparingly. + def manual_overwrite + render( + ::EnterpriseEdition::BannerComponent + .new(nil, + title: "A splendid feature", + description: "This is a splendid feature that you should use. It just might transform your life.", + href: "https://www.openproject.org", + link_title: "Get more information", + skip_render: false) + ) + end + end + end +end diff --git a/modules/auth_saml/config/locales/crowdin/ms.yml b/modules/auth_saml/config/locales/crowdin/ms.yml index 52114feed568..9ea882adba52 100644 --- a/modules/auth_saml/config/locales/crowdin/ms.yml +++ b/modules/auth_saml/config/locales/crowdin/ms.yml @@ -2,10 +2,10 @@ ms: activemodel: attributes: saml/provider: - display_name: Name - identifier: Identifier - secret: Secret - scope: Scope + display_name: Nama + identifier: Pengenalan + secret: Sulit + scope: Skop assertion_consumer_service_url: ACS (Assertion consumer service) URL limit_self_registration: Limit self registration sp_entity_id: Service entity ID diff --git a/modules/avatars/config/locales/crowdin/mn.yml b/modules/avatars/config/locales/crowdin/mn.yml index 5fb37d6d90e8..2308c5bfeaa8 100644 --- a/modules/avatars/config/locales/crowdin/mn.yml +++ b/modules/avatars/config/locales/crowdin/mn.yml @@ -4,23 +4,23 @@ mn: name: "Avatars" description: >- This plugin allows OpenProject users to upload a picture to be used as an avatar or use registered images from Gravatar. - label_avatar: "Avatar" - label_avatar_plural: "Avatars" - label_current_avatar: "Current Avatar" - label_choose_avatar: "Choose Avatar from file" - message_avatar_uploaded: "Avatar changed successfully." - error_image_upload: "Error saving the image." - error_image_size: "The image is too large." + label_avatar: "Аватар" + label_avatar_plural: "Аватар" + label_current_avatar: "Одоогийн Аватар" + label_choose_avatar: "Аватарыг файлаас сонгох" + message_avatar_uploaded: "Аватар амжилттай өөрчлөгдлөө." + error_image_upload: "Зураг хадгалахад алдаа гарлаа." + error_image_size: "Зураг хэтэрхий том байна." are_you_sure_delete_avatar: "Are you sure you want to delete your avatar?" - avatar_deleted: "Avatar deleted successfully." + avatar_deleted: "Аватар амжилттай устгалаа." unable_to_delete_avatar: "Avatar could not be deleted." wrong_file_format: "Allowed formats are jpg, png, gif" empty_file_error: "Please upload a valid image (jpg, png, gif)" avatars: - label_avatar: "Avatar" + label_avatar: "Аватар" label_gravatar: 'Gravatar' - label_current_avatar: 'Current avatar' - label_local_avatar: 'Custom avatar' + label_current_avatar: 'Одоогийн Аватар' + label_local_avatar: 'Дурын аватар' text_current_avatar: | The following image shows the current avatar. text_upload_instructions: | diff --git a/modules/backlogs/config/locales/crowdin/mn.yml b/modules/backlogs/config/locales/crowdin/mn.yml index 2ac1af81dda1..1f81853379ff 100644 --- a/modules/backlogs/config/locales/crowdin/mn.yml +++ b/modules/backlogs/config/locales/crowdin/mn.yml @@ -26,7 +26,7 @@ mn: activerecord: attributes: work_package: - position: "албан тушаал" + position: "Албан тушаал" story_points: "Гүйцэтгэлийн оноо" backlogs_work_package_type: "Backlog type" errors: @@ -47,16 +47,16 @@ mn: burndown_graph: "Burndown Graph" card_paper_size: "Paper size for card printing" chart_options: "Chart options" - close: "Close" + close: "Хаах" column_width: "Column width:" - date: "Day" + date: "Өдөр" definition_of_done: "Definition of Done" generating_chart: "Generating Graph..." - hours: "Hours" + hours: "Цаг" impediment: "Impediment" label_versions_default_fold_state: "Show versions folded" work_package_is_closed: "Work package is done, when" - label_is_done_status: "Status %{status_name} means done" + label_is_done_status: "Төлөв %{status_name} дууссан гэсэн үг" no_burndown_data: "No burndown data available. It is necessary to have the sprint start- and end dates set." points: "Оноо" positions_could_not_be_rebuilt: "Positions could not be rebuilt." @@ -70,11 +70,11 @@ mn: story: "Story" story_points: "Гүйцэтгэлийн оноо" story_points_ideal: "Story Points (ideal)" - task: "Task" - task_color: "Task color" + task: "Даалгавар" + task_color: "Даалгаврын өнгө" unassigned: "Unassigned" x_more: "%{count} more..." - backlogs_active: "active" + backlogs_active: "идэвхтэй" backlogs_any: "any" backlogs_inactive: "Project shows no activity" backlogs_points_burn_direction: "Points burn up/down" @@ -102,7 +102,7 @@ mn: error_outro: "Please correct the above errors before submitting again." event_sprint_description: "%{summary}: %{url}\n%{description}" event_sprint_summary: "%{project}: %{summary}" - ideal: "ideal" + ideal: "хамгийн тохиромжтой" inclusion: "is not included in the list" label_back_to_project: "Back to project page" label_backlog: "Backlog" diff --git a/modules/bim/app/models/bim/queries/work_packages/filter/bcf_issue_associated_filter.rb b/modules/bim/app/models/bim/queries/work_packages/filter/bcf_issue_associated_filter.rb index a92b82e8ef2b..1ce6ffce8a2f 100644 --- a/modules/bim/app/models/bim/queries/work_packages/filter/bcf_issue_associated_filter.rb +++ b/modules/bim/app/models/bim/queries/work_packages/filter/bcf_issue_associated_filter.rb @@ -41,6 +41,10 @@ def allowed_values ] end + def human_name + I18n.t("bcf.label_bcf_issue_associated") + end + def where if associated? ::Queries::Operators::All.sql_for_field(values, ::Bim::Bcf::Issue.table_name, "id") diff --git a/modules/bim/config/locales/crowdin/af.yml b/modules/bim/config/locales/crowdin/af.yml index 00e78e306103..aeff38e4ab86 100644 --- a/modules/bim/config/locales/crowdin/af.yml +++ b/modules/bim/config/locales/crowdin/af.yml @@ -9,6 +9,7 @@ af: label_bcf: 'BSF' label_imported_failed: 'Mislukte invoer van BSF-onderwerpe' label_imported_successfully: 'BSF-onderwerpe is suksesvol ingevoer' + label_bcf_issue_associated: "BCF issue associated" issues: "Kwessies" recommended: 'aanbeveelde' not_recommended: 'nie aanbeveel nie' diff --git a/modules/bim/config/locales/crowdin/ar.yml b/modules/bim/config/locales/crowdin/ar.yml index 11ca419ea133..7ebcd439c854 100644 --- a/modules/bim/config/locales/crowdin/ar.yml +++ b/modules/bim/config/locales/crowdin/ar.yml @@ -9,6 +9,7 @@ ar: label_bcf: 'BCF' label_imported_failed: 'فشل استيراد مواضيع BCF' label_imported_successfully: 'تم استيراد موضوعات BCF بنجاح' + label_bcf_issue_associated: "BCF issue associated" issues: "مشاكل" recommended: 'موصى بها' not_recommended: 'غير موصى بها' diff --git a/modules/bim/config/locales/crowdin/az.yml b/modules/bim/config/locales/crowdin/az.yml index 7d8823bf14be..65591209d6b0 100644 --- a/modules/bim/config/locales/crowdin/az.yml +++ b/modules/bim/config/locales/crowdin/az.yml @@ -9,6 +9,7 @@ az: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/be.yml b/modules/bim/config/locales/crowdin/be.yml index ba9dc4cde091..1269b044823c 100644 --- a/modules/bim/config/locales/crowdin/be.yml +++ b/modules/bim/config/locales/crowdin/be.yml @@ -9,6 +9,7 @@ be: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/bg.yml b/modules/bim/config/locales/crowdin/bg.yml index a78afaf5c3b1..8e8f97b9f6ac 100644 --- a/modules/bim/config/locales/crowdin/bg.yml +++ b/modules/bim/config/locales/crowdin/bg.yml @@ -9,6 +9,7 @@ bg: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/ca.yml b/modules/bim/config/locales/crowdin/ca.yml index 155aaf7d266d..af2ea128aa7e 100644 --- a/modules/bim/config/locales/crowdin/ca.yml +++ b/modules/bim/config/locales/crowdin/ca.yml @@ -9,6 +9,7 @@ ca: label_bcf: 'BCF' label_imported_failed: 'Importació de temes BCF no reeixida' label_imported_successfully: 'S''ha importat els temes BCF correctament.' + label_bcf_issue_associated: "BCF issue associated" issues: "Problemes" recommended: 'recomanat' not_recommended: 'no recomanat' diff --git a/modules/bim/config/locales/crowdin/ckb-IR.yml b/modules/bim/config/locales/crowdin/ckb-IR.yml index 63c610ae7f6f..d149aea8e9fa 100644 --- a/modules/bim/config/locales/crowdin/ckb-IR.yml +++ b/modules/bim/config/locales/crowdin/ckb-IR.yml @@ -9,6 +9,7 @@ ckb-IR: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/cs.yml b/modules/bim/config/locales/crowdin/cs.yml index 14cb64db1b34..e0abce3e1827 100644 --- a/modules/bim/config/locales/crowdin/cs.yml +++ b/modules/bim/config/locales/crowdin/cs.yml @@ -9,6 +9,7 @@ cs: label_bcf: 'BCF' label_imported_failed: 'Selhalo importování témat BCF' label_imported_successfully: 'Importovaná témata BCF úspěšně' + label_bcf_issue_associated: "BCF issue associated" issues: "Problémy" recommended: 'doporučeno' not_recommended: 'nedoporučeno' diff --git a/modules/bim/config/locales/crowdin/da.yml b/modules/bim/config/locales/crowdin/da.yml index 484e0b0cdc2c..a07856feffa0 100644 --- a/modules/bim/config/locales/crowdin/da.yml +++ b/modules/bim/config/locales/crowdin/da.yml @@ -9,6 +9,7 @@ da: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/de.yml b/modules/bim/config/locales/crowdin/de.yml index 88b080092141..0ce37edd4756 100644 --- a/modules/bim/config/locales/crowdin/de.yml +++ b/modules/bim/config/locales/crowdin/de.yml @@ -9,6 +9,7 @@ de: label_bcf: 'BCF' label_imported_failed: 'Fehler beim Import von BCF-Themen' label_imported_successfully: 'Erfolgreich importierte Einträge' + label_bcf_issue_associated: "BCF issue associated" issues: "Probleme" recommended: 'empfohlen' not_recommended: 'nicht empfohlen' diff --git a/modules/bim/config/locales/crowdin/el.yml b/modules/bim/config/locales/crowdin/el.yml index 5a8acb456cd1..abd8826b8637 100644 --- a/modules/bim/config/locales/crowdin/el.yml +++ b/modules/bim/config/locales/crowdin/el.yml @@ -9,6 +9,7 @@ el: label_bcf: 'BCF' label_imported_failed: 'Αποτυχημένες εισαγωγές των θεμάτων BCF' label_imported_successfully: 'Επιτυχής εισαγωγή θέματων BCF' + label_bcf_issue_associated: "BCF issue associated" issues: "Ζητήματα" recommended: 'προτεινόμενο' not_recommended: 'δεν συνιστάται' diff --git a/modules/bim/config/locales/crowdin/eo.yml b/modules/bim/config/locales/crowdin/eo.yml index 38181d844d4e..6a32b767e8c1 100644 --- a/modules/bim/config/locales/crowdin/eo.yml +++ b/modules/bim/config/locales/crowdin/eo.yml @@ -9,6 +9,7 @@ eo: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/es.yml b/modules/bim/config/locales/crowdin/es.yml index a10876169bee..699f6721a61f 100644 --- a/modules/bim/config/locales/crowdin/es.yml +++ b/modules/bim/config/locales/crowdin/es.yml @@ -9,6 +9,7 @@ es: label_bcf: 'BCF' label_imported_failed: 'No se pudieron importar los temas de BCF' label_imported_successfully: 'Los temas de BCF se importaron correctamente' + label_bcf_issue_associated: "BCF issue associated" issues: "Incidencias" recommended: 'recomendado' not_recommended: 'no recomendado' diff --git a/modules/bim/config/locales/crowdin/et.yml b/modules/bim/config/locales/crowdin/et.yml index d52d1ab243b1..c715b81577a8 100644 --- a/modules/bim/config/locales/crowdin/et.yml +++ b/modules/bim/config/locales/crowdin/et.yml @@ -9,6 +9,7 @@ et: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/eu.yml b/modules/bim/config/locales/crowdin/eu.yml index c122c85cb45e..80e1a788ff51 100644 --- a/modules/bim/config/locales/crowdin/eu.yml +++ b/modules/bim/config/locales/crowdin/eu.yml @@ -9,6 +9,7 @@ eu: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/fa.yml b/modules/bim/config/locales/crowdin/fa.yml index cd6bec3ebd3d..7acc2eab619d 100644 --- a/modules/bim/config/locales/crowdin/fa.yml +++ b/modules/bim/config/locales/crowdin/fa.yml @@ -9,6 +9,7 @@ fa: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'موضوعات BCF با موفقیت درون‌ریزی شد' + label_bcf_issue_associated: "BCF issue associated" issues: "مشکلات" recommended: 'پیشنهادی' not_recommended: 'پیشنهاد نشده' diff --git a/modules/bim/config/locales/crowdin/fi.yml b/modules/bim/config/locales/crowdin/fi.yml index af8f559a5478..b1ccee6c520d 100644 --- a/modules/bim/config/locales/crowdin/fi.yml +++ b/modules/bim/config/locales/crowdin/fi.yml @@ -9,6 +9,7 @@ fi: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'suositellut' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/fil.yml b/modules/bim/config/locales/crowdin/fil.yml index 7fcffceffb30..81ff5c18889d 100644 --- a/modules/bim/config/locales/crowdin/fil.yml +++ b/modules/bim/config/locales/crowdin/fil.yml @@ -9,6 +9,7 @@ fil: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/fr.yml b/modules/bim/config/locales/crowdin/fr.yml index 1be78163d4bc..1bcc6d0df30b 100644 --- a/modules/bim/config/locales/crowdin/fr.yml +++ b/modules/bim/config/locales/crowdin/fr.yml @@ -9,6 +9,7 @@ fr: label_bcf: 'BCF' label_imported_failed: 'Impossible d''importer les sujets BCF' label_imported_successfully: 'Sujets BCF importés avec succès' + label_bcf_issue_associated: "BCF issue associated" issues: "Problèmes" recommended: 'recommandé' not_recommended: 'déconseillé' diff --git a/modules/bim/config/locales/crowdin/he.yml b/modules/bim/config/locales/crowdin/he.yml index a1eda3ce2252..50d6bdd12b1f 100644 --- a/modules/bim/config/locales/crowdin/he.yml +++ b/modules/bim/config/locales/crowdin/he.yml @@ -9,6 +9,7 @@ he: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/hi.yml b/modules/bim/config/locales/crowdin/hi.yml index b443b6c6159c..c6b599d9e651 100644 --- a/modules/bim/config/locales/crowdin/hi.yml +++ b/modules/bim/config/locales/crowdin/hi.yml @@ -9,6 +9,7 @@ hi: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/hr.yml b/modules/bim/config/locales/crowdin/hr.yml index 3bb911736ff0..0b91a958972a 100644 --- a/modules/bim/config/locales/crowdin/hr.yml +++ b/modules/bim/config/locales/crowdin/hr.yml @@ -9,6 +9,7 @@ hr: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/hu.yml b/modules/bim/config/locales/crowdin/hu.yml index 2bbd50f01874..31dc9b7661d2 100644 --- a/modules/bim/config/locales/crowdin/hu.yml +++ b/modules/bim/config/locales/crowdin/hu.yml @@ -9,6 +9,7 @@ hu: label_bcf: 'BCF' label_imported_failed: 'Hiba a BCF topocs importálásakor' label_imported_successfully: 'Sikeres BCF import' + label_bcf_issue_associated: "BCF issue associated" issues: "Feladat" recommended: 'Ajánlott' not_recommended: 'nem ajánlott' diff --git a/modules/bim/config/locales/crowdin/id.yml b/modules/bim/config/locales/crowdin/id.yml index 77bc93dfeabe..62a96cb4f14c 100644 --- a/modules/bim/config/locales/crowdin/id.yml +++ b/modules/bim/config/locales/crowdin/id.yml @@ -9,6 +9,7 @@ id: label_bcf: 'BCF' label_imported_failed: 'Gagal mengimport topik BCF' label_imported_successfully: 'Berhasil mengimport topik BCF' + label_bcf_issue_associated: "BCF issue associated" issues: "Masalah" recommended: 'Disarankan' not_recommended: 'Tidak disarankan' diff --git a/modules/bim/config/locales/crowdin/it.yml b/modules/bim/config/locales/crowdin/it.yml index 1e227d617269..699fd5a652d3 100644 --- a/modules/bim/config/locales/crowdin/it.yml +++ b/modules/bim/config/locales/crowdin/it.yml @@ -9,6 +9,7 @@ it: label_bcf: 'BCF' label_imported_failed: 'Importazione di argomenti BCF non riuscita' label_imported_successfully: 'Argomenti BCF importati con successo' + label_bcf_issue_associated: "BCF issue associated" issues: "Problemi" recommended: 'consigliato' not_recommended: 'non consigliato' diff --git a/modules/bim/config/locales/crowdin/ja.yml b/modules/bim/config/locales/crowdin/ja.yml index 0ea3c866dfb7..9f900f84fa1d 100644 --- a/modules/bim/config/locales/crowdin/ja.yml +++ b/modules/bim/config/locales/crowdin/ja.yml @@ -9,6 +9,7 @@ ja: label_bcf: 'BCF' label_imported_failed: 'BCFトピックのインポートに失敗しました' label_imported_successfully: 'BCFトピックを正常にインポートしました' + label_bcf_issue_associated: "BCF issue associated" issues: "チケット" recommended: '推奨' not_recommended: '非推奨' diff --git a/modules/bim/config/locales/crowdin/ka.yml b/modules/bim/config/locales/crowdin/ka.yml index bdc43b04e070..70fca6f04f69 100644 --- a/modules/bim/config/locales/crowdin/ka.yml +++ b/modules/bim/config/locales/crowdin/ka.yml @@ -9,6 +9,7 @@ ka: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "შენიშვნები" recommended: 'რეკომენდებულია' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/kk.yml b/modules/bim/config/locales/crowdin/kk.yml index 8d7d35ffd47a..ae4970022096 100644 --- a/modules/bim/config/locales/crowdin/kk.yml +++ b/modules/bim/config/locales/crowdin/kk.yml @@ -9,6 +9,7 @@ kk: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/ko.yml b/modules/bim/config/locales/crowdin/ko.yml index 7676527e9ad1..13afd9382cc0 100644 --- a/modules/bim/config/locales/crowdin/ko.yml +++ b/modules/bim/config/locales/crowdin/ko.yml @@ -9,6 +9,7 @@ ko: label_bcf: 'BCF' label_imported_failed: 'BCF 항목 가져오기 실패' label_imported_successfully: 'BCF 항목 가져오기 성공' + label_bcf_issue_associated: "BCF issue associated" issues: "이슈" recommended: '추천' not_recommended: '추천하지 않음' diff --git a/modules/bim/config/locales/crowdin/lt.yml b/modules/bim/config/locales/crowdin/lt.yml index 7073e36534fb..96a0ffd308ed 100644 --- a/modules/bim/config/locales/crowdin/lt.yml +++ b/modules/bim/config/locales/crowdin/lt.yml @@ -9,6 +9,7 @@ lt: label_bcf: 'BCF' label_imported_failed: 'BCF temų importas nepavyko' label_imported_successfully: 'BCF temos sėkmingai importuotos' + label_bcf_issue_associated: "BCF issue associated" issues: "Trūkumai" recommended: 'rekomenduojama' not_recommended: 'nerekomenduojama' diff --git a/modules/bim/config/locales/crowdin/lv.yml b/modules/bim/config/locales/crowdin/lv.yml index 96d2e45449a9..35be104e340c 100644 --- a/modules/bim/config/locales/crowdin/lv.yml +++ b/modules/bim/config/locales/crowdin/lv.yml @@ -9,6 +9,7 @@ lv: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/mn.yml b/modules/bim/config/locales/crowdin/mn.yml index e040cc037792..7587b60f15ec 100644 --- a/modules/bim/config/locales/crowdin/mn.yml +++ b/modules/bim/config/locales/crowdin/mn.yml @@ -9,6 +9,7 @@ mn: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/ms.yml b/modules/bim/config/locales/crowdin/ms.yml index dff87b50b925..6fe1a272c62c 100644 --- a/modules/bim/config/locales/crowdin/ms.yml +++ b/modules/bim/config/locales/crowdin/ms.yml @@ -9,6 +9,7 @@ ms: label_bcf: 'BCF' label_imported_failed: 'Import topik BCF yang gagal' label_imported_successfully: 'Import topik BCF yang berjaya' + label_bcf_issue_associated: "BCF issue associated" issues: "Isu-isu" recommended: 'disarankan' not_recommended: 'tidak disarankan' diff --git a/modules/bim/config/locales/crowdin/ne.yml b/modules/bim/config/locales/crowdin/ne.yml index e232369a455f..2be6b0381808 100644 --- a/modules/bim/config/locales/crowdin/ne.yml +++ b/modules/bim/config/locales/crowdin/ne.yml @@ -9,6 +9,7 @@ ne: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/nl.yml b/modules/bim/config/locales/crowdin/nl.yml index bc932dd36242..78cf3ea2c696 100644 --- a/modules/bim/config/locales/crowdin/nl.yml +++ b/modules/bim/config/locales/crowdin/nl.yml @@ -9,6 +9,7 @@ nl: label_bcf: 'BCF' label_imported_failed: 'Mislukte import van BCF onderwerpen' label_imported_successfully: 'Succesvol BCF onderwerpen geïmporteerd' + label_bcf_issue_associated: "BCF issue associated" issues: "Problemen" recommended: 'aanbevolen' not_recommended: 'niet aanbevolen' diff --git a/modules/bim/config/locales/crowdin/no.yml b/modules/bim/config/locales/crowdin/no.yml index ae655052c08a..7681c1727688 100644 --- a/modules/bim/config/locales/crowdin/no.yml +++ b/modules/bim/config/locales/crowdin/no.yml @@ -9,6 +9,7 @@ label_bcf: 'BCF' label_imported_failed: 'Kunne ikke importere BCF-emner' label_imported_successfully: 'Vellykket importert av BCF-emner' + label_bcf_issue_associated: "BCF issue associated" issues: "Problemer" recommended: 'anbefalt' not_recommended: 'ikke anbefalt' diff --git a/modules/bim/config/locales/crowdin/pl.yml b/modules/bim/config/locales/crowdin/pl.yml index 80c3d0088a03..b82710480df0 100644 --- a/modules/bim/config/locales/crowdin/pl.yml +++ b/modules/bim/config/locales/crowdin/pl.yml @@ -9,6 +9,7 @@ pl: label_bcf: 'BCF' label_imported_failed: 'Nieudane importy tematów BCF' label_imported_successfully: 'Zaimportowane z powodzeniem tematy BCF' + label_bcf_issue_associated: "BCF issue associated" issues: "Problemy" recommended: 'zalecane' not_recommended: 'niezalecane' diff --git a/modules/bim/config/locales/crowdin/pt-BR.yml b/modules/bim/config/locales/crowdin/pt-BR.yml index 9c8b89a127b9..e191f45cdbd0 100644 --- a/modules/bim/config/locales/crowdin/pt-BR.yml +++ b/modules/bim/config/locales/crowdin/pt-BR.yml @@ -9,6 +9,7 @@ pt-BR: label_bcf: 'BCF' label_imported_failed: 'Importação de tópicos BCF falhou' label_imported_successfully: 'Tópicos BCF importados com sucesso' + label_bcf_issue_associated: "BCF issue associated" issues: "Problemas" recommended: 'recomendado' not_recommended: 'não recomendado' diff --git a/modules/bim/config/locales/crowdin/pt-PT.yml b/modules/bim/config/locales/crowdin/pt-PT.yml index ce55bd40cda8..f7484d9c4e13 100644 --- a/modules/bim/config/locales/crowdin/pt-PT.yml +++ b/modules/bim/config/locales/crowdin/pt-PT.yml @@ -9,6 +9,7 @@ pt-PT: label_bcf: 'BCF' label_imported_failed: 'A importação de tópicos BCF falhou' label_imported_successfully: 'Tópicos BCF importados com sucesso' + label_bcf_issue_associated: "BCF issue associated" issues: "Problemas" recommended: 'recomendado' not_recommended: 'não recomendado' diff --git a/modules/bim/config/locales/crowdin/ro.yml b/modules/bim/config/locales/crowdin/ro.yml index 16677886f798..f845ef941565 100644 --- a/modules/bim/config/locales/crowdin/ro.yml +++ b/modules/bim/config/locales/crowdin/ro.yml @@ -9,6 +9,7 @@ ro: label_bcf: 'BCF' label_imported_failed: 'Importuri eșuate de subiecte BCF' label_imported_successfully: 'Ați importat cu succes subiectele BCF' + label_bcf_issue_associated: "BCF issue associated" issues: "Sunt câteva probleme cu produsele din coșul tău. Te rog mergi înapoi la pagina coșului și remediază aceste probleme înainte de finalizarea comenzii." recommended: 'recomandat' not_recommended: 'Recomandat' diff --git a/modules/bim/config/locales/crowdin/ru.yml b/modules/bim/config/locales/crowdin/ru.yml index 9c6dccc7c3ae..eda54c4ccd1e 100644 --- a/modules/bim/config/locales/crowdin/ru.yml +++ b/modules/bim/config/locales/crowdin/ru.yml @@ -9,6 +9,7 @@ ru: label_bcf: 'BCF' label_imported_failed: 'Неудачный импорт тем BCF' label_imported_successfully: 'Успешно импортированные темы BCF' + label_bcf_issue_associated: "Связанная проблема BCF" issues: "Замечания" recommended: 'рекомендуется' not_recommended: 'не рекомендуется' diff --git a/modules/bim/config/locales/crowdin/rw.yml b/modules/bim/config/locales/crowdin/rw.yml index c7787ca82930..bc85639e1900 100644 --- a/modules/bim/config/locales/crowdin/rw.yml +++ b/modules/bim/config/locales/crowdin/rw.yml @@ -9,6 +9,7 @@ rw: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/si.yml b/modules/bim/config/locales/crowdin/si.yml index 0073510451eb..ed5d98a46a04 100644 --- a/modules/bim/config/locales/crowdin/si.yml +++ b/modules/bim/config/locales/crowdin/si.yml @@ -9,6 +9,7 @@ si: label_bcf: 'BCF' label_imported_failed: 'BCF මාතෘකා ආනයනය අසමත්' label_imported_successfully: 'සාර්ථකව ආනයනය BCF මාතෘකා' + label_bcf_issue_associated: "BCF issue associated" issues: "ගැටළු" recommended: 'නිර්දේශ' not_recommended: 'නිර්දේශ කර නැත' diff --git a/modules/bim/config/locales/crowdin/sk.yml b/modules/bim/config/locales/crowdin/sk.yml index 115cc3abb16b..83cece88924f 100644 --- a/modules/bim/config/locales/crowdin/sk.yml +++ b/modules/bim/config/locales/crowdin/sk.yml @@ -9,6 +9,7 @@ sk: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/sl.yml b/modules/bim/config/locales/crowdin/sl.yml index 21dd1a15ba2d..2f2aa2d9b175 100644 --- a/modules/bim/config/locales/crowdin/sl.yml +++ b/modules/bim/config/locales/crowdin/sl.yml @@ -9,6 +9,7 @@ sl: label_bcf: 'BCF' label_imported_failed: 'Uvoz tematike BCF ni uspel' label_imported_successfully: 'Uspešno vnesena tematika BCF' + label_bcf_issue_associated: "BCF issue associated" issues: "Zahtevki" recommended: 'Priporočeno' not_recommended: 'ni priporočeno' diff --git a/modules/bim/config/locales/crowdin/sr.yml b/modules/bim/config/locales/crowdin/sr.yml index c58bfc06be4d..70c241a8fcf5 100644 --- a/modules/bim/config/locales/crowdin/sr.yml +++ b/modules/bim/config/locales/crowdin/sr.yml @@ -9,6 +9,7 @@ sr: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/sv.yml b/modules/bim/config/locales/crowdin/sv.yml index 565c0cd636c8..c6ba765552d5 100644 --- a/modules/bim/config/locales/crowdin/sv.yml +++ b/modules/bim/config/locales/crowdin/sv.yml @@ -9,6 +9,7 @@ sv: label_bcf: 'BCF' label_imported_failed: 'Misslyckad import av BCF-ämnen' label_imported_successfully: 'BCF-ämnen har importerats' + label_bcf_issue_associated: "BCF issue associated" issues: "Problem" recommended: 'rekommenderad' not_recommended: 'rekommenderas inte' diff --git a/modules/bim/config/locales/crowdin/th.yml b/modules/bim/config/locales/crowdin/th.yml index 8097ec79f63a..32f3ebf94e45 100644 --- a/modules/bim/config/locales/crowdin/th.yml +++ b/modules/bim/config/locales/crowdin/th.yml @@ -9,6 +9,7 @@ th: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/tr.yml b/modules/bim/config/locales/crowdin/tr.yml index 620324c49d7f..0b61a6b81f31 100644 --- a/modules/bim/config/locales/crowdin/tr.yml +++ b/modules/bim/config/locales/crowdin/tr.yml @@ -9,6 +9,7 @@ tr: label_bcf: 'BCF' label_imported_failed: 'BCF konularının başarısız ithalatı' label_imported_successfully: 'BCF konuları başarıyla içe aktarıldı' + label_bcf_issue_associated: "BCF issue associated" issues: "Sorunlar" recommended: 'Tavsiye edilen' not_recommended: 'tavsiye edilmez' diff --git a/modules/bim/config/locales/crowdin/uk.yml b/modules/bim/config/locales/crowdin/uk.yml index b067b682121b..54170c09c47b 100644 --- a/modules/bim/config/locales/crowdin/uk.yml +++ b/modules/bim/config/locales/crowdin/uk.yml @@ -9,6 +9,7 @@ uk: label_bcf: 'BCF' label_imported_failed: 'Не вдалося імпортувати BFC теми' label_imported_successfully: 'Успішно завантажено BCF теми' + label_bcf_issue_associated: "BCF issue associated" issues: "Задачі" recommended: 'рекомендовано' not_recommended: 'не рекомендується' diff --git a/modules/bim/config/locales/crowdin/uz.yml b/modules/bim/config/locales/crowdin/uz.yml index 468866f74686..586ed9485ae7 100644 --- a/modules/bim/config/locales/crowdin/uz.yml +++ b/modules/bim/config/locales/crowdin/uz.yml @@ -9,6 +9,7 @@ uz: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/config/locales/crowdin/vi.yml b/modules/bim/config/locales/crowdin/vi.yml index df7002050e26..e998a3eba566 100644 --- a/modules/bim/config/locales/crowdin/vi.yml +++ b/modules/bim/config/locales/crowdin/vi.yml @@ -9,6 +9,7 @@ vi: label_bcf: 'BCF' label_imported_failed: 'Nhập các chủ đề BCF thất bại' label_imported_successfully: 'Đã nhập các chủ đề BCF thành công' + label_bcf_issue_associated: "BCF issue associated" issues: "Các vấn đề" recommended: 'khuyến nghị' not_recommended: 'không khuyến nghị' diff --git a/modules/bim/config/locales/crowdin/zh-CN.yml b/modules/bim/config/locales/crowdin/zh-CN.yml index 34121ece8a78..4f3239732f93 100644 --- a/modules/bim/config/locales/crowdin/zh-CN.yml +++ b/modules/bim/config/locales/crowdin/zh-CN.yml @@ -9,6 +9,7 @@ zh-CN: label_bcf: 'BCF' label_imported_failed: '导入 BCF 主题失败' label_imported_successfully: '已成功导入 BCF 主题' + label_bcf_issue_associated: "相关的 BCF 问题" issues: "问题" recommended: '推荐' not_recommended: '不推荐' diff --git a/modules/bim/config/locales/crowdin/zh-TW.yml b/modules/bim/config/locales/crowdin/zh-TW.yml index 1fed792db0ab..e4bfd930797e 100644 --- a/modules/bim/config/locales/crowdin/zh-TW.yml +++ b/modules/bim/config/locales/crowdin/zh-TW.yml @@ -9,6 +9,7 @@ zh-TW: label_bcf: 'BCF' label_imported_failed: '無法匯入 BCF 主題' label_imported_successfully: ' ' + label_bcf_issue_associated: "相關 BCF 問題" issues: "問題集" recommended: '推薦' not_recommended: '不推薦' diff --git a/modules/bim/config/locales/en.yml b/modules/bim/config/locales/en.yml index a500501d80ce..d8636669aa9a 100644 --- a/modules/bim/config/locales/en.yml +++ b/modules/bim/config/locales/en.yml @@ -11,6 +11,7 @@ en: label_bcf: 'BCF' label_imported_failed: 'Failed imports of BCF topics' label_imported_successfully: 'Successfully imported BCF topics' + label_bcf_issue_associated: "BCF issue associated" issues: "Issues" recommended: 'recommended' not_recommended: 'not recommended' diff --git a/modules/bim/spec/models/queries/work_packages/filter/bcf_issue_associated_filter_spec.rb b/modules/bim/spec/models/queries/work_packages/filter/bcf_issue_associated_filter_spec.rb index d935b80db580..58a2be69a24e 100644 --- a/modules/bim/spec/models/queries/work_packages/filter/bcf_issue_associated_filter_spec.rb +++ b/modules/bim/spec/models/queries/work_packages/filter/bcf_issue_associated_filter_spec.rb @@ -35,6 +35,7 @@ let(:model) { WorkPackage } let(:class_key) { :bcf_issue_associated } let(:type) { :list } + let(:human_name) { "BCF issue associated" } describe "#available?" do context "if bim is enabled", with_config: { edition: "bim" } do diff --git a/modules/boards/config/locales/crowdin/js-mn.yml b/modules/boards/config/locales/crowdin/js-mn.yml index 439c3d0a0d38..f9d9a67c5692 100644 --- a/modules/boards/config/locales/crowdin/js-mn.yml +++ b/modules/boards/config/locales/crowdin/js-mn.yml @@ -2,29 +2,29 @@ mn: js: boards: - create_new: 'Create new board' - label_unnamed_board: 'Unnamed board' - label_unnamed_list: 'Unnamed list' - label_board_type: 'Board type' + create_new: 'Шинэ самбар үүсгэх' + label_unnamed_board: 'Нэрлэгдээгүй самбар' + label_unnamed_list: 'Нэрлэгдээгүй жагсаалт' + label_board_type: 'Самбарын төрөл' upsale: teaser_text: 'Would you like to automate your workflows with Boards? Advanced boards are an Enterprise add-on. Please upgrade to a paid plan.' - upgrade: 'Upgrade now' + upgrade: 'Яг одоо шинэчлэх' lists: - delete: 'Delete list' + delete: 'Устгасан жагсаалт' version: is_locked: 'Version is locked. No items can be added to this version.' is_closed: 'Version is closed. No items can be added to this version.' - close_version: 'Close version' - open_version: 'Open version' - lock_version: 'Lock version' - unlock_version: 'Unlock version' - edit_version: 'Edit version' - show_version: 'Show version' - locked: 'Locked' - closed: 'Closed' - new_board: 'New board' + close_version: 'Хувилбар хаах' + open_version: 'Хувилбар нээх' + lock_version: 'Хувилбар цоожлох' + unlock_version: 'Хувилбарын цоожыг тайлах' + edit_version: 'Хувилбар засах' + show_version: 'Хувилбар харах' + locked: 'Цоожлогдсон' + closed: 'Хаагдсан' + new_board: 'Шинэ самбар' add_list: 'Add list to board' - add_card: 'Add card' + add_card: 'Картлуу нэмэх' error_attribute_not_writable: "Cannot move the work package, %{attribute} is not writable." error_loading_the_list: "Error loading the list: %{error_message}" error_permission_missing: "The permission to create public queries is missing" @@ -32,12 +32,12 @@ mn: text_hidden_list_warning: "Not all lists are displayed because you lack the permission. Contact your admin for more information." click_to_remove_list: "Click to remove this list" board_type: - text: 'Board type' - free: 'basic' + text: 'Самбарын төрөл' + free: 'ердийн' select_board_type: 'Please choose the type of board you need.' free_text: > Start from scratch with a blank board. Manually add cards and columns to this board. - action: 'Action board' + action: 'Үйлдлийн самбар' action_by_attribute: 'Action board (%{attribute})' action_text: > A board with filtered lists on %{attribute} attribute. Moving work packages to other lists will update their attribute. @@ -52,18 +52,18 @@ mn: action_text_version: > Board with automated columns based on the version attribute. Ideal for planning product development. action_type: - assignee: assignee - status: status + assignee: даалгагч + status: төлөв version: version - subproject: subproject + subproject: дэд төсөл subtasks: parent-child board_type_title: - assignee: Assignee - status: Status - version: Version + assignee: Даалгагч + status: Төлөв + version: Хувилбар subproject: Subproject subtasks: Parent-child - basic: Basic + basic: Ердийн select_attribute: "Action attribute" add_list_modal: labels: diff --git a/modules/boards/config/locales/crowdin/mn.yml b/modules/boards/config/locales/crowdin/mn.yml index c6adf037e768..6401d3514b74 100644 --- a/modules/boards/config/locales/crowdin/mn.yml +++ b/modules/boards/config/locales/crowdin/mn.yml @@ -3,24 +3,24 @@ mn: plugin_openproject_boards: name: "OpenProject Boards" description: "Provides board views." - permission_show_board_views: "View boards" - permission_manage_board_views: "Manage boards" - project_module_board_view: "Boards" + permission_show_board_views: "Самбаруудыг үзэх" + permission_manage_board_views: "Самбаруудыг удирдах" + project_module_board_view: "Самбарууд" boards: - label_board: "Board" - label_boards: "Boards" - label_create_new_board: "Create new board" - label_board_type: "Board type" + label_board: "Самбар" + label_boards: "Самбарууд" + label_create_new_board: "Шинэ самбар үүсгэх" + label_board_type: "Самбарын төрөл" board_types: - free: Basic - action: "Action board (%{attribute})" + free: Ердийн + action: "Үйлдлийн самбар (%{attribute})" board_type_attributes: - assignee: Assignee - status: Status - version: Version - subproject: Subproject + assignee: Даалгагч + status: Төлөв + version: Хувилбар + subproject: Дэд төсөл subtasks: Parent-child - basic: Basic + basic: Ердийн board_type_descriptions: basic: > Start from scratch with a blank board. Manually add cards and columns to this board. @@ -35,5 +35,5 @@ mn: subtasks: > Board with automated columns for sub-elements. Dragging work packages to other lists updates the parent accordingly. upsale: - teaser_text: 'Would you like to automate your workflows with Boards? Advanced boards are an Enterprise add-on. Please upgrade to a paid plan.' - upgrade: 'Upgrade now' + teaser_text: 'Та самбарын тусламжтайгаар ажлын урсгалаа автоматжуулахыг хүсч байна уу? Нарийвчилсан самбарууд нь Enterprise нэмэлт юм. Төлбөртэй багц болгон шинэчилнэ үү.' + upgrade: 'Одоо шинэчлэх' diff --git a/modules/calendar/config/locales/crowdin/js-mn.yml b/modules/calendar/config/locales/crowdin/js-mn.yml index 194eaf34bdc6..005c38122ee1 100644 --- a/modules/calendar/config/locales/crowdin/js-mn.yml +++ b/modules/calendar/config/locales/crowdin/js-mn.yml @@ -2,7 +2,7 @@ mn: js: calendar: - create_new: 'Create new calendar' - title: 'Calendar' - too_many: 'There are %{count} work packages in total, but only %{max} can be shown.' - unsaved_title: 'Unnamed calendar' + create_new: 'Шинэ хуанли үүсгэх' + title: 'Хуанли' + too_many: 'Нийт %{count} ажлын багц байгаа ч зөвхөн %{max}-г харуулах боломжтой.' + unsaved_title: 'Нэрлэгдээгүй хуанли' diff --git a/modules/calendar/config/locales/crowdin/mn.yml b/modules/calendar/config/locales/crowdin/mn.yml index b8eb4cd2d168..78f6a9ad08e4 100644 --- a/modules/calendar/config/locales/crowdin/mn.yml +++ b/modules/calendar/config/locales/crowdin/mn.yml @@ -1,12 +1,12 @@ #English strings go here mn: plugin_openproject_calendar: - name: "OpenProject Calendar" - description: "Provides calendar views." + name: "OpenProject Хуанли" + description: "Хуанли харах боломжийг олгодог." label_calendar: "Calendar" - label_calendar_plural: "Calendars" - label_new_calendar: "New calendar" - permission_view_calendar: "View calendars" - permission_manage_calendars: "Manage calendars" + label_calendar_plural: "Хуанли" + label_new_calendar: "Шинэ хуанли" + permission_view_calendar: "Хуанли харах" + permission_manage_calendars: "Хуанли удирдах" permission_share_calendars: "Subscribe to iCalendars" - project_module_calendar_view: "Calendars" + project_module_calendar_view: "Хуанли" diff --git a/modules/dashboards/config/locales/crowdin/js-mn.yml b/modules/dashboards/config/locales/crowdin/js-mn.yml index fa1138ce7dd5..47e6b5a69741 100644 --- a/modules/dashboards/config/locales/crowdin/js-mn.yml +++ b/modules/dashboards/config/locales/crowdin/js-mn.yml @@ -1,4 +1,4 @@ mn: js: dashboards: - label: ' Хянах самбар' + label: 'Хянах самбар' diff --git a/modules/documents/config/locales/crowdin/mn.yml b/modules/documents/config/locales/crowdin/mn.yml index 4430633680a2..0717bdcec09f 100644 --- a/modules/documents/config/locales/crowdin/mn.yml +++ b/modules/documents/config/locales/crowdin/mn.yml @@ -21,23 +21,23 @@ #++ mn: plugin_openproject_documents: - name: "OpenProject Documents" + name: "OpenProject баримт бичиг" description: "An OpenProject plugin to allow creation of documents in projects." activerecord: models: - document: "Document" + document: "Баримт бичиг" activity: filter: - document: "Documents" - default_doc_category_tech: "Technical documentation" - default_doc_category_user: "User documentation" - enumeration_doc_categories: "Document categories" + document: "Баримт бичгүүд" + default_doc_category_tech: "Техникийн баримт бичиг" + default_doc_category_user: "Хэрэглэгчийн баримт бичиг" + enumeration_doc_categories: "Баримт бичгийн ангилал" documents: - label_attachment_author: "Attachment author" - label_document_added: "Document added" + label_attachment_author: "Хавсралтын зохиогч" + label_document_added: "Баримт бичиг нэмэгдсэн" label_document_new: "New document" - label_document_plural: "Documents" - label_documents: "Documents" - permission_manage_documents: "Manage documents" - permission_view_documents: "View documents" - project_module_documents: "Documents" + label_document_plural: "Баримт бичгүүд" + label_documents: "Баримт бичгүүд" + permission_manage_documents: "Баримт бичгүүдийг удирдах" + permission_view_documents: "Баримт бичгүүдийг харах" + project_module_documents: "Баримт бичгүүд" diff --git a/modules/gantt/config/locales/crowdin/js-mn.yml b/modules/gantt/config/locales/crowdin/js-mn.yml index 06c711fbbf89..e126cc447b3f 100644 --- a/modules/gantt/config/locales/crowdin/js-mn.yml +++ b/modules/gantt/config/locales/crowdin/js-mn.yml @@ -2,4 +2,4 @@ mn: js: work_packages: default_queries: - milestones: 'Milestones' + milestones: 'Чухал үеүүд' diff --git a/modules/job_status/config/locales/crowdin/mn.yml b/modules/job_status/config/locales/crowdin/mn.yml index 0be309ed5798..5de2f35a0d77 100644 --- a/modules/job_status/config/locales/crowdin/mn.yml +++ b/modules/job_status/config/locales/crowdin/mn.yml @@ -1,21 +1,21 @@ mn: - label_job_status_plural: "Job statuses" + label_job_status_plural: "Ажлын төлвүүд" plugin_openproject_job_status: name: "OpenProject Job status" description: "Listing and status of background jobs." job_status_dialog: download_starts: 'The download should start automatically.' link_to_download: 'Or, %{link} to download.' - click_here: 'click here' - title: 'Background job status' + click_here: 'энд дарна уу' + title: 'Суурь ажлын төлөв' redirect: 'You are being redirected.' redirect_link: 'Please click here to continue.' redirect_errors: 'Due to these errors, you will not be redirected automatically.' - errors: 'Something went wrong' + errors: 'Ямар нэг алдаа гарлаа' generic_messages: not_found: 'This job could not be found.' in_queue: 'The job has been queued and will be processed shortly.' in_process: 'The job is currently being processed.' - error: 'The job has failed to complete.' + error: 'Ажлыг дуусгаж чадсангүй.' cancelled: 'The job has been cancelled due to an error.' success: 'The job completed successfully.' diff --git a/modules/meeting/app/components/meeting_agenda_items/blank_slate_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/blank_slate_component.html.erb index 3380f57b5620..44f1977e1331 100644 --- a/modules/meeting/app/components/meeting_agenda_items/blank_slate_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/blank_slate_component.html.erb @@ -8,14 +8,15 @@ flex.with_row(mb: 2) do render(Primer::Beta::Text.new(color: :subtle)) { t(:"recurring_meeting.template.description") } end + else + flex.with_row(mb: 2) do + render(Primer::Beta::Text.new(color: :subtle)) { t(:text_meeting_empty_description_1) } + end + flex.with_row do + render(Primer::Beta::Text.new(color: :subtle)) { t(:text_meeting_empty_description_2) } + end end - flex.with_row(mb: 2) do - render(Primer::Beta::Text.new(color: :subtle)) { t(:text_meeting_empty_description_1) } - end - flex.with_row do - render(Primer::Beta::Text.new(color: :subtle)) { t(:text_meeting_empty_description_2) } - end if can_finalize_template? flex.with_row(mt: 2) do render(Primer::Beta::Text.new(font_weight: :bold, color: :subtle)) do diff --git a/modules/meeting/app/components/meeting_agenda_items/list_component.html.erb b/modules/meeting/app/components/meeting_agenda_items/list_component.html.erb index 3941939e1767..174a85ae63be 100644 --- a/modules/meeting/app/components/meeting_agenda_items/list_component.html.erb +++ b/modules/meeting/app/components/meeting_agenda_items/list_component.html.erb @@ -1,7 +1,7 @@ <%= component_wrapper(data: wrapper_data_attributes) do flex_layout(mb: 3) do |flex| - if @meeting.template? + if @meeting.template? && !empty? flex.with_row(mb: 3) do render Primer::Alpha::Banner.new(scheme: :default, icon: :info, @@ -21,7 +21,7 @@ ) ) end - if @meeting.agenda_items.empty? && @meeting.sections.empty? + if empty? flex.with_row do render(border_box_container) do |border_box| if @form_hidden diff --git a/modules/meeting/app/components/meeting_agenda_items/list_component.rb b/modules/meeting/app/components/meeting_agenda_items/list_component.rb index 92cd53f9b065..709fd947170c 100644 --- a/modules/meeting/app/components/meeting_agenda_items/list_component.rb +++ b/modules/meeting/app/components/meeting_agenda_items/list_component.rb @@ -40,6 +40,10 @@ def initialize(meeting:, form_hidden: true, form_type: :simple) @form_type = form_type end + def empty? + @meeting.agenda_items.empty? && @meeting.sections.empty? + end + private def wrapper_data_attributes diff --git a/modules/meeting/app/components/meetings/index/form_component.html.erb b/modules/meeting/app/components/meetings/index/form_component.html.erb index 82f8c581a1e9..01b12e0dc224 100644 --- a/modules/meeting/app/components/meetings/index/form_component.html.erb +++ b/modules/meeting/app/components/meetings/index/form_component.html.erb @@ -6,7 +6,11 @@ method: form_method, data: { turbo: true, - controller: "show-when-value-selected" + controller: [ + "show-when-value-selected", + @meeting.is_a?(RecurringMeeting) ? "recurring-meetings--form" : nil, + ].compact.join(" "), + "application-target": "dynamic" }, html: { id: 'meeting-form' @@ -35,15 +39,11 @@ end modal_body.with_row(mt: 3) do - render(Meeting::TimeGroup.new(f, meeting: @meeting)) - end - - modal_body.with_row(mt: 3) do - render(Meeting::Duration.new(f, meeting: @meeting)) + render(Meeting::Location.new(f, meeting: @meeting)) end modal_body.with_row(mt: 3) do - render(Meeting::Location.new(f, meeting: @meeting)) + render(Meeting::TimeGroup.new(f, meeting: @meeting)) end if @meeting.is_a?(RecurringMeeting) @@ -67,28 +67,50 @@ end end - modal_body.with_row(mt: 3) do - render(RecurringMeeting::EndAfter.new(f)) + modal_body.with_row(mt: 1) do + render(Primer::Beta::Text.new( + id: "recurring-meeting-frequency-schedule", + font_size: :small, + color: :subtle, + )) { @meeting.human_frequency_schedule } end - modal_body.with_row(mt: 3, - hidden: @meeting.end_after_iterations?, - data: { - value: "specific_date", - target_name: "end_after", - "show-when-value-selected-target": "effect" } - ) do - render(RecurringMeeting::SpecificDate.new(f, meeting: @meeting)) - end + modal_body.with_row(mt: 3) do + flex_layout(classes: "FormControl-horizontalGroup") do |frequency_row| + frequency_row.with_column(flex: 1) do + render(RecurringMeeting::EndAfter.new(f)) + end - modal_body.with_row(mt: 3, - hidden: @meeting.end_after_specific_date?, - data: { - value: "iterations", - target_name: "end_after", - "show-when-value-selected-target": "effect" - }) do - render(RecurringMeeting::Iterations.new(f)) + frequency_row.with_column( + flex: 1, + hidden: @meeting.frequency_working_days?, + data: { + target_name: "frequency", + not_value: "working_days", + set_visibility: "true", + "show-when-value-selected-target": "effect" + }) do + flex_layout do |end_after| + end_after.with_row(hidden: @meeting.end_after_iterations?, + data: { + value: "specific_date", + target_name: "end_after", + "show-when-value-selected-target": "effect" } + ) do + render(RecurringMeeting::SpecificDate.new(f, meeting: @meeting)) + end + + end_after.with_row(hidden: @meeting.end_after_specific_date?, + data: { + value: "iterations", + target_name: "end_after", + "show-when-value-selected-target": "effect" + }) do + render(RecurringMeeting::Iterations.new(f)) + end + end + end + end end else modal_body.with_row do diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb index 70644cb58e25..b1aca653a074 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb @@ -27,20 +27,24 @@ tag: :a, href: new_dialog_meetings_path(project_id: @project&.id, type: :structured), content_arguments: { data: { controller: "async-dialog" }} - ) + ) do |item| + item.with_description.with_content(t("meeting.types.structured_text")) + end - if OpenProject::FeatureDecisions.recurring_meetings_active? - menu.with_item(label: I18n.t("meeting.types.recurring"), - tag: :a, - href: new_dialog_meetings_path(project_id: @project&.id, type: :recurring), - content_arguments: { data: { controller: "async-dialog" }} - ) + menu.with_item(label: I18n.t("meeting.types.recurring"), + tag: :a, + href: new_dialog_meetings_path(project_id: @project&.id, type: :recurring), + content_arguments: { data: { controller: "async-dialog" }} + ) do |item| + item.with_description.with_content(t("meeting.types.recurring_text")) end menu.with_item(label: I18n.t("meeting.types.classic"), tag: :a, href: dynamic_path - ) + ) do |item| + item.with_description.with_content(t("meeting.types.classic_text")) + end end end end diff --git a/modules/meeting/app/components/meetings/side_panel/details_component.html.erb b/modules/meeting/app/components/meetings/side_panel/details_component.html.erb index d8f8fc7d623c..c9d94216d661 100644 --- a/modules/meeting/app/components/meetings/side_panel/details_component.html.erb +++ b/modules/meeting/app/components/meetings/side_panel/details_component.html.erb @@ -32,18 +32,10 @@ details.with_row do render_meeting_attribute_row(:"git-commit") do render(Primer::Beta::Text.new) do - @meeting.recurring_meeting.human_frequency + @meeting.recurring_meeting.base_schedule end end end - - details.with_row(mt: 2) do - render_meeting_attribute_row(:calendar) do - render(Primer::Beta::Text.new) do - @meeting.recurring_meeting.human_day_of_week - end - end - end if @meeting.recurring_meeting.frequency_weekly? else if @series.present? details.with_row(mb: 2) do diff --git a/modules/meeting/app/components/meetings/side_panel/details_form_component.html.erb b/modules/meeting/app/components/meetings/side_panel/details_form_component.html.erb index cdc2bbc4d52c..cc719ac1358a 100644 --- a/modules/meeting/app/components/meetings/side_panel/details_form_component.html.erb +++ b/modules/meeting/app/components/meetings/side_panel/details_form_component.html.erb @@ -17,10 +17,6 @@ render(Meeting::TimeGroup.new(f, meeting: @meeting)) end - modal_body.with_row(mt: 3) do - render(Meeting::Duration.new(f, meeting: @meeting)) - end - modal_body.with_row(mt: 3) do render(Meeting::Location.new(f, meeting: @meeting)) end diff --git a/modules/meeting/app/components/recurring_meetings/footer_component.rb b/modules/meeting/app/components/recurring_meetings/footer_component.rb index a3666e063930..5a68df141e95 100644 --- a/modules/meeting/app/components/recurring_meetings/footer_component.rb +++ b/modules/meeting/app/components/recurring_meetings/footer_component.rb @@ -49,7 +49,7 @@ def label if @direction == "past" I18n.t("label_recurring_meeting_more_past#{label_suffix}", count:) else - I18n.t("label_recurring_meeting_more#{label_suffix}", count:, schedule: @meeting.schedule_in_words) + I18n.t("label_recurring_meeting_more#{label_suffix}", count:, schedule: @meeting.full_schedule_in_words) end end end diff --git a/modules/meeting/app/components/recurring_meetings/row_component.rb b/modules/meeting/app/components/recurring_meetings/row_component.rb index fc11d9415199..8a958c871717 100644 --- a/modules/meeting/app/components/recurring_meetings/row_component.rb +++ b/modules/meeting/app/components/recurring_meetings/row_component.rb @@ -91,12 +91,6 @@ def relative_time render(OpPrimer::RelativeTimeComponent.new(datetime: user_time_zone(time), prefix: I18n.t(:label_on))) end - def last_edited - return unless instantiated? - - helpers.format_time(meeting.updated_at, include_date: true) - end - def state if model.cancelled? "cancelled" diff --git a/modules/meeting/app/components/recurring_meetings/show_page_header_component.rb b/modules/meeting/app/components/recurring_meetings/show_page_header_component.rb index 20cc8aa68e4a..757fe2c6fe99 100644 --- a/modules/meeting/app/components/recurring_meetings/show_page_header_component.rb +++ b/modules/meeting/app/components/recurring_meetings/show_page_header_component.rb @@ -69,7 +69,7 @@ def page_title end def page_description - @meeting.schedule_in_words + @meeting.full_schedule_in_words end def breadcrumb_items diff --git a/modules/meeting/app/components/recurring_meetings/table_component.rb b/modules/meeting/app/components/recurring_meetings/table_component.rb index 520c2c4e6a63..5b92be0e4aec 100644 --- a/modules/meeting/app/components/recurring_meetings/table_component.rb +++ b/modules/meeting/app/components/recurring_meetings/table_component.rb @@ -32,7 +32,7 @@ module RecurringMeetings class TableComponent < ::OpPrimer::BorderBoxTableComponent options :current_project, :count, :direction, :max_count - columns :start_time, :relative_time, :last_edited, :status, :create + columns :start_time, :relative_time, :status, :create def has_actions? true @@ -70,7 +70,6 @@ def headers @headers ||= [ [:start_time, { caption: I18n.t(:label_meeting_date_and_time) }], [:relative_time, { caption: I18n.t("recurring_meeting.starts") }], - [:last_edited, { caption: I18n.t(:label_meeting_last_updated) }], [:status, { caption: Meeting.human_attribute_name(:status) }], [:create, { caption: "" }] ].compact diff --git a/modules/meeting/app/controllers/recurring_meetings/schedule_controller.rb b/modules/meeting/app/controllers/recurring_meetings/schedule_controller.rb new file mode 100644 index 000000000000..8c8b842494c3 --- /dev/null +++ b/modules/meeting/app/controllers/recurring_meetings/schedule_controller.rb @@ -0,0 +1,40 @@ +module RecurringMeetings + class ScheduleController < ApplicationController + before_action do + do_authorize :create_meetings, global: true + end + authorization_checked! :humanize_schedule + + around_action :with_user_time_zone + before_action :build_meeting + + def humanize_schedule + text = @recurring_meeting.human_frequency_schedule + respond_to do |format| + format.html { render plain: text } + format.turbo_stream do + render turbo_stream: turbo_stream.update("recurring-meeting-frequency-schedule", + plain: text) + end + end + end + + private + + def with_user_time_zone(&) + User.execute_as(User.current, &) + end + + def build_meeting + @recurring_meeting = RecurringMeeting.new(schedule_params.compact_blank) + end + + def schedule_params + params + .require(:meeting) + .permit(:start_date, :start_time_hour, :frequency, :interval) + end + + def default_breadcrumb; end + end +end diff --git a/modules/meeting/app/forms/meeting/location.rb b/modules/meeting/app/forms/meeting/location.rb index 996b17e033b9..4d5be511d7af 100644 --- a/modules/meeting/app/forms/meeting/location.rb +++ b/modules/meeting/app/forms/meeting/location.rb @@ -33,8 +33,7 @@ class Meeting::Location < ApplicationForm value: @value, placeholder: Meeting.human_attribute_name(:location), label: Meeting.human_attribute_name(:location), - visually_hide_label: false, - leading_visual: { icon: :location } + visually_hide_label: false ) end diff --git a/modules/meeting/app/forms/meeting/time_group.rb b/modules/meeting/app/forms/meeting/time_group.rb index 20aee89aeb3b..a7c1eccd8083 100644 --- a/modules/meeting/app/forms/meeting/time_group.rb +++ b/modules/meeting/app/forms/meeting/time_group.rb @@ -35,11 +35,13 @@ class Meeting::TimeGroup < ApplicationForm name: :start_date, type: "date", value: @initial_date, - placeholder: Meeting.human_attribute_name(:start_date), - label: Meeting.human_attribute_name(:start_date), - leading_visual: { icon: :calendar }, + placeholder: @meeting.class.human_attribute_name(:start_date), + label: @meeting.class.human_attribute_name(:start_date), required: true, - autofocus: false + autofocus: false, + data: { + action: "input->recurring-meetings--form#updateFrequencyText" + } ) group.text_field( @@ -48,9 +50,25 @@ class Meeting::TimeGroup < ApplicationForm value: @initial_time, placeholder: Meeting.human_attribute_name(:start_time), label: Meeting.human_attribute_name(:start_time), - leading_visual: { icon: :clock }, required: true, - caption: formatted_time_zone_offset + caption: formatted_time_zone_offset, + data: { + action: "input->recurring-meetings--form#updateFrequencyText" + } + ) + group.text_field( + name: :duration, + type: :text, + value: @duration, + placeholder: Meeting.human_attribute_name(:duration), + label: Meeting.human_attribute_name(:duration), + visually_hide_label: false, + required: true, + caption: I18n.t("text_in_hours"), + data: { + controller: "chronic-duration", + application_target: "dynamic" + } ) end end @@ -58,7 +76,21 @@ class Meeting::TimeGroup < ApplicationForm def initialize(meeting:) super() + @meeting = meeting @initial_time = meeting.start_time_hour.presence || format_time(meeting.start_time, include_date: false, format: "%H:%M") @initial_date = meeting.start_date.presence || format_time_as_date(meeting.start_time, format: "%Y-%m-%d") + + duration = duration_value(meeting) + @duration = duration.nil? ? "" : ChronicDuration.output(duration * 3600, format: :hours_only) + end + + private + + def duration_value(meeting) + if meeting.is_a?(RecurringMeeting) && meeting.template + meeting.template.duration + else + meeting.duration + end end end diff --git a/modules/meeting/app/forms/recurring_meeting/frequency.rb b/modules/meeting/app/forms/recurring_meeting/frequency.rb index 06992662d220..8ed3963ec16a 100644 --- a/modules/meeting/app/forms/recurring_meeting/frequency.rb +++ b/modules/meeting/app/forms/recurring_meeting/frequency.rb @@ -33,7 +33,8 @@ class RecurringMeeting::Frequency < ApplicationForm label: I18n.t("activerecord.attributes.recurring_meeting.frequency"), data: { target_name: "frequency", - "show-when-value-selected-target": "cause" + "show-when-value-selected-target": "cause", + action: "input->recurring-meetings--form#updateFrequencyText" } ) do |list| RecurringMeeting.frequencies.each_key do |value| diff --git a/modules/meeting/app/forms/recurring_meeting/interval.rb b/modules/meeting/app/forms/recurring_meeting/interval.rb index 9d598246dd6b..e94f080bf69a 100644 --- a/modules/meeting/app/forms/recurring_meeting/interval.rb +++ b/modules/meeting/app/forms/recurring_meeting/interval.rb @@ -31,8 +31,12 @@ class RecurringMeeting::Interval < ApplicationForm meeting_form.text_field( name: :interval, type: :number, + step: 1, + max: RecurringMeeting::MAX_INTERVAL, label: I18n.t("activerecord.attributes.recurring_meeting.interval"), - caption: I18n.t("recurring_meeting.interval.instructions") + data: { + action: "input->recurring-meetings--form#updateFrequencyText" + } ) end end diff --git a/modules/meeting/app/forms/recurring_meeting/iterations.rb b/modules/meeting/app/forms/recurring_meeting/iterations.rb index a9f1feb2c5af..dffe00d35bc2 100644 --- a/modules/meeting/app/forms/recurring_meeting/iterations.rb +++ b/modules/meeting/app/forms/recurring_meeting/iterations.rb @@ -31,6 +31,8 @@ class RecurringMeeting::Iterations < ApplicationForm meeting_form.text_field( name: :iterations, type: :number, + step: 1, + max: RecurringMeeting::MAX_ITERATIONS, label: I18n.t("activerecord.attributes.recurring_meeting.iterations") ) end diff --git a/modules/meeting/app/forms/recurring_meeting/specific_date.rb b/modules/meeting/app/forms/recurring_meeting/specific_date.rb index 8860012a3f74..53af80881348 100644 --- a/modules/meeting/app/forms/recurring_meeting/specific_date.rb +++ b/modules/meeting/app/forms/recurring_meeting/specific_date.rb @@ -34,7 +34,6 @@ class RecurringMeeting::SpecificDate < ApplicationForm value: @value, placeholder: Meeting.human_attribute_name(:end_date), label: Meeting.human_attribute_name(:end_date), - leading_visual: { icon: :calendar }, required: false, autofocus: false ) diff --git a/modules/meeting/app/menus/meetings/menu.rb b/modules/meeting/app/menus/meetings/menu.rb index f4990f3d626e..cb5a9d328c86 100644 --- a/modules/meeting/app/menus/meetings/menu.rb +++ b/modules/meeting/app/menus/meetings/menu.rb @@ -34,9 +34,9 @@ def initialize(params:, project: nil) def menu_items [ OpenProject::Menu::MenuGroup.new(header: nil, children: top_level_menu_items), - meeting_series_menu_group, + OpenProject::Menu::MenuGroup.new(header: I18n.t(:label_meeting_series), children: meeting_series_menu_items), OpenProject::Menu::MenuGroup.new(header: I18n.t(:label_involvement), children: involvement_sidebar_menu_items) - ].compact + ] end def top_level_menu_items @@ -49,13 +49,7 @@ def top_level_menu_items recurring_menu_item, menu_item(title: I18n.t(:label_all_meetings), query_params: { filters: all_filter }) - ].compact - end - - def meeting_series_menu_group - return unless OpenProject::FeatureDecisions.recurring_meetings_active? - - OpenProject::Menu::MenuGroup.new(header: I18n.t(:label_meeting_series), children: meeting_series_menu_items) + ] end def meeting_series_menu_items @@ -77,8 +71,6 @@ def meeting_series_menu_items end def recurring_menu_item - return unless OpenProject::FeatureDecisions.recurring_meetings_active? - recurring_filter = [{ type: { operator: "=", values: ["t"] } }].to_json menu_item(title: I18n.t("label_recurring_meeting_plural"), diff --git a/modules/meeting/app/models/meeting.rb b/modules/meeting/app/models/meeting.rb index 265df7658197..8f38e8a6aeaf 100644 --- a/modules/meeting/app/models/meeting.rb +++ b/modules/meeting/app/models/meeting.rb @@ -28,6 +28,7 @@ class Meeting < ApplicationRecord include VirtualStartTime + include ChronicDuration include OpenProject::Journal::AttachmentHelper self.table_name = "meetings" @@ -101,7 +102,9 @@ class Meeting < ApplicationRecord accepts_nested_attributes_for :participants, allow_destroy: true - validates_presence_of :title, :project_id, :duration + validates_presence_of :title, :project_id + + validates_numericality_of :duration, greater_than: 0 before_save :add_new_participants_as_watcher diff --git a/modules/meeting/app/forms/meeting/duration.rb b/modules/meeting/app/models/meeting/chronic_duration.rb similarity index 64% rename from modules/meeting/app/forms/meeting/duration.rb rename to modules/meeting/app/models/meeting/chronic_duration.rb index 8e61bd6e91ae..b48a2f186cc9 100644 --- a/modules/meeting/app/forms/meeting/duration.rb +++ b/modules/meeting/app/models/meeting/chronic_duration.rb @@ -26,32 +26,16 @@ # See COPYRIGHT and LICENSE files for more details. #++ -class Meeting::Duration < ApplicationForm - form do |meeting_form| - meeting_form.text_field( - name: :duration, - type: :number, - min: 0, - max: 24, - step: 0.05, - value: @value, - placeholder: Meeting.human_attribute_name(:duration), - label: Meeting.human_attribute_name(:duration), - visually_hide_label: false, - required: true, - leading_visual: { icon: :stopwatch }, - caption: I18n.t("text_in_hours") - ) +module Meeting::ChronicDuration + def duration=(value) + if value.is_a?(String) + write_attribute(:duration, value.to_hours) + else + super + end end - def initialize(meeting:) - super() - - @value = - if meeting.is_a?(RecurringMeeting) && meeting.template - meeting.template.duration - else - meeting.duration - end + def formatted_duration + DurationConverter.output(duration, format: :hours_only) end end diff --git a/modules/meeting/app/models/queries/meetings/filters/attended_user_filter.rb b/modules/meeting/app/models/queries/meetings/filters/attended_user_filter.rb index 5101106cb599..d004477eb838 100644 --- a/modules/meeting/app/models/queries/meetings/filters/attended_user_filter.rb +++ b/modules/meeting/app/models/queries/meetings/filters/attended_user_filter.rb @@ -43,6 +43,10 @@ def where "meeting_participants.user_id IN (#{values.join(',')}) AND meeting_participants.attended" end + def human_name + I18n.t(:label_attended_user) + end + def joins :participants end diff --git a/modules/meeting/app/models/queries/meetings/filters/invited_user_filter.rb b/modules/meeting/app/models/queries/meetings/filters/invited_user_filter.rb index db80fb27f544..59d8f333dfbb 100644 --- a/modules/meeting/app/models/queries/meetings/filters/invited_user_filter.rb +++ b/modules/meeting/app/models/queries/meetings/filters/invited_user_filter.rb @@ -46,6 +46,10 @@ def where ].join(" AND ") end + def human_name + I18n.t(:label_invited_user) + end + def joins :participants end diff --git a/modules/meeting/app/models/queries/meetings/filters/recurring_filter.rb b/modules/meeting/app/models/queries/meetings/filters/recurring_filter.rb index 01279912b04d..47f4e224d2eb 100644 --- a/modules/meeting/app/models/queries/meetings/filters/recurring_filter.rb +++ b/modules/meeting/app/models/queries/meetings/filters/recurring_filter.rb @@ -37,10 +37,6 @@ def human_name I18n.t("label_recurring_meeting_part_of") end - def available? - OpenProject::FeatureDecisions.recurring_meetings_active? - end - def apply_to(query_scope) if allowed_values.first.intersect?(values) query_scope.recurring diff --git a/modules/meeting/app/models/queries/meetings/filters/time_filter.rb b/modules/meeting/app/models/queries/meetings/filters/time_filter.rb index 8ac8caa5f607..f482aed8c1c6 100644 --- a/modules/meeting/app/models/queries/meetings/filters/time_filter.rb +++ b/modules/meeting/app/models/queries/meetings/filters/time_filter.rb @@ -51,6 +51,10 @@ def where end end + def human_name + Meeting.human_attribute_name(:start_time) + end + def type :list end diff --git a/modules/meeting/app/models/recurring_meeting.rb b/modules/meeting/app/models/recurring_meeting.rb index 857f4535b673..30be11c7e309 100644 --- a/modules/meeting/app/models/recurring_meeting.rb +++ b/modules/meeting/app/models/recurring_meeting.rb @@ -1,4 +1,8 @@ class RecurringMeeting < ApplicationRecord + # Magical maximum of iterations + MAX_ITERATIONS = 1000 + # Magical maximum of interval, derived from other calendars + MAX_INTERVAL = 100 include ::Meeting::VirtualStartTime include Redmine::I18n @@ -7,15 +11,21 @@ class RecurringMeeting < ApplicationRecord validates_presence_of :start_time, :title, :frequency, :end_after validates_presence_of :end_date, if: -> { end_after_specific_date? } - validates_numericality_of :iterations, if: -> { end_after_iterations? } + validates_numericality_of :iterations, + only_integer: true, + greater_than_or_equal_to: 1, + less_than_or_equal_to: MAX_ITERATIONS, + if: -> { end_after_iterations? } validates_numericality_of :interval, only_integer: true, greater_than_or_equal_to: 1, + less_than_or_equal_to: MAX_INTERVAL, if: -> { !frequency_working_days? } validate :end_date_constraints, if: -> { end_after_specific_date? } + after_initialize :set_defaults after_save :unset_schedule enum frequency: { @@ -78,31 +88,38 @@ def schedule end end - def schedule_in_words # rubocop:disable Metrics/AbcSize - base = - case frequency - when "daily" - interval == 1 ? human_frequency : I18n.t("recurring_meeting.in_words.daily_interval", interval: interval.ordinalize) - when "working_days" - if interval == 1 - I18n.t("recurring_meeting.in_words.working_days") - else - I18n.t("recurring_meeting.in_words.working_days_interval", interval: interval.ordinalize) - end - when "weekly" - if interval == 1 - I18n.t("recurring_meeting.in_words.weekly", weekday:) - else - I18n.t("recurring_meeting.in_words.weekly_interval", interval: interval.ordinalize, weekday:) - end + def base_schedule + case frequency + when "daily" + if interval == 1 + human_frequency + else + I18n.t("recurring_meeting.in_words.daily_interval", interval:) + end + when "working_days" + I18n.t("recurring_meeting.in_words.working_days") + when "weekly" + if interval == 1 + I18n.t("recurring_meeting.in_words.weekly", weekday:) + else + I18n.t("recurring_meeting.in_words.weekly_interval", interval:, weekday:) end + end + end + def full_schedule_in_words I18n.t("recurring_meeting.in_words.full", - base:, + base: base_schedule, time: format_time(start_time, include_date: false), end_date: format_date(last_occurrence)) end + def human_frequency_schedule + I18n.t("recurring_meeting.in_words.frequency", + base: base_schedule, + time: format_time(start_time, include_date: false)) + end + def scheduled_occurrences(limit:) schedule.next_occurrences(limit, Time.current) end @@ -187,4 +204,8 @@ def count_rule(rule) rule.until(end_date.to_time(:utc)) end end + + def set_defaults + self.end_date ||= 1.year.from_now + end end diff --git a/modules/meeting/config/locales/crowdin/af.yml b/modules/meeting/config/locales/crowdin/af.yml index fdcc3bd00f65..e03952906f4f 100644 --- a/modules/meeting/config/locales/crowdin/af.yml +++ b/modules/meeting/config/locales/crowdin/af.yml @@ -53,14 +53,15 @@ af: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ af: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ af: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ af: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ af: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ af: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/ar.yml b/modules/meeting/config/locales/crowdin/ar.yml index 2ab800bb1c54..a611c21c6209 100644 --- a/modules/meeting/config/locales/crowdin/ar.yml +++ b/modules/meeting/config/locales/crowdin/ar.yml @@ -57,14 +57,15 @@ ar: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "ليس وقتًا صالحًا. التصميم المطلوب: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "جدول الأعمال" meeting_minutes: "محضر الجلسة" @@ -98,7 +99,7 @@ ar: label_meeting: "الاجتماع" label_meeting_plural: "الاجتماعات" label_meeting_new: "اجتماع جديد" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -143,8 +144,10 @@ ar: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "إرسال للمراجعة" label_icalendar: "إرسال iCalendar" @@ -185,10 +188,11 @@ ar: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "نسخ من الاجتماع #%{id}" meeting_section: @@ -197,9 +201,6 @@ ar: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -223,15 +224,15 @@ ar: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "تم إرسال الإشعار بنجاح" notice_timezone_missing: لم يتم تعيين المنطقة الزمنية و%{zone} مُفترض. لاختيار منطقتك الزمنية، من فضلك اضغط هنا. diff --git a/modules/meeting/config/locales/crowdin/az.yml b/modules/meeting/config/locales/crowdin/az.yml index 1aa3a66d8627..2725b3ece425 100644 --- a/modules/meeting/config/locales/crowdin/az.yml +++ b/modules/meeting/config/locales/crowdin/az.yml @@ -53,14 +53,15 @@ az: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ az: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ az: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ az: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ az: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ az: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/be.yml b/modules/meeting/config/locales/crowdin/be.yml index b7fb33f441ef..76b08f5668c9 100644 --- a/modules/meeting/config/locales/crowdin/be.yml +++ b/modules/meeting/config/locales/crowdin/be.yml @@ -55,14 +55,15 @@ be: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -96,7 +97,7 @@ be: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -141,8 +142,10 @@ be: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -183,10 +186,11 @@ be: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -195,9 +199,6 @@ be: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ be: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/bg.yml b/modules/meeting/config/locales/crowdin/bg.yml index f037b41c9552..5d379e1086d2 100644 --- a/modules/meeting/config/locales/crowdin/bg.yml +++ b/modules/meeting/config/locales/crowdin/bg.yml @@ -53,14 +53,15 @@ bg: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "не е валидно време. Задължителен формат: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Среща (динамична)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Точка от дневния ред" meeting_agenda: "Дневен ред" meeting_minutes: "Минути" @@ -94,7 +95,7 @@ bg: label_meeting: "среща" label_meeting_plural: "Срещи" label_meeting_new: "Нова среща" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ bg: label_past_meetings_short: "Предишен" label_involvement: "Участие" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Минали покани" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Изпращане за преглед" label_icalendar: "Изпращане на iCalendar" @@ -181,10 +184,11 @@ bg: label_mail_all_participants: "Изпрати имейл до всички участници" types: classic: "Класически" - classic_text: "Организирайте срещата си в текстова програма и протокол, които могат да се форматират." - structured: "Динамичен" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Организирайте срещата си като списък с точки от дневния ред, като по желание ги свържете с работен пакет." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Копирането на среща понастоящем не копира свързаните с нея точки от дневния ред, а само подробностите." copied: "Копирано от среща #%{id}" meeting_section: @@ -193,9 +197,6 @@ bg: placeholder_title: "New section" empty_text: "Завлечете елементите тук, или създайте нов елемент" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ bg: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/ca.yml b/modules/meeting/config/locales/crowdin/ca.yml index 4d3430d54136..b0b3a1079914 100644 --- a/modules/meeting/config/locales/crowdin/ca.yml +++ b/modules/meeting/config/locales/crowdin/ca.yml @@ -53,14 +53,15 @@ ca: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "no és una hora vàlida. El format requerit és: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Reunió (dinàmica)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Element d'agenda" meeting_agenda: "Agenda" meeting_minutes: "Acta" @@ -94,7 +95,7 @@ ca: label_meeting: "Reunió" label_meeting_plural: "Reunions" label_meeting_new: "Nova reunió" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ ca: label_past_meetings_short: "Passades" label_involvement: "Implicació" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Invitacions passades" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Envia per revisar" label_icalendar: "Envia iCalendar" @@ -181,10 +184,11 @@ ca: label_mail_all_participants: "Envia un correu a tots els participants" types: classic: "Clàssica" - classic_text: "Organitzeu la vostra reunió en una agenda i un protocol de text formatejables." - structured: "Dinàmica" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organitza la vostra reunió com una llista d'elements de l'agenda, enllaçant-los opcionalment a un paquet de treball." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Actualment en copiar una reunió no es copiaran els elements associats a l'agenda de la reunió, només els detalls." copied: "Copiat de la reunió #%{id}" meeting_section: @@ -193,9 +197,6 @@ ca: placeholder_title: "Nova secció" empty_text: "Arrossega els elements aquí o crea un de nou" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ ca: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notificació enviada correctament" notice_timezone_missing: No s'ha configurat la zona horària i la %{zone} és assumida. Per seleccionar la teva zona horària, si us plau, fes clic aquí. diff --git a/modules/meeting/config/locales/crowdin/ckb-IR.yml b/modules/meeting/config/locales/crowdin/ckb-IR.yml index f248cb2efab6..7b5e3a149d2e 100644 --- a/modules/meeting/config/locales/crowdin/ckb-IR.yml +++ b/modules/meeting/config/locales/crowdin/ckb-IR.yml @@ -53,14 +53,15 @@ ckb-IR: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ ckb-IR: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ ckb-IR: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ ckb-IR: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ ckb-IR: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ ckb-IR: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/cs.yml b/modules/meeting/config/locales/crowdin/cs.yml index dffc110eea79..10fad8337ed8 100644 --- a/modules/meeting/config/locales/crowdin/cs.yml +++ b/modules/meeting/config/locales/crowdin/cs.yml @@ -55,14 +55,15 @@ cs: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "není platný čas. Požadovaný formát: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "" + structured_meeting: "One-time meeting" meeting_agenda_item: "Pořad jednání" meeting_agenda: "Agenda" meeting_minutes: "Zápis" @@ -96,7 +97,7 @@ cs: label_meeting: "Schůzka" label_meeting_plural: "Schůzky" label_meeting_new: "Nová schůzka" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Vytvořit schůzku" label_meeting_copy: "Kopírovat schůzku" @@ -141,8 +142,10 @@ cs: label_past_meetings_short: "Minulé" label_involvement: "Zapojení" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Minulé pozvánky" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Odeslat k posouzení" label_icalendar: "Odeslat iCalendar" @@ -183,10 +186,11 @@ cs: label_mail_all_participants: "Poslat e-mail všem účastníkům" types: classic: "Klasické" - classic_text: "Uspořádat schůzku do formátů textového programu a protokolu." - structured: "Dynamický" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Uspořádat schůzku jako seznam bodů pořadu jednání, případně je propojit s pracovním balíčkem." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Kopírování schůzky v současné době nezkopíruje související body pořadu jednání, jen podrobnosti" copied: "Zkopírováno ze schůzky #%{id}" meeting_section: @@ -195,9 +199,6 @@ cs: placeholder_title: "Nová sekce" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ cs: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Oznámení bylo úspěšně odesláno" notice_timezone_missing: Není nastaveno žádné časové pásmo a předpokládá se %{zone} . Chcete-li vybrat časové pásmo, klikněte prosím zde. diff --git a/modules/meeting/config/locales/crowdin/da.yml b/modules/meeting/config/locales/crowdin/da.yml index 2f5cca5c8c35..177e036e0cc8 100644 --- a/modules/meeting/config/locales/crowdin/da.yml +++ b/modules/meeting/config/locales/crowdin/da.yml @@ -53,14 +53,15 @@ da: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Dagsorden" meeting_minutes: "Referat" @@ -94,7 +95,7 @@ da: label_meeting: "Møde" label_meeting_plural: "Møder" label_meeting_new: "Nyt møde" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ da: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send til vurdering" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ da: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ da: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ da: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Påmindelse er afsendt" notice_timezone_missing: Der er ikke sat en tidszone og systemet har valgt %{zone}. For at vælge din egen tidszone, klik venligst her. diff --git a/modules/meeting/config/locales/crowdin/de.yml b/modules/meeting/config/locales/crowdin/de.yml index 57d5376ac760..cd6175d98709 100644 --- a/modules/meeting/config/locales/crowdin/de.yml +++ b/modules/meeting/config/locales/crowdin/de.yml @@ -53,14 +53,15 @@ de: recurring_meeting: frequency: "Häufigkeit" interval: "Intervall" - end_after: "Ende nach" + start_date: "Started am" + end_after: "Serie endet nach" iterations: "Ereignisse" errors: messages: invalid_time_format: "ist keine gültige Zeit. Erforderliches Format: HH:MM" models: recurring_meeting: "Wiederkehrende Besprechung" - structured_meeting: "Besprechung (dynamisch)" + structured_meeting: "Einmalige Besprechung" meeting_agenda_item: "Tagesordnungspunkt" meeting_agenda: "Agenda" meeting_minutes: "Protokoll" @@ -94,8 +95,8 @@ de: label_meeting: "Besprechung" label_meeting_plural: "Besprechungen" label_meeting_new: "Neue Besprechung" - label_meeting_new_dynamic: "Neue dynamische Besprechung" - label_meeting_new_recurring: "Neue wiederkehrende Besprechung" + label_meeting_new_dynamic: "Neue einmalige Besprechung" + label_meeting_new_recurring: "Neue Terminserie" label_meeting_create: "Besprechung erstellen" label_meeting_copy: "Besprechung kopieren" label_meeting_edit: "Besprechung bearbeiten" @@ -110,27 +111,27 @@ de: label_meeting_date_and_time: "Datum und Zeit" label_meeting_diff: "Differenz" label_recurring_meeting: "Wiederkehrende Besprechung" - label_recurring_meeting_part_of: "Teil einer Besprechungsreihe" - label_recurring_meeting_new: "Neue wiederkehrende Besprechung" + label_recurring_meeting_part_of: "Teil einer Terminserie" + label_recurring_meeting_new: "Neue Terminserie" label_recurring_meeting_plural: "Wiederkehrende Besprechungen" label_template: "Vorlage" - label_recurring_meeting_view: "Besprechungsreihe ansehen" + label_recurring_meeting_view: "Terminserie ansehen" label_recurring_meeting_create: "Aus Vorlage erstellen" - label_recurring_meeting_copy: "Copy as one-off" - label_recurring_meeting_cancel: "Dieses Ereignis abbrechen" - label_recurring_meeting_delete: "Ereignis löschen" + label_recurring_meeting_copy: "Als einmalige Besprechung kopieren" + label_recurring_meeting_cancel: "Diese Besprechung absagen" + label_recurring_meeting_delete: "Besprechung löschen" label_recurring_meeting_delete_confirmation: > - Diese Besprechung ist Teil einer Serie namens %{name}. Dadurch wird nur dieses bestimmte Ereignis und nicht die gesamte Serie gelöscht. Möchten Sie fortfahren? + Diese Besprechung ist Teil der Terminserie %{name}. Dadurch wird nur dieses bestimmte Ereignis und nicht die gesamte Serie gelöscht. Möchten Sie fortfahren? label_recurring_occurrence_delete_confirmation: > - Alle Besprechungsinformationen, die nicht in der Vorlage enthalten sind, gehen verloren. Möchten Sie fortfahren? - label_recurring_meeting_restore: "Dieses Ereignis wiederherstellen" - label_recurring_meeting_more: "There are %{count} more scheduled meetings (%{schedule})." - label_recurring_meeting_more_singular: "There is %{count} more scheduled meeting (%{schedule})." - label_recurring_meeting_more_past: "There are %{count} more past meetings." - label_recurring_meeting_more_past_singular: "There is %{count} more past meeting." - label_recurring_meeting_show_more: "Show more" - label_recurring_meeting_series_edit: "Besprechungsreihe bearbeiten" - label_recurring_meeting_series_delete: "Besprechungsreihe löschen" + Alle Inhalte der Besprechung, die nicht aus der Vorlage stammen, werden gelöscht werden. Möchten Sie fortfahren? + label_recurring_meeting_restore: "Dieses Vorkommen wiederherstellen" + label_recurring_meeting_more: "Es gibt %{count} folgende Besprechungen (%{schedule})." + label_recurring_meeting_more_singular: "Es gibt %{count} folgende Besprechung (%{schedule})." + label_recurring_meeting_more_past: "Es gibt %{count} weitere vergangene Besprechungen." + label_recurring_meeting_more_past_singular: "Es gibt %{count} weitere vergangene Besprechung." + label_recurring_meeting_show_more: "Mehr anzeigen" + label_recurring_meeting_series_edit: "Terminserie bearbeiten" + label_recurring_meeting_series_delete: "Terminserie löschen" label_my_meetings: "Meine Besprechungen" label_all_meetings: "Alle Besprechungen" label_upcoming_meetings: "Zukünftige Meetings" @@ -139,22 +140,24 @@ de: label_past_meetings_short: "Vergangen" label_involvement: "Beteiligt" label_invitations: "Einladungen" + label_invited_user: "Eingeladen" label_past_invitations: "Vergangene Einladungen" label_attended: "Teilgenommen" + label_attended_user: "Teilgenommen" label_created_by_me: "Von mir erstellt" label_notify: "Zur Einsicht verschicken" label_icalendar: "iCalendar senden" label_icalendar_download: "iCalendar-Termin herunterladen" - label_view_meeting_series: "Besprechungsreihe ansehen" - label_meeting_series: "Besprechungsreihe" + label_view_meeting_series: "Terminserie ansehen" + label_meeting_series: "Terminserien" label_version: "Version" label_time_zone: "Zeitzone" label_start_date: "Beginn" meeting: participants: - template: "Diese Teilnehmer werden automatisch zu allen zukünftigen Besprechungen eingeladen, sobald sie erstellt werden." + template: "Diese Teilnehmer werden automatisch zu allen zukünftigen Besprechungen eingeladen, sobald diese erstellt werden." attachments: - template: "Die angehängten Dateien werden in alle künftigen Besprechungen dieser Reihe einbezogen." + template: "Die angehängten Dateien werden in alle künftigen Besprechungen dieser Terminserie einbezogen." text: "Angehängte Dateien sind für alle Teilnehmer der Besprechung verfügbar. Sie können diese auch per Drag-and-drop in die Notizen der Tagesordnungspunkte ziehen." copy: title: "Besprechung kopieren: %{title}" @@ -181,9 +184,10 @@ de: label_mail_all_participants: "E-Mail an alle Teilnehmer senden" types: classic: "Klassisch" - classic_text: "Organisieren Sie Ihr Meeting in einer formatierbaren textbasierter Agenda und zugehöriges Protokoll." - structured: "Dynamisch" - recurring: "Wiederkehrend" + classic_text: "Organisieren Sie Ihre Besprechung und zugehöriges Protokoll in einem einzelnen Notizblock." + structured: "Einmalig" + recurring: "Terminserie" + recurring_text: "Erstellen Sie eine Terminserie mit einer dynamischen Vorlage und wiederkehrenden Besprechungen." structured_text: "Organisieren Sie Ihr Meeting als strukturierte Liste von Einträgen und verknüpfen Sie diese optional mit einem Arbeitspaket." structured_text_copy: "Das Kopieren einer Besprechung kopiert derzeit nicht die zugehörigen Tagesordnungspunkte, sondern nur dessen Details" copied: "Kopiert von Meeting #%{id}" @@ -193,42 +197,39 @@ de: placeholder_title: "Neuer Abschnitt" empty_text: "Neue Agendapunkte hierhin bewegen oder neu erstellen" recurring_meeting: - interval: - instructions: > - Geben Sie die Anzahl der Tage oder Wochen zwischen den einzelnen Ereignissen an. occurrence: - infoline: "Diese Besprechung ist Teil einer wiederkehrenden Besprechungsreihe." - error_no_next: "There is no next occurrence for this meeting." - first_already_exists: "The first occurrence of this meeting series is already instantiated." + infoline: "Diese Besprechung ist Teil einer Terminserie." + error_no_next: "Es gibt keinen nächsten Termin für diese Serie." + first_already_exists: "Das erste Vorkommen dieser Terminserie wurde bereits angelegt." first_created: > - The first meeting has been successfuly created from template. All future meetings will be created automatically at the time of the previous occurrence. + Die erste Besprechung wurde erfolgreich aus der Vorlage erstellt. Weitere werden automatisch zu dem Zeitpunkt erstellt, wenn die vorhergehende Besprechung startet. template: button_finalize: "Vorlage fertigstellen" - blank_title: "Your meeting series template is empty" + blank_title: "Die Vorlage für die wiederkehrenden Besprechungen ist leer" description: > - This template will be used whenever new meetings in the series get created. You can add agenda items, participants, and attachments to this template. + Diese Vorlage wird immer dann verwendet, wenn neue Besprechungen der Terminserie erstellt werden. Sie können zu dieser Vorlage Tagesordnungspunkte, Teilnehmer und Anhänge hinzufügen. blankslate_finalize: > - When you're done preparing this template, click the '%{button_title}' button above to finish the setup and schedule the first meeting of the series. - label_view_template: "Vorlagen ansehen" + Wenn Sie mit der Vorbereitung dieser Vorlage fertig sind, klicken Sie oben auf die Schaltfläche '%{button_title}', um die Einrichtung abzuschließen und die erste Besprechung der Terminserie anzulegen. + label_view_template: "Vorlage ansehen" label_edit_template: "Vorlage bearbeiten" banner_html: > - You are currently editing a template of a meeting series: %{link}. Every new occurrence of a meeting in the series will use this template. Changes will not affect past or already created meetings. + Sie bearbeiten gerade eine Vorlage einer Terminserie: %{link}. Jede neue Besprechung der Serie kopiert diese Vorlage. Änderungen wirken sich nicht auf frühere oder bereits erstellte Besprechungen aus. frequency: every_weekday: "Jeden %{day_of_the_week}" daily: "Täglich" - working_days: "Every working day" + working_days: "An Arbeitstagen" weekly: "Wöchentlich" end_after: - specific_date: "Ein bestimmtes Datum" - iterations: "Eine Reihe von Ereignissen" + specific_date: "einem bestimmten Datum" + iterations: "nach Anzahl von Ereignissen" starts: "Beginnt" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Alle %{interval} Tage" working_days: "Jeden Arbeitstag" - working_days_interval: "Every %{interval} working day" - weekly: "Wöchentlich am %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" - full: "%{base} at %{time}, ends on %{end_date}" + weekly: "Jede Woche am %{weekday}" + weekly_interval: "Alle %{interval} Wochen am %{weekday}" + frequency: "%{base} um %{time}" + full: "%{base} um %{time}, endet %{end_date}" notice_successful_notification: "Benachrichtigung erfolgreich gesendet" notice_timezone_missing: Keine Zeitzone eingestellt und daher %{zone} angenommen. Um Ihre Zeitzone einzustellen, klicken Sie bitte hier. notice_meeting_updated: "Diese Seite wurde von einem anderen Benutzer verändert. Laden Sie neu, um die Änderungen zu sehen." @@ -281,7 +282,7 @@ de: text_deleted_agenda_item: 'Gelöschter Tagesordnungspunkt' label_initial_meeting_details: "Besprechung" label_meeting_details: "Besprechungsdetails" - label_meeting_series_details: "Meeting series details" + label_meeting_series_details: "Details der Terminserie" label_meeting_details_edit: "Besprechungsdetails bearbeiten" label_meeting_state: "Besprechungsstatus" label_meeting_state_open: "Offen" @@ -290,7 +291,7 @@ de: label_meeting_state_closed_html: "Geschlossen" label_meeting_state_agenda_created: "Tagesordnung erstellt" label_meeting_state_scheduled: "Geplant" - label_meeting_state_cancelled: "Abgebrochen" + label_meeting_state_cancelled: "Abgesagt" label_meeting_state_skipped: "Übersprungen" label_meeting_reopen_action: "Besprechung wiedereröffnen" label_meeting_close_action: "Besprechung schließen" diff --git a/modules/meeting/config/locales/crowdin/el.yml b/modules/meeting/config/locales/crowdin/el.yml index 99319a025cd0..2f282756b054 100644 --- a/modules/meeting/config/locales/crowdin/el.yml +++ b/modules/meeting/config/locales/crowdin/el.yml @@ -53,14 +53,15 @@ el: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "δεν είναι έγκυρη ώρα. Απαιτούμενη μορφοποίηση: ΩΩ:ΛΛ" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Ατζέντα" meeting_minutes: "Πρακτικά" @@ -94,7 +95,7 @@ el: label_meeting: "Συνάντηση" label_meeting_plural: "Συναντήσεις" label_meeting_new: "Νέα Συνάντηση" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ el: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Αποστολή για αναθεώρηση" label_icalendar: "Αποστολή στο iCalendar" @@ -181,10 +184,11 @@ el: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Αντιγράφηκε από τη Συνάντηση #%{id}" meeting_section: @@ -193,9 +197,6 @@ el: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ el: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Η ειδοποίηση απεστάλη επιτυχώς" notice_timezone_missing: Δεν έχει οριστεί ζώνη ώρας και θεωρήθηκε η %{zone}. Για να επιλέξετε την ζώνη ώρας σας, παρακαλούμε κάντε κλικ εδώ. diff --git a/modules/meeting/config/locales/crowdin/eo.yml b/modules/meeting/config/locales/crowdin/eo.yml index 30dd67c08c6b..df4be1349619 100644 --- a/modules/meeting/config/locales/crowdin/eo.yml +++ b/modules/meeting/config/locales/crowdin/eo.yml @@ -53,14 +53,15 @@ eo: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ eo: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ eo: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ eo: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ eo: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ eo: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/es.yml b/modules/meeting/config/locales/crowdin/es.yml index 4c1db3bb779f..45f20d9298ad 100644 --- a/modules/meeting/config/locales/crowdin/es.yml +++ b/modules/meeting/config/locales/crowdin/es.yml @@ -53,14 +53,15 @@ es: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "no es una hora válida. Formato requerido: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Reunión (dinámico)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Puntos de Agenda" meeting_agenda: "Agenda" meeting_minutes: "Minutas" @@ -94,7 +95,7 @@ es: label_meeting: "Reunión" label_meeting_plural: "Reuniones" label_meeting_new: "Nueva reunión" - label_meeting_new_dynamic: "Nueva reunión dinámica" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Crear reunión" label_meeting_copy: "Copiar reunión" @@ -139,8 +140,10 @@ es: label_past_meetings_short: "Pasado" label_involvement: "Implicación" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Invitaciones pasadas" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Enviar para revisión" label_icalendar: "Enviar iCalendar" @@ -181,10 +184,11 @@ es: label_mail_all_participants: "Enviar email a todos los participantes" types: classic: "Clásico" - classic_text: "Organice su reunión en un formato de agenda de texto y protocolos." - structured: "Dinámico" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organice su reunión como una lista de temas del orden del día, enlazándolos opcionalmente a un paquete de trabajo." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copiar una reunión no copiará actualmente los elementos asociados de la agenda de la reunión, solo los detalles" copied: "Copiado de la reunión %{id}" meeting_section: @@ -193,9 +197,6 @@ es: placeholder_title: "Nueva sección" empty_text: "Arrastre los elementos aquí o cree uno nuevo" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ es: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notificación enviada correctamente" notice_timezone_missing: No se ha establecido zona horaria y se asume %{zone}. Para elegir su zona horaria, por favor, haga clic aquí. diff --git a/modules/meeting/config/locales/crowdin/et.yml b/modules/meeting/config/locales/crowdin/et.yml index 6581c5c0dafc..9b2af6cdd074 100644 --- a/modules/meeting/config/locales/crowdin/et.yml +++ b/modules/meeting/config/locales/crowdin/et.yml @@ -53,14 +53,15 @@ et: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Päevakava" meeting_minutes: "Minutit" @@ -94,7 +95,7 @@ et: label_meeting: "Koosolek" label_meeting_plural: "Koosolekud" label_meeting_new: "Uus koosolek" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ et: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Saada ülevaatamisele" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ et: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ et: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ et: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/eu.yml b/modules/meeting/config/locales/crowdin/eu.yml index 4116ef989587..d0913cf10cb3 100644 --- a/modules/meeting/config/locales/crowdin/eu.yml +++ b/modules/meeting/config/locales/crowdin/eu.yml @@ -53,14 +53,15 @@ eu: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "ez da baliozko ordua. Eskatzen den formatua: OO:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Aktak" @@ -94,7 +95,7 @@ eu: label_meeting: "Hitzordua" label_meeting_plural: "Hitzorduak" label_meeting_new: "Hitzordu berria" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ eu: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Berrikustera bidali" label_icalendar: "Bidali iEgutegia" @@ -181,10 +184,11 @@ eu: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "#%{id} Hitzordutik kopiatua" meeting_section: @@ -193,9 +197,6 @@ eu: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ eu: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Jakinarazpena ondo bidali da" notice_timezone_missing: Ez da ordu-eremurik zehaztu eta %{zone} hartu da ontzat. Ordu-eremua aukeratzeko klikatu hemen, mesedez. diff --git a/modules/meeting/config/locales/crowdin/fa.yml b/modules/meeting/config/locales/crowdin/fa.yml index 9266b46757e0..9b7cbb7b5967 100644 --- a/modules/meeting/config/locales/crowdin/fa.yml +++ b/modules/meeting/config/locales/crowdin/fa.yml @@ -53,14 +53,15 @@ fa: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "دستور کار" meeting_minutes: "دقیقه ها" @@ -94,7 +95,7 @@ fa: label_meeting: "جلسه" label_meeting_plural: "جلسات" label_meeting_new: "ایجاد جلسه" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ fa: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "ارسال برای بازبینی" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ fa: label_mail_all_participants: "Send email to all participants" types: classic: "کلاسیک" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ fa: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ fa: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/fi.yml b/modules/meeting/config/locales/crowdin/fi.yml index ff1a99fab27e..64ce4d80a0fa 100644 --- a/modules/meeting/config/locales/crowdin/fi.yml +++ b/modules/meeting/config/locales/crowdin/fi.yml @@ -53,14 +53,15 @@ fi: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "ei ole kelvollinen aika. Vaadittava muoto: TT:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Esityslista" meeting_minutes: "Pöytäkirja" @@ -94,7 +95,7 @@ fi: label_meeting: "Kokous" label_meeting_plural: "Kokoukset" label_meeting_new: "Uusi kokous" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ fi: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Lähetä tarkistettavaksi" label_icalendar: "Lähetä iCalendar" @@ -181,10 +184,11 @@ fi: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Kopioitu kokouksesta #%{id}" meeting_section: @@ -193,9 +197,6 @@ fi: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ fi: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Ilmoituksen lähettäminen onnistui" notice_timezone_missing: Aikavyöhykettä ei ole määritetty, joten oletuksena on %{zone}. Valitaksesi aikavyöhykkeen, klikkaa tästä. diff --git a/modules/meeting/config/locales/crowdin/fil.yml b/modules/meeting/config/locales/crowdin/fil.yml index fbbefa58b540..82dfec15aede 100644 --- a/modules/meeting/config/locales/crowdin/fil.yml +++ b/modules/meeting/config/locales/crowdin/fil.yml @@ -53,14 +53,15 @@ fil: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "ay hindi balidong oras. Ang hinihinging format ay: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ fil: label_meeting: "Pagpupulong" label_meeting_plural: "Mga Pagpupulong" label_meeting_new: "Bagong Pagpupulong" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ fil: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Ipadala para sa pagsusuri" label_icalendar: "Ipadala ang iCalendar" @@ -181,10 +184,11 @@ fil: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ fil: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ fil: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Ang abiso ay naipadala ng matagumpay" notice_timezone_missing: Walang nakatakdang time zone at ang %{zone} ay ipinagpalagay na siyang time zone. Para piliin ang iyong time zone, mangyaring magclick dito. diff --git a/modules/meeting/config/locales/crowdin/fr.yml b/modules/meeting/config/locales/crowdin/fr.yml index b26da98058ad..de0207ea4662 100644 --- a/modules/meeting/config/locales/crowdin/fr.yml +++ b/modules/meeting/config/locales/crowdin/fr.yml @@ -53,14 +53,15 @@ fr: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "n’est pas une heure valide. Format requis : HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Réunion (dynamique)" + structured_meeting: "One-time meeting" meeting_agenda_item: "" meeting_agenda: "Ordre du jour" meeting_minutes: "Compte-rendu" @@ -94,7 +95,7 @@ fr: label_meeting: "Réunion" label_meeting_plural: "Réunions" label_meeting_new: "Nouvelle réunion" - label_meeting_new_dynamic: "Nouvelle réunion dynamique" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Créer une réunion" label_meeting_copy: "Copier la réunion" @@ -139,8 +140,10 @@ fr: label_past_meetings_short: "Passé" label_involvement: "Participation" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Invitations passées" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Envoyer pour révision" label_icalendar: "Envoyer iCalendar" @@ -181,10 +184,11 @@ fr: label_mail_all_participants: "Envoyer un mail à tous les participants" types: classic: "Classique" - classic_text: "Organisez votre réunion sous la forme d'un ordre du jour et d'un protocole en texte formatable." - structured: "Dynamique" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organisez votre réunion sous la forme d'une liste de points à l'ordre du jour, en les reliant éventuellement à des lots de travaux." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Actuellement, la copie d'une réunion n'entraîne pas la copie des points de l'ordre du jour de la réunion, mais uniquement des détails." copied: "Copié depuis la réunion #%{id}" meeting_section: @@ -193,9 +197,6 @@ fr: placeholder_title: "Nouvelle section" empty_text: "Faites glisser des éléments ici ou créez-en un nouveau" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ fr: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification envoyée avec succès" notice_timezone_missing: Aucun fuseau horaire n'est défini et %{zone} est supposé. Pour choisir votre fuseau horaire, veuillez cliquer ici. diff --git a/modules/meeting/config/locales/crowdin/he.yml b/modules/meeting/config/locales/crowdin/he.yml index bdfeab834b7a..8fb2cec56f8f 100644 --- a/modules/meeting/config/locales/crowdin/he.yml +++ b/modules/meeting/config/locales/crowdin/he.yml @@ -55,14 +55,15 @@ he: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "תבנית הזמן אינה תקינה. התבנית הנדרשת היא: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "סדר היום" meeting_minutes: "דקות" @@ -96,7 +97,7 @@ he: label_meeting: "פגישה" label_meeting_plural: "פגישות" label_meeting_new: "פגישה חדשה" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -141,8 +142,10 @@ he: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "שלח לבדיקה" label_icalendar: "שלח iCalendar" @@ -183,10 +186,11 @@ he: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -195,9 +199,6 @@ he: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ he: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "הודעה נשלחה בהצלחה" notice_timezone_missing: אין איזור זמן מוגדר, ההערכה היא %{zone}. כדי לבחור את איזור הזמן שלך, אנא לחץ כאן. diff --git a/modules/meeting/config/locales/crowdin/hi.yml b/modules/meeting/config/locales/crowdin/hi.yml index 7769810c5b23..e08421129302 100644 --- a/modules/meeting/config/locales/crowdin/hi.yml +++ b/modules/meeting/config/locales/crowdin/hi.yml @@ -53,14 +53,15 @@ hi: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ hi: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ hi: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ hi: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ hi: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ hi: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/hr.yml b/modules/meeting/config/locales/crowdin/hr.yml index 3a6255163cde..b34d29af1ec8 100644 --- a/modules/meeting/config/locales/crowdin/hr.yml +++ b/modules/meeting/config/locales/crowdin/hr.yml @@ -54,14 +54,15 @@ hr: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Dnevni red" meeting_minutes: "Minute" @@ -95,7 +96,7 @@ hr: label_meeting: "Sastanak" label_meeting_plural: "Sastanci" label_meeting_new: "Novi sastanak" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -140,8 +141,10 @@ hr: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Šalji na pregled" label_icalendar: "Send iCalendar" @@ -182,10 +185,11 @@ hr: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -194,9 +198,6 @@ hr: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -220,15 +221,15 @@ hr: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notifikacija uspješno poslana" notice_timezone_missing: Vremenska zona nije postavljena na osnovu zamišljene %{zone} zone. Da bi ste odabrali vremensku zonu molim vas kliknite ovdje. diff --git a/modules/meeting/config/locales/crowdin/hu.yml b/modules/meeting/config/locales/crowdin/hu.yml index 805de8ce2826..e52f8a9360f7 100644 --- a/modules/meeting/config/locales/crowdin/hu.yml +++ b/modules/meeting/config/locales/crowdin/hu.yml @@ -53,14 +53,15 @@ hu: recurring_meeting: frequency: "Gyakoriság" interval: "Időköz" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Előfordulások" errors: messages: invalid_time_format: "nem egy érvényes időpont. Előírt formátum: óó:pp" models: recurring_meeting: "Ismétlődő megbeszélés" - structured_meeting: "Megbeszélés (dinamikus)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Napirendi pont" meeting_agenda: "Napirend" meeting_minutes: "Jegyzőkönyv" @@ -94,7 +95,7 @@ hu: label_meeting: "Megbeszélés" label_meeting_plural: "Megbeszélések" label_meeting_new: "Új megbeszélés" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ hu: label_past_meetings_short: "Korábbi" label_involvement: "Bevonás " label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Korábbi meghívások" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Küldés véleményezésre" label_icalendar: "iCalendar küldése" @@ -181,10 +184,11 @@ hu: label_mail_all_participants: "Email küldése minden résztvevőnek" types: classic: "Szokásos" - classic_text: "Szervezd meg a találkozódat formázott szöveges napirendben és protokollban." - structured: "Dinamikus" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Szervezd meg a találkozódat napirendi pontokkal, melyeket opcionálisan munkacsomagokhoz rendelhetsz." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "A megbeszélés másolásával jelnleg nem fogja átmásolni a hozzákapcsolt napirendi pontokat, csak a megbeszélés részleteit." copied: "#%{id} megbeszélésből másolva" meeting_section: @@ -193,9 +197,6 @@ hu: placeholder_title: "New section" empty_text: "Húzza ide az elemeket, vagy hozzon létre egy újat" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ hu: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Értesítés sikeresen kiküldve" notice_timezone_missing: Nincs időzóna beállítva, %{zone} a feltételezett. Időzóna beállításához kattintson ide. diff --git a/modules/meeting/config/locales/crowdin/id.yml b/modules/meeting/config/locales/crowdin/id.yml index f946dc1388a9..150e5940ea89 100644 --- a/modules/meeting/config/locales/crowdin/id.yml +++ b/modules/meeting/config/locales/crowdin/id.yml @@ -52,14 +52,15 @@ id: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "bukanlah waktu yang valid. Format seharusnya; JJ:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Rapat (dinamis)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Item agenda" meeting_agenda: "Agenda" meeting_minutes: "Laporan" @@ -93,7 +94,7 @@ id: label_meeting: "Rapat" label_meeting_plural: "Rapat" label_meeting_new: "Rapat Baru" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -138,8 +139,10 @@ id: label_past_meetings_short: "Lalu" label_involvement: "Keterlibatan" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Undangan sebelumnya" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Kirim untuk ulasan" label_icalendar: "Kirim iCalendar" @@ -180,10 +183,11 @@ id: label_mail_all_participants: "Kirim email ke semua peserta" types: classic: "Klasik" - classic_text: "Atur rapat Anda dalam agenda dan protokol teks yang dapat diformat." - structured: "Dinamis" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Disalin dari Meeting #%{id}" meeting_section: @@ -192,9 +196,6 @@ id: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -218,15 +219,15 @@ id: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Berhasil mengirim notifikasi" notice_timezone_missing: Tidak ada zona waktu yang ditetapkan sehingga diasumsikan %{zone}. Untuk memilih zona waktu, silakan mengeklik di sini. diff --git a/modules/meeting/config/locales/crowdin/it.yml b/modules/meeting/config/locales/crowdin/it.yml index dd53db5edc58..2b76d5a4aa02 100644 --- a/modules/meeting/config/locales/crowdin/it.yml +++ b/modules/meeting/config/locales/crowdin/it.yml @@ -53,14 +53,15 @@ it: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "non è un tempo valido. Formato richiesto: HH: mm" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Riunione (dinamica)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Attività" meeting_agenda: "Ordine del giorno" meeting_minutes: "Verbali" @@ -94,7 +95,7 @@ it: label_meeting: "Riunione" label_meeting_plural: "Riunioni" label_meeting_new: "Nuova riunione" - label_meeting_new_dynamic: "Nuova riunione dinamica" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Crea riunione" label_meeting_copy: "Copia riunione" @@ -139,8 +140,10 @@ it: label_past_meetings_short: "Passato" label_involvement: "Coinvolgimento" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Inviti passati" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Invia per revisione" label_icalendar: "Invia iCalendar" @@ -181,10 +184,11 @@ it: label_mail_all_participants: "Invia e-mail a tutti i partecipanti" types: classic: "Classica" - classic_text: "Organizza la tua riunione in un'agenda e un protocollo di testo formattabile." - structured: "Dinamica" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organizza la tua riunione come un elenco di punti all'ordine del giorno, collegandoli facoltativamente a un pacchetto di lavoro." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "La copia di una riunione al momento non copierà gli elementi dell'ordine del giorno della riunione, ma solo i dettagli" copied: "Copiato dalla riunione #%{id}" meeting_section: @@ -193,9 +197,6 @@ it: placeholder_title: "Nuova sezione" empty_text: "Trascina gli elementi qui o creane una nuova" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ it: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notifica inviata con successo" notice_timezone_missing: Nessun fuso orario è impostato e la %{zone} è un requisito necessario. Per scegliere il tuo fuso orario, fare clic qui. diff --git a/modules/meeting/config/locales/crowdin/ja.yml b/modules/meeting/config/locales/crowdin/ja.yml index 3762f391e5a9..db70e88621cf 100644 --- a/modules/meeting/config/locales/crowdin/ja.yml +++ b/modules/meeting/config/locales/crowdin/ja.yml @@ -52,14 +52,15 @@ ja: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "有効な時間ではありません。必要なフォーマット: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "会議(ダイナミック)" + structured_meeting: "One-time meeting" meeting_agenda_item: "議題項目" meeting_agenda: "アジェンダ" meeting_minutes: "議事録" @@ -93,7 +94,7 @@ ja: label_meeting: "会議" label_meeting_plural: "会議" label_meeting_new: "新しい会議" - label_meeting_new_dynamic: "新しいダイナミック会議" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "会議を作成" label_meeting_copy: "会議をコピー" @@ -138,8 +139,10 @@ ja: label_past_meetings_short: "過去" label_involvement: "関与" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "過去の招待状" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "レビュー用に送信" label_icalendar: "iCalendar を送信" @@ -180,10 +183,11 @@ ja: label_mail_all_participants: "すべての参加者にメールを送信" types: classic: "クラシック" - classic_text: "会議をテキスト形式で議題と議事録として整理します。" - structured: "ダイナミック" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "会議を議題項目のリストとして整理し、オプションでそれらをワークパッケージにリンクさせることができます。" + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "会議をコピーする場合、現在は関連する議題項目はコピーされず、詳細のみがコピーされます。" copied: "ミーティング#%{id} からコピーしました" meeting_section: @@ -192,9 +196,6 @@ ja: placeholder_title: "新しいセクション" empty_text: "アイテムをここにドラッグするか、新しいアイテムを作成してください" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -218,15 +219,15 @@ ja: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "通知が正常に送信されました" notice_timezone_missing: タイムゾーンが設定されていない場合、%{zone} が使用されます。タイムゾーンを選択するには、ここをクリックしてください。 diff --git a/modules/meeting/config/locales/crowdin/ka.yml b/modules/meeting/config/locales/crowdin/ka.yml index 2ded66d51f31..bdd3dd8c8624 100644 --- a/modules/meeting/config/locales/crowdin/ka.yml +++ b/modules/meeting/config/locales/crowdin/ka.yml @@ -53,14 +53,15 @@ ka: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "განრიგის პუნქტი" meeting_agenda: "დღის განრიგი" meeting_minutes: "წუთი" @@ -94,7 +95,7 @@ ka: label_meeting: "შეხვედრა" label_meeting_plural: "შეხვედრები" label_meeting_new: "ახალი შეხვედრა" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ ka: label_past_meetings_short: "წარს" label_involvement: "ჩარეულობა" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "'iCalendar'-ის გაგზავნა" @@ -181,10 +184,11 @@ ka: label_mail_all_participants: "Send email to all participants" types: classic: "კლასიკური" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "დინამიკური" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ ka: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ ka: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/kk.yml b/modules/meeting/config/locales/crowdin/kk.yml index 7fe8549dc432..820ab7290841 100644 --- a/modules/meeting/config/locales/crowdin/kk.yml +++ b/modules/meeting/config/locales/crowdin/kk.yml @@ -53,14 +53,15 @@ kk: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ kk: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ kk: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ kk: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ kk: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ kk: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/ko.yml b/modules/meeting/config/locales/crowdin/ko.yml index a079d8200319..19813af03d2f 100644 --- a/modules/meeting/config/locales/crowdin/ko.yml +++ b/modules/meeting/config/locales/crowdin/ko.yml @@ -52,14 +52,15 @@ ko: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "은(는) 유효한 시간이 아닙니다. 필요한 형식: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "미팅(다이내믹)" + structured_meeting: "One-time meeting" meeting_agenda_item: "의제 항목" meeting_agenda: "의제" meeting_minutes: "의사록" @@ -93,7 +94,7 @@ ko: label_meeting: "미팅" label_meeting_plural: "미팅" label_meeting_new: "새 미팅" - label_meeting_new_dynamic: "새로운 다이내믹 미팅" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "미팅 생성" label_meeting_copy: "미팅 복사" @@ -138,8 +139,10 @@ ko: label_past_meetings_short: "과거" label_involvement: "참여" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "과거 초대" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "검토를 위해 보내기" label_icalendar: "iCalendar 보내기" @@ -180,10 +183,11 @@ ko: label_mail_all_participants: "모든 참가자에게 이메일 보내기" types: classic: "클래식" - classic_text: "서식 지정 가능한 텍스트 의제 및 프로토콜로 미팅을 구성하세요." - structured: "다이내믹" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "미팅을 의제 항목 목록으로 구성하고, 선택적으로 작업 패키지에 연결합니다." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "미팅을 복사하면 관련 미팅 의제 항목은 현재 복사되지 않고 세부 정보만 복사됩니다" copied: "미팅 #%{id}에서 복사됨" meeting_section: @@ -192,9 +196,6 @@ ko: placeholder_title: "새 섹션" empty_text: "항목을 여기에 끌어오거나 새로 만들기" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -218,15 +219,15 @@ ko: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "알림이 전송됨" notice_timezone_missing: 표준 시간대가 설정되지 않았으며 %{zone}(으)로 간주됩니다. 해당 표준 시간대를 선택하려면 여기를 클릭하세요. diff --git a/modules/meeting/config/locales/crowdin/lt.yml b/modules/meeting/config/locales/crowdin/lt.yml index 6f227f929c4d..b7e47eeb8997 100644 --- a/modules/meeting/config/locales/crowdin/lt.yml +++ b/modules/meeting/config/locales/crowdin/lt.yml @@ -55,14 +55,15 @@ lt: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "netinkamas laikas. Reikalingas formatas: HH:MM (pvz.: 10:30)" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Susitikimas (dinaminis)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Darbotvarkės punktas" meeting_agenda: "Dienotvarkė" meeting_minutes: "Minutės" @@ -96,7 +97,7 @@ lt: label_meeting: "Pasitarimas" label_meeting_plural: "Pasitarimai" label_meeting_new: "Naujas pasitarimas" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -141,8 +142,10 @@ lt: label_past_meetings_short: "Buvę" label_involvement: "Įsitraukimas" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Ankstesni pakvietimai" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Siųsti peržiūrai" label_icalendar: "Siųsti iCalendar formatu" @@ -183,10 +186,11 @@ lt: label_mail_all_participants: "Siųsti e-laišką visiems dalyviams" types: classic: "Klasikinis" - classic_text: "Organizuokite jūsų susitikimą su formatuojamo teksto darbotvarke ir protokolu." - structured: "Dinaminis" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organizuokite jūsų susitikimą su darbotvarkės elementų sąrašu, pasirinktinai susiejant juos su darbo paketu." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Šiuo metu nukopijavus susitikimą, susiję susitikimo elmentai nebus kopijuojami, tik detalės." copied: "Nukopijuota iš susitikimo #%{id}" meeting_section: @@ -195,9 +199,6 @@ lt: placeholder_title: "Nauja skiltis" empty_text: "Tempkite elementus čia arba sukurtkite naują" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ lt: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Pranešimas sėkmingai išsiųstas" notice_timezone_missing: Laiko zona nenustatyta ir %{zone} zona yra rekomenduojama. Kad pasirinktumėte laiko zoną, paspauskite čia. diff --git a/modules/meeting/config/locales/crowdin/lv.yml b/modules/meeting/config/locales/crowdin/lv.yml index bfebfff98cf2..ce69da028054 100644 --- a/modules/meeting/config/locales/crowdin/lv.yml +++ b/modules/meeting/config/locales/crowdin/lv.yml @@ -54,14 +54,15 @@ lv: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "nav derīgs laiks. Vajadzīgais formāts: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Sanāksme (dinamiska)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Darba kārtības punkts" meeting_agenda: "Darba kārtība" meeting_minutes: "Protokols" @@ -95,7 +96,7 @@ lv: label_meeting: "Sanāksmes" label_meeting_plural: "Sanāksmes" label_meeting_new: "Jauna sanāksme" - label_meeting_new_dynamic: "Jauna dinamiska sanāksme" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Izveidot sanāksmi" label_meeting_copy: "Kopēt sanāksmi" @@ -140,8 +141,10 @@ lv: label_past_meetings_short: "Iepriekšējās" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Iepriekšējie ielūgumi" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -182,10 +185,11 @@ lv: label_mail_all_participants: "Send email to all participants" types: classic: "Klasisks" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -194,9 +198,6 @@ lv: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -220,15 +221,15 @@ lv: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Paziņojums veiksmīgi nosūtīts" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/mn.yml b/modules/meeting/config/locales/crowdin/mn.yml index aed61b941f4c..d1e8ade34c11 100644 --- a/modules/meeting/config/locales/crowdin/mn.yml +++ b/modules/meeting/config/locales/crowdin/mn.yml @@ -53,14 +53,15 @@ mn: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ mn: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ mn: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ mn: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ mn: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ mn: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/ms.yml b/modules/meeting/config/locales/crowdin/ms.yml index c2c2b149ea3c..892aacc4d6f3 100644 --- a/modules/meeting/config/locales/crowdin/ms.yml +++ b/modules/meeting/config/locales/crowdin/ms.yml @@ -52,14 +52,15 @@ ms: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "bukan masa yang sah. Format yang diperlukan: JJ:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Mesyuarat (dinamik)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Item agenda" meeting_agenda: "Agenda" meeting_minutes: "Minit mesyuarat" @@ -93,7 +94,7 @@ ms: label_meeting: "Mesyuarat" label_meeting_plural: "Mesyuarat-mesyuarat" label_meeting_new: "Mesyuarat Baharu" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -138,8 +139,10 @@ ms: label_past_meetings_short: "Lalu" label_involvement: "Penglibatan" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Jemputan yang lepas" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Hantar untuk semakan" label_icalendar: "Hantar iCalendar\n" @@ -180,10 +183,11 @@ ms: label_mail_all_participants: "Hantar e-mel kepada semua peserta" types: classic: "Klasik" - classic_text: "Aturkan mesyuarat anda dalam agenda teks yang boleh diformat dan diprotokol." - structured: "Dinamik" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Aturkan mesyuarat anda sebagai senarai butiran agenda, pautkannya ke pakej kerja secara pilihan." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Menyalin mesyuarat pada masa ini tidak akan menyalin item agenda mesyuarat yang berkaitan, hanya butiran sahaja" copied: "Disalin daripada Mesyuarat #%{id}" meeting_section: @@ -192,9 +196,6 @@ ms: placeholder_title: "Bahagian baharu" empty_text: "Tarik item ke sini atau cipta yang baharu" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -218,15 +219,15 @@ ms: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Pemberitahuan berjaya dihantar" notice_timezone_missing: Tiada zon waktu yang ditetapkan dan %{zone} adalah diandaikan. Untuk pilih zon waktu anda, sila klik sini. diff --git a/modules/meeting/config/locales/crowdin/ne.yml b/modules/meeting/config/locales/crowdin/ne.yml index 58ae1dba9e7b..3c15a9d4e6a9 100644 --- a/modules/meeting/config/locales/crowdin/ne.yml +++ b/modules/meeting/config/locales/crowdin/ne.yml @@ -53,14 +53,15 @@ ne: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ ne: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ ne: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ ne: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ ne: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ ne: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/nl.yml b/modules/meeting/config/locales/crowdin/nl.yml index 33a6107924d7..522ec086b3f5 100644 --- a/modules/meeting/config/locales/crowdin/nl.yml +++ b/modules/meeting/config/locales/crowdin/nl.yml @@ -51,16 +51,17 @@ nl: meeting_section: title: "Titel" recurring_meeting: - frequency: "Frequency" + frequency: "Frequentie" interval: "Interval" - end_after: "End after" - iterations: "Occurrences" + start_date: "Starts on" + end_after: "End series after" + iterations: "Voorvallen" errors: messages: invalid_time_format: "is geen geldige tijd. Vereist formaat: UH:MM" models: - recurring_meeting: "Recurring meeting" - structured_meeting: "Vergadering (dynamisch)" + recurring_meeting: "Terugkerende vergadering" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agendapunt" meeting_agenda: "Agenda" meeting_minutes: "Minuten" @@ -94,8 +95,8 @@ nl: label_meeting: "Vergadering" label_meeting_plural: "Vergaderingen" label_meeting_new: "Nieuwe vergadering" - label_meeting_new_dynamic: "Nieuwe dynamische vergadering" - label_meeting_new_recurring: "New recurring meeting" + label_meeting_new_dynamic: "New one-time meeting" + label_meeting_new_recurring: "Nieuwe terugkerende vergadering" label_meeting_create: "Creëer vergadering" label_meeting_copy: "Kopie vergadering" label_meeting_edit: "Vergadering bewerken" @@ -109,50 +110,52 @@ nl: label_meeting_date_time: "Datum/Tijd" label_meeting_date_and_time: "Datum en tijd" label_meeting_diff: "Diff" - label_recurring_meeting: "Recurring meeting" - label_recurring_meeting_part_of: "Part of a meeting series" - label_recurring_meeting_new: "New recurring meeting" - label_recurring_meeting_plural: "Recurring meetings" - label_template: "Template" - label_recurring_meeting_view: "View meeting series" - label_recurring_meeting_create: "Create from template" - label_recurring_meeting_copy: "Copy as one-off" - label_recurring_meeting_cancel: "Cancel this occurrence" - label_recurring_meeting_delete: "Delete occurrence" + label_recurring_meeting: "Terugkerende vergadering" + label_recurring_meeting_part_of: "Deel van een vergaderreeks" + label_recurring_meeting_new: "Nieuwe terugkerende vergadering" + label_recurring_meeting_plural: "Terugkerende vergaderingen" + label_template: "Sjabloon" + label_recurring_meeting_view: "Bekijk vergaderreeksen" + label_recurring_meeting_create: "Op basis van sjabloon maken" + label_recurring_meeting_copy: "Eenmalig kopiëren" + label_recurring_meeting_cancel: "Deze gebeurtenis annuleren" + label_recurring_meeting_delete: "Gebeurtenis verwijderen" label_recurring_meeting_delete_confirmation: > - This meeting is part of a series called %{name}. This will only delete this particular occurrence and not the entire series. Do you want to continue? + Deze bijeenkomst maakt deel uit van een serie genaamd %{name}. Hiermee wordt alleen deze specifieke gebeurtenis verwijderd en niet de hele serie. Wilt u doorgaan? label_recurring_occurrence_delete_confirmation: > - Any meeting information not in the template will be lost. Do you want to continue? - label_recurring_meeting_restore: "Restore this occurrence" - label_recurring_meeting_more: "There are %{count} more scheduled meetings (%{schedule})." - label_recurring_meeting_more_singular: "There is %{count} more scheduled meeting (%{schedule})." - label_recurring_meeting_more_past: "There are %{count} more past meetings." - label_recurring_meeting_more_past_singular: "There is %{count} more past meeting." - label_recurring_meeting_show_more: "Show more" - label_recurring_meeting_series_edit: "Edit meeting series" - label_recurring_meeting_series_delete: "Delete meeting series" - label_my_meetings: "My meetings" - label_all_meetings: "All meetings" + Alle vergaderinformatie die niet in de sjabloon staat, zal verloren gaan. Wilt u doorgaan? + label_recurring_meeting_restore: "Herstel deze gebeurtenis" + label_recurring_meeting_more: "Er zijn nog %{count} geplande vergaderingen (%{schedule})." + label_recurring_meeting_more_singular: "Er zijn nog %{count} geplande vergaderingen (%{schedule})." + label_recurring_meeting_more_past: "Er zijn %{count} meer eerdere vergaderingen." + label_recurring_meeting_more_past_singular: "Er zijn %{count} meer eerdere vergaderingen." + label_recurring_meeting_show_more: "Toon meer" + label_recurring_meeting_series_edit: "Vergaderreeks bewerken" + label_recurring_meeting_series_delete: "Verwijder serie van vergaderingen" + label_my_meetings: "Mijn vergaderingen" + label_all_meetings: "Alle vergaderingen" label_upcoming_meetings: "Geplande vergaderingen" label_past_meetings: "Eerdere vergaderingen" label_upcoming_meetings_short: "Aankomende" label_past_meetings_short: "Vorige" label_involvement: "Betrokkenheid" - label_invitations: "Invitations" + label_invitations: "Uitnodigingen" + label_invited_user: "Invited user" label_past_invitations: "Vorige uitnodigingen" - label_attended: "Attended" - label_created_by_me: "Created by me" + label_attended: "Deelgenomen" + label_attended_user: "Attended user" + label_created_by_me: "Gemaakt door mij" label_notify: "Verzenden voor revisie" label_icalendar: "Verstuur iCalendar" label_icalendar_download: "Download iCalendar event" - label_view_meeting_series: "View meeting series" - label_meeting_series: "Meeting series" + label_view_meeting_series: "Bekijk vergaderreeksen" + label_meeting_series: "Vergaderreeksen" label_version: "Versie" label_time_zone: "Tijdzone" label_start_date: "Startdatum" meeting: participants: - template: "These participants will be invited automatically to all future meetings as they are created." + template: "Deze deelnemers worden automatisch uitgenodigd voor alle toekomstige vergaderingen wanneer deze worden aangemaakt." attachments: template: "These attached files will be included in all future meetings in the series." text: "Bijgevoegde bestanden zijn beschikbaar voor alle deelnemers aan de vergadering. U kunt deze ook naar agendapunt notities slepen." @@ -181,10 +184,11 @@ nl: label_mail_all_participants: "E-mail verzenden naar alle deelnemers" types: classic: "Klassiek" - classic_text: "Organiseer uw vergadering met een opmaakbare tekstagenda en protocol." - structured: "Dynamisch" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organiseren van uw vergadering als een lijst met agendapunten, eventueel koppelen aan een werkpakket." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Een vergadering kopiëren zal momenteel niet de bijbehorende agendapunten kopiëren, alleen de details" copied: "Gekopieerd van vergadering #%{id}" meeting_section: @@ -193,9 +197,6 @@ nl: placeholder_title: "Nieuwe Sectie" empty_text: "Sleep items hierheen of maak een nieuwe" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ nl: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notificatie succesvol verzonden" notice_timezone_missing: Geen tijdzone is ingesteld en %{zone} is aangenomen. Om uw tijdzone te kiezen, klik dan hier. diff --git a/modules/meeting/config/locales/crowdin/no.yml b/modules/meeting/config/locales/crowdin/no.yml index 21b42eae7dd6..db3ca3b0cfac 100644 --- a/modules/meeting/config/locales/crowdin/no.yml +++ b/modules/meeting/config/locales/crowdin/no.yml @@ -53,14 +53,15 @@ recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "er ikke et gyldig tidpunkt. Formatet må være HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Møte (dynamisk)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Dagsorden element" meeting_agenda: "Saksliste" meeting_minutes: "Referat" @@ -94,7 +95,7 @@ label_meeting: "Møte" label_meeting_plural: "Møter" label_meeting_new: "Nytt møte" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ label_past_meetings_short: "Tidligere" label_involvement: "Involvering" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Tidligere invitasjoner" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send till gjennomgang" label_icalendar: "Send til iCalendar" @@ -181,10 +184,11 @@ label_mail_all_participants: "Send e-post til alle deltagere" types: classic: "Klassisk" - classic_text: "Organiser møtet ditt i en formattabel tekst agenda og protokoll." - structured: "Dynamisk" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organiser møtet som en liste over saker, eventuelt knytte dem til en arbeidspakke." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Kopiering av et møte vil for tiden ikke kopiere de tilknyttede elementene på dagsordenen, bare detaljene" copied: "Kopiert fra møte #%{id}" meeting_section: @@ -193,9 +197,6 @@ placeholder_title: "Ny seksjon" empty_text: "Dra punkter hit eller opprett et nytt" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Påminning sendt" notice_timezone_missing: Ingen tidssone angis og %{zone} antas. Vennligst klikk her for å velge egen tidssone. diff --git a/modules/meeting/config/locales/crowdin/pl.yml b/modules/meeting/config/locales/crowdin/pl.yml index d5d6aeaa6765..cb86fa88153f 100644 --- a/modules/meeting/config/locales/crowdin/pl.yml +++ b/modules/meeting/config/locales/crowdin/pl.yml @@ -55,14 +55,15 @@ pl: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "nie jest prawidłowy. Wymagany format to: GG:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Spotkanie (dynamiczne)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Punkt programu" meeting_agenda: "Plan spotkania" meeting_minutes: "Protokół ze spotkania" @@ -96,7 +97,7 @@ pl: label_meeting: "Spotkanie" label_meeting_plural: "Spotkania" label_meeting_new: "Nowe spotkanie" - label_meeting_new_dynamic: "Nowe spotkanie dynamiczne" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Utwórz spotkanie" label_meeting_copy: "Skopiuj spotkanie" @@ -141,8 +142,10 @@ pl: label_past_meetings_short: "Poprzednie" label_involvement: "Zaangażowanie" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Poprzednie zaproszenia" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Wyślij do przeglądu" label_icalendar: "Wyślij iCalendar" @@ -183,10 +186,11 @@ pl: label_mail_all_participants: "Wyślij wiadomość e-mail do wszystkich uczestników" types: classic: "Klasyczny" - classic_text: "Zorganizuj spotkanie w formatowanym tekstowym planie spotkania i protokole." - structured: "Dynamiczne" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Zorganizuj spotkanie jako listę punktów planu spotkania, opcjonalnie powiązując je z pakietem roboczym." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Skopiowanie spotkania nie powoduje obecnie skopiowania powiązanych pozycji planu spotkania, a jedynie szczegółów" copied: "Skopiowano ze spotkania #%{id}" meeting_section: @@ -195,9 +199,6 @@ pl: placeholder_title: "Nowa sekcja" empty_text: "Przeciągnij elementy tutaj lub utwórz nowe" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ pl: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Powiadomienia wysłane pomyślnie" notice_timezone_missing: 'Została ustawiona domyślna strefa czasowa: %{zone}. Aby zmienić strefę czasową, kliknij tutaj.' diff --git a/modules/meeting/config/locales/crowdin/pt-BR.yml b/modules/meeting/config/locales/crowdin/pt-BR.yml index ef737a5c36dd..7b7ef2264774 100644 --- a/modules/meeting/config/locales/crowdin/pt-BR.yml +++ b/modules/meeting/config/locales/crowdin/pt-BR.yml @@ -53,14 +53,15 @@ pt-BR: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "não é um horário válido. Formato exigido: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Reunião (dinâmica)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Item da agenda" meeting_agenda: "Agenda" meeting_minutes: "Atas" @@ -94,7 +95,7 @@ pt-BR: label_meeting: "Reunião" label_meeting_plural: "Reuniões" label_meeting_new: "Nova Reunião" - label_meeting_new_dynamic: "Nova reunião dinâmica" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Criar reunião" label_meeting_copy: "Copiar reunião" @@ -139,8 +140,10 @@ pt-BR: label_past_meetings_short: "Passado" label_involvement: "Envolvimento" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Convites anteriores" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Enviar para revisão" label_icalendar: "Enviar iCalendar" @@ -181,10 +184,11 @@ pt-BR: label_mail_all_participants: "Enviar e-mail para todos os participantes" types: classic: "Clássico" - classic_text: "Organize sua reunião em uma agenda e protocolo de texto formatáveis." - structured: "Dinâmico" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize sua reunião como uma lista de itens da agenda, opcionalmente vinculando-os a um pacote de trabalho." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copiar uma reunião atualmente não copiará os itens associados da agenda da reunião, apenas os detalhes" copied: "Copiado para a Reunião #%{id}" meeting_section: @@ -193,9 +197,6 @@ pt-BR: placeholder_title: "Nova seção" empty_text: "Arraste itens para cá ou crie um novo." recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ pt-BR: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notificação enviada com sucesso" notice_timezone_missing: Nenhum fuso horário está definido, portanto assumiu-se %{zone}. Para escolher o seu fuso horário, clique aqui. diff --git a/modules/meeting/config/locales/crowdin/pt-PT.yml b/modules/meeting/config/locales/crowdin/pt-PT.yml index 81465b5ac253..5fb7c85dcea3 100644 --- a/modules/meeting/config/locales/crowdin/pt-PT.yml +++ b/modules/meeting/config/locales/crowdin/pt-PT.yml @@ -53,14 +53,15 @@ pt-PT: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "não é uma hora válida. Formato exigido: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Reunião (dinâmica)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Pontos da ordem de trabalhos" meeting_agenda: "Agenda" meeting_minutes: "Minutos" @@ -94,7 +95,7 @@ pt-PT: label_meeting: "Reunião" label_meeting_plural: "Reuniões" label_meeting_new: "Nova reunião" - label_meeting_new_dynamic: "Nova reunião dinâmica" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Criar reunião" label_meeting_copy: "Copiar reunião" @@ -139,8 +140,10 @@ pt-PT: label_past_meetings_short: "Passado" label_involvement: "Envolvimento" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Convites anteriores" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Enviar para revisão" label_icalendar: "Enviar iCalendar" @@ -181,10 +184,11 @@ pt-PT: label_mail_all_participants: "Enviar e-mail a todos os participantes" types: classic: "Clássico" - classic_text: "Organize a sua reunião numa agenda e protocolo de texto formatáveis." - structured: "Dinâmico" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize a sua reunião como uma lista de itens da agenda, associando-os opcionalmente a um pacote de trabalho." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Atualmente, a cópia de uma reunião não copia os itens associados da agenda da reunião, apenas os detalhes" copied: "Copiado da reunião #%{id}" meeting_section: @@ -193,9 +197,6 @@ pt-PT: placeholder_title: "Nova secção" empty_text: "Arraste itens para aqui ou crie um novo" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ pt-PT: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notificação enviada com sucesso" notice_timezone_missing: Sem fuso horário definido, presume-se %{zone}. Para escolher o seu fuso horário, por favor clique aqui. diff --git a/modules/meeting/config/locales/crowdin/ro.yml b/modules/meeting/config/locales/crowdin/ro.yml index 3ff0e9c1af6b..c0104d89dc89 100644 --- a/modules/meeting/config/locales/crowdin/ro.yml +++ b/modules/meeting/config/locales/crowdin/ro.yml @@ -54,14 +54,15 @@ ro: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "nu este o oră valabilă. Format necesar: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agendă" meeting_minutes: "Minute" @@ -95,7 +96,7 @@ ro: label_meeting: "ID Întâlnire" label_meeting_plural: "Întâlniri" label_meeting_new: "Noua întâlnire" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -140,8 +141,10 @@ ro: label_past_meetings_short: "Past" label_involvement: "Implicare" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Trimiteți pentru revizuire" label_icalendar: "Trimiteți iCalendar" @@ -182,10 +185,11 @@ ro: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copiat de la Întâlnire #%{id}" meeting_section: @@ -194,9 +198,6 @@ ro: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -220,15 +221,15 @@ ro: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notificare trimisă cu succes" notice_timezone_missing: Nu este setat niciun fus orar și se presupune %{zone}. Pentru a vă alege fusul orar, vă rugăm să faceți clic aici. diff --git a/modules/meeting/config/locales/crowdin/ru.yml b/modules/meeting/config/locales/crowdin/ru.yml index 6a0c8204deb7..58a752ddd939 100644 --- a/modules/meeting/config/locales/crowdin/ru.yml +++ b/modules/meeting/config/locales/crowdin/ru.yml @@ -24,7 +24,7 @@ ru: plugin_openproject_meeting: name: "Встреча OpenProject" description: >- - Этот модуль добавляет функции для поддержки встреч проектов в OpenProject. Для участия в работе совещания могут быть запланированы приглашенные из того же проекта. Повестка дня может быть создана и отправлена приглашенным лицам. После встречи участники могут быть выбраны и минуты могут быть созданы на основе повестки дня. Наконец, минуты могут быть отправлены всем участникам и приглашенным. + Этот модуль добавляет поддержку совещаний в проектах. Совещания могут быть запланированы, выбрав приглашенных из того же проекта. Повестка дня может быть создана и отправлена приглашенным лицам. После совещания можно выбрать участников и создать протокол на основе повестки дня. Протокол может быть отправлен всем участникам и приглашенным. activerecord: attributes: meeting: @@ -55,14 +55,15 @@ ru: recurring_meeting: frequency: "Периодичность" interval: "Промежуток" - end_after: "Окончание через" + start_date: "Начинается" + end_after: "Завершение серии после" iterations: "События" errors: messages: invalid_time_format: "недопустимое время. Требуемый формат: ЧЧ:ММ" models: - recurring_meeting: "Повторяющаяся встреча" - structured_meeting: "Встреча (динамическая)" + recurring_meeting: "Повторяющееся совещание" + structured_meeting: "Однократное совещание" meeting_agenda_item: "Пункт повестки" meeting_agenda: "Повестка дня" meeting_minutes: "Протокол(-ы)" @@ -96,8 +97,8 @@ ru: label_meeting: "Совещание" label_meeting_plural: "Совещания" label_meeting_new: "Новое совещание" - label_meeting_new_dynamic: "Новая динамичная встреча" - label_meeting_new_recurring: "Новая повторяющаяся встреча" + label_meeting_new_dynamic: "Новое однократное совещание" + label_meeting_new_recurring: "Новое повторяющееся совещание" label_meeting_create: "Создать совещание" label_meeting_copy: "Копировать совещание" label_meeting_edit: "Измененить совещание" @@ -111,53 +112,55 @@ ru: label_meeting_date_time: "Дата/Время" label_meeting_date_and_time: "Дата и время" label_meeting_diff: "Различия" - label_recurring_meeting: "Повторяющаяся встреча" - label_recurring_meeting_part_of: "Часть серии встреч" - label_recurring_meeting_new: "Новая повторяющаяся встреча" - label_recurring_meeting_plural: "Повторяющиеся встречи" + label_recurring_meeting: "Повторяющееся совещание" + label_recurring_meeting_part_of: "Часть серии совещаний" + label_recurring_meeting_new: "Новое повторяющееся совещание" + label_recurring_meeting_plural: "Повторяющиеся совещания" label_template: "Шаблон" - label_recurring_meeting_view: "Посмотреть серию встреч" + label_recurring_meeting_view: "Посмотреть серию совещаний" label_recurring_meeting_create: "Создать из шаблона" label_recurring_meeting_copy: "Копировать как одноразовое" label_recurring_meeting_cancel: "Отменить это событие" label_recurring_meeting_delete: "Удалить событие" label_recurring_meeting_delete_confirmation: > - Эта встреча является частью серии под названием %{name}. Это приведет к удалению только этой конкретной встречи, а не всей серии. Вы хотите продолжить? + Это совещание является частью серии под названием %{name}. Это приведет к удалению только этого конкретного совещания, а не всей серии. Вы хотите продолжить? label_recurring_occurrence_delete_confirmation: > - Любая информация о встрече, не включенная в шаблон, будет потеряна. Вы хотите продолжить? + Любая информация о совещании, не включенная в шаблон, будет потеряна. Вы хотите продолжить? label_recurring_meeting_restore: "Восстановить это событие" - label_recurring_meeting_more: "There are %{count} more scheduled meetings (%{schedule})." - label_recurring_meeting_more_singular: "There is %{count} more scheduled meeting (%{schedule})." - label_recurring_meeting_more_past: "There are %{count} more past meetings." - label_recurring_meeting_more_past_singular: "There is %{count} more past meeting." - label_recurring_meeting_show_more: "Show more" - label_recurring_meeting_series_edit: "Изменить серию встреч" - label_recurring_meeting_series_delete: "Удалить серию встреч" - label_my_meetings: "Мои встречи" - label_all_meetings: "Все встречи" + label_recurring_meeting_more: "Есть еще %{count} запланированных совещаний (%{schedule})." + label_recurring_meeting_more_singular: "Есть еще %{count} запланированное совещание (%{schedule})." + label_recurring_meeting_more_past: "Есть еще %{count} прошедших совещаний." + label_recurring_meeting_more_past_singular: "Есть еще %{count} прошедшее совещание." + label_recurring_meeting_show_more: "Показать еще" + label_recurring_meeting_series_edit: "Изменить серию совещаний" + label_recurring_meeting_series_delete: "Удалить серию совещаний" + label_my_meetings: "Мои совещания" + label_all_meetings: "Все совещания" label_upcoming_meetings: "Предстоящие встречи" label_past_meetings: "Прошедшие встречи" label_upcoming_meetings_short: "Предстоящие" label_past_meetings_short: "Прошедшие" label_involvement: "Вовлечение" label_invitations: "Приглашения" + label_invited_user: "Приглашенный пользователь" label_past_invitations: "Прошлые приглашения" label_attended: "Участвовал" + label_attended_user: "Участвовавший пользователь" label_created_by_me: "Создано мной" label_notify: "Отправка на рецензию" label_icalendar: "Отправить iCalendar" label_icalendar_download: "Скачать мероприятие iCalendar" - label_view_meeting_series: "Посмотреть серию встреч" - label_meeting_series: "Серия встреч" + label_view_meeting_series: "Посмотреть серию совещаний" + label_meeting_series: "Серия совещаний" label_version: "Версия" label_time_zone: "Часовой пояс" label_start_date: "Дата начала" meeting: participants: - template: "Эти участники будут автоматически приглашаться на все будущие встречи по мере их создания." + template: "Эти участники будут автоматически приглашаться на все будущие совещания по мере их создания." attachments: - template: "Эти прикрепленные файлы будут включены во все последующие встречи этой серии." - text: "Прикрепленные файлы доступны всем участникам встречи. Вы также можете перенести их в примечания к пунктам повестки дня." + template: "Эти прикрепленные файлы будут включены во все последующие совещания этой серии." + text: "Прикрепленные файлы доступны всем участникам совещания. Вы также можете перенести их в примечания к пунктам повестки дня." copy: title: "Копировать встречу %{title}" attachments: "Копировать вложения" @@ -183,9 +186,10 @@ ru: label_mail_all_participants: "Отправить письмо всем участникам" types: classic: "Классический" - classic_text: "Организуйте своё совещание с помощью форматируемой текстовой повестки и протокола." - structured: "Динамический" + classic_text: "Организуйте встречу как одну форматируемую повестку и протокол." + structured: "Однократная" recurring: "Периодичность" + recurring_text: "Создать серию встреч с динамическим шаблоном для каждого события." structured_text: "Организуйте своё совещание в виде списка пунктов повестки, при необходимости связав их с пакетом работ." structured_text_copy: "При копировании совещания в настоящее время не скопируются связанные с ним пункты повестки, будут скопированы только детали" copied: "Скопировано со встречи #%{id}" @@ -195,41 +199,38 @@ ru: placeholder_title: "Новый раздел" empty_text: "Перенесите элементы сюда или создайте новые" recurring_meeting: - interval: - instructions: > - Введите количество дней или недель между каждым событием. occurrence: - infoline: "Эта встреча является частью повторяющейся серии встреч." - error_no_next: "Следующее событие для этой встречи не состоится." - first_already_exists: "Первое событие этой серии встреч уже произошло." + infoline: "Это совещание является частью повторяющейся серии совещаний." + error_no_next: "Следующее событие для этого совещания не состоится." + first_already_exists: "Первое событие этой серии совещаний уже произошло." first_created: > - Первая встреча была успешно создана из шаблона. Все последующие встречи будут создаваться автоматически в момент предыдущей. + Первое совещание было успешно создано из шаблона. Все последующие совещания будут создаваться автоматически в момент предыдущего. template: button_finalize: "Завершить шаблон" - blank_title: "Ваш шаблон серии встреч пуст" + blank_title: "Ваш шаблон серии совещаний пуст" description: > - Этот шаблон будет использоваться каждый раз, когда будут создаваться новые встречи в серии. Вы можете добавить в этот шаблон пункты повестки дня, участников и вложения. + Этот шаблон будет использоваться каждый раз, когда будут создаваться новые совещания в серии. Вы можете добавить в этот шаблон пункты повестки дня, участников и вложения. blankslate_finalize: > - По завершении подготовки шаблона нажмите кнопку '%{button_title}', чтобы завершить установку и запланировать первую встречу этой серии. + По завершении подготовки шаблона нажмите кнопку '%{button_title}', чтобы завершить установку и запланировать первое совещание этой серии. label_view_template: "Посмотреть шаблон" label_edit_template: "Изменить шаблон" banner_html: > - You are currently editing a template of a meeting series: %{link}. Every new occurrence of a meeting in the series will use this template. Changes will not affect past or already created meetings. + В настоящее время вы редактируете шаблон серии совещаний: %{link}. Каждое новое совещание в этой серии будет использовать этот шаблон. Изменения не повлияют на прошлые или уже созданные совещания. frequency: every_weekday: "Каждый %{day_of_the_week}" daily: "Ежедневно" - working_days: "Every working day" + working_days: "Каждый рабочий день" weekly: "Еженедельно" end_after: - specific_date: "Конкретная дата" - iterations: "Количество событий" + specific_date: "конкретная дата" + iterations: "количество событий" starts: "Начало" in_words: - daily_interval: "Каждый %{interval} день" + daily_interval: "Каждые %{interval} дней" working_days: "Каждый рабочий день" - working_days_interval: "Каждый %{interval} рабочий день" - weekly: "Еженедельно в %{weekday}" - weekly_interval: "Каждую %{interval} неделю в %{weekday}" + weekly: "Каждую неделю в %{weekday}" + weekly_interval: "Каждые %{interval} недель в %{weekday}" + frequency: "%{base} в %{time}" full: "%{base} в %{time}, заканчивается %{end_date}" notice_successful_notification: "Уведомление успешно отправленно" notice_timezone_missing: Не установлен часовой пояс и применена %{zone}. Чтобы выбрать часовой пояс, пожалуйста, нажмите сюда. @@ -283,7 +284,7 @@ ru: text_deleted_agenda_item: 'Удаленный пункт повестки' label_initial_meeting_details: "Встреча" label_meeting_details: "Детали совещания" - label_meeting_series_details: "Meeting series details" + label_meeting_series_details: "Подробности серии совещаний" label_meeting_details_edit: "Изменить сведения о встрече" label_meeting_state: "Статус встречи" label_meeting_state_open: "Открыть" diff --git a/modules/meeting/config/locales/crowdin/rw.yml b/modules/meeting/config/locales/crowdin/rw.yml index 941eaecfcabf..7e6d11605bb8 100644 --- a/modules/meeting/config/locales/crowdin/rw.yml +++ b/modules/meeting/config/locales/crowdin/rw.yml @@ -53,14 +53,15 @@ rw: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ rw: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ rw: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ rw: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ rw: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ rw: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/si.yml b/modules/meeting/config/locales/crowdin/si.yml index 05f146d7e583..de018eb40aee 100644 --- a/modules/meeting/config/locales/crowdin/si.yml +++ b/modules/meeting/config/locales/crowdin/si.yml @@ -53,14 +53,15 @@ si: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ si: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ si: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ si: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ si: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ si: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/sk.yml b/modules/meeting/config/locales/crowdin/sk.yml index ebf36e6f79bd..4428e2a7c96d 100644 --- a/modules/meeting/config/locales/crowdin/sk.yml +++ b/modules/meeting/config/locales/crowdin/sk.yml @@ -55,14 +55,15 @@ sk: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "nie je platný čas. Požadovaný formát: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Zápisnica" @@ -96,7 +97,7 @@ sk: label_meeting: "Stretnutie" label_meeting_plural: "Stretnutia" label_meeting_new: "Nové stretnutie" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -141,8 +142,10 @@ sk: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Odoslať na revíziu" label_icalendar: "Zaslať iKalendár" @@ -183,10 +186,11 @@ sk: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -195,9 +199,6 @@ sk: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ sk: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notifikácia úspešne odoslaná" notice_timezone_missing: Časové pásmo nebolo špecificky nastavené, použilo sa teda %{zone}. Ak chcete vybrať iné časové pásmo, kliknite prosím tu. diff --git a/modules/meeting/config/locales/crowdin/sl.yml b/modules/meeting/config/locales/crowdin/sl.yml index bf7cff25e70d..1c5cefe83f9a 100644 --- a/modules/meeting/config/locales/crowdin/sl.yml +++ b/modules/meeting/config/locales/crowdin/sl.yml @@ -55,14 +55,15 @@ sl: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "ni veljaven čas. Potreben format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Dnevni red" meeting_minutes: "Zapisnik" @@ -96,7 +97,7 @@ sl: label_meeting: "Sestanek" label_meeting_plural: "Sestanki" label_meeting_new: "Nov sestanek" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -141,8 +142,10 @@ sl: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Pošljite v pregled" label_icalendar: "Pošljite iCalendar" @@ -183,10 +186,11 @@ sl: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Kopirano iz sestanka #%{id}" meeting_section: @@ -195,9 +199,6 @@ sl: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ sl: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Obvestila uspešno poslana" notice_timezone_missing: Časovni pas ni določen, %{zone} je izbran avtomatsko. Za določitev časovnega pasu kliknite tukaj. diff --git a/modules/meeting/config/locales/crowdin/sr.yml b/modules/meeting/config/locales/crowdin/sr.yml index f0f107990b26..36d1a84f0487 100644 --- a/modules/meeting/config/locales/crowdin/sr.yml +++ b/modules/meeting/config/locales/crowdin/sr.yml @@ -54,14 +54,15 @@ sr: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -95,7 +96,7 @@ sr: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -140,8 +141,10 @@ sr: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -182,10 +185,11 @@ sr: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -194,9 +198,6 @@ sr: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -220,15 +221,15 @@ sr: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/sv.yml b/modules/meeting/config/locales/crowdin/sv.yml index f9f60f167498..e8fb818d0bbd 100644 --- a/modules/meeting/config/locales/crowdin/sv.yml +++ b/modules/meeting/config/locales/crowdin/sv.yml @@ -53,14 +53,15 @@ sv: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "är inte en giltig tid. Använd formatet HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Protokoll" @@ -94,7 +95,7 @@ sv: label_meeting: "Möte" label_meeting_plural: "Möten" label_meeting_new: "Nytt möte" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ sv: label_past_meetings_short: "Past" label_involvement: "Involvering" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Tidigare inbjudningar" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Skicka för granskning" label_icalendar: "Skicka iCalendar" @@ -181,10 +184,11 @@ sv: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Kopierat från möte #%{id}" meeting_section: @@ -193,9 +197,6 @@ sv: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ sv: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Underrättelse skickades" notice_timezone_missing: Ingen tidszon angiven och %{zone} antas. För att välja din tidszon, vänligen klicka här. diff --git a/modules/meeting/config/locales/crowdin/th.yml b/modules/meeting/config/locales/crowdin/th.yml index f227d7449f76..fc40b9e3b159 100644 --- a/modules/meeting/config/locales/crowdin/th.yml +++ b/modules/meeting/config/locales/crowdin/th.yml @@ -52,14 +52,15 @@ th: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -93,7 +94,7 @@ th: label_meeting: "ประชุม" label_meeting_plural: "ประชุม" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -138,8 +139,10 @@ th: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -180,10 +183,11 @@ th: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -192,9 +196,6 @@ th: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -218,15 +219,15 @@ th: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/tr.yml b/modules/meeting/config/locales/crowdin/tr.yml index d5845c744d5d..90a706d28d97 100644 --- a/modules/meeting/config/locales/crowdin/tr.yml +++ b/modules/meeting/config/locales/crowdin/tr.yml @@ -53,14 +53,15 @@ tr: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "geçerli bir zaman değil. Gerekli format: SS:DD" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Toplantı (dinamik)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Ajanda öğesi" meeting_agenda: "Ajanda" meeting_minutes: "Dakika" @@ -94,7 +95,7 @@ tr: label_meeting: "Toplantı" label_meeting_plural: "Toplantılar" label_meeting_new: "Yeni Toplantı" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Toplantı oluştur" label_meeting_copy: "Toplantıyı kopyala" @@ -139,8 +140,10 @@ tr: label_past_meetings_short: "Geçmiş" label_involvement: "Katılım" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Geçmiş davetiyeler" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Gözden geçirilmek üzere gönder" label_icalendar: "Takvime gönder" @@ -181,10 +184,11 @@ tr: label_mail_all_participants: "Tüm katılımcılara e-posta gönderin" types: classic: "Klasik" - classic_text: "Toplantınızı biçimlendirilebilir bir metin gündemi ve protokolüyle düzenleyin." - structured: "Dinamik" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Toplantınızı, isteğe bağlı olarak bunları bir çalışma paketine bağlayarak, gündem maddelerinin bir listesi halinde düzenleyin." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Toplantıyı kopyalamak toplantıyla ilgili ajanda maddelerini kopyalamayacaktır, sadece detaylar kopyalanacak" copied: "#%{id} numaralı toplantıdan kopyalandı" meeting_section: @@ -193,9 +197,6 @@ tr: placeholder_title: "New section" empty_text: "Maddeleri buraya sürükleyin ya da yeni bir tane oluşturun" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ tr: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Bildirim başarıyla gönderildi" notice_timezone_missing: Saat dilimi ayarlanmadı ve %{zone} kabul edildi. Saat dilimini seçmek için lütfen buraya tıklayın. diff --git a/modules/meeting/config/locales/crowdin/uk.yml b/modules/meeting/config/locales/crowdin/uk.yml index cd4551ad5d38..d57f6ecef75e 100644 --- a/modules/meeting/config/locales/crowdin/uk.yml +++ b/modules/meeting/config/locales/crowdin/uk.yml @@ -55,14 +55,15 @@ uk: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "не є допустимим часом. Необхідний формат: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Нарада (динамічна)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Порядок денний" meeting_agenda: "Порядок денний" meeting_minutes: "Хвилини" @@ -96,7 +97,7 @@ uk: label_meeting: "Зустріч" label_meeting_plural: "Зустрічі" label_meeting_new: "Нова зустріч" - label_meeting_new_dynamic: "Нова динамічна нарада" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Створити нараду" label_meeting_copy: "Копіювати нараду" @@ -141,8 +142,10 @@ uk: label_past_meetings_short: "Минулі" label_involvement: "Участь" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Минулі запрошення" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Надіслати на розгляд" label_icalendar: "Надіслати iCalendar" @@ -183,10 +186,11 @@ uk: label_mail_all_participants: "Надіслати лист усім учасникам" types: classic: "Класична" - classic_text: "Організуйте нараду у вигляді порядку денного й протоколу в текстовому форматі з підтримкою редагування." - structured: "Динамічна" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Організуйте нараду у вигляді переліку пунктів порядку денного, за бажанням пов’язавши їх із пакетом робіт." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Зараз копіювання наради стосується лише докладних даних про неї, але не пов’язаних пунктів її порядку денного" copied: "Скопійовано з наради #%{id} " meeting_section: @@ -195,9 +199,6 @@ uk: placeholder_title: "Новий розділ" empty_text: "Перетягніть елементи сюди або створіть новий" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -221,15 +222,15 @@ uk: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Повідомлення успішно надіслано" notice_timezone_missing: Часовий пояс не встановлено і %{zone} передбачається. Щоб вибрати часовий пояс, натисніть тут. diff --git a/modules/meeting/config/locales/crowdin/uz.yml b/modules/meeting/config/locales/crowdin/uz.yml index 111c46322df8..9fe6fcd5d451 100644 --- a/modules/meeting/config/locales/crowdin/uz.yml +++ b/modules/meeting/config/locales/crowdin/uz.yml @@ -53,14 +53,15 @@ uz: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -94,7 +95,7 @@ uz: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -139,8 +140,10 @@ uz: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -181,10 +184,11 @@ uz: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" meeting_section: @@ -193,9 +197,6 @@ uz: placeholder_title: "New section" empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -219,15 +220,15 @@ uz: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" notice_timezone_missing: No time zone is set and %{zone} is assumed. To choose your time zone, please click here. diff --git a/modules/meeting/config/locales/crowdin/vi.yml b/modules/meeting/config/locales/crowdin/vi.yml index 33c373d7f9c6..4eb92a420bb7 100644 --- a/modules/meeting/config/locales/crowdin/vi.yml +++ b/modules/meeting/config/locales/crowdin/vi.yml @@ -52,14 +52,15 @@ vi: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "không phải giờ hợp lệ. Yêu cầu định dạng: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Cuộc họp (dạng động)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Mục chương trình nghị sự" meeting_agenda: "Các ý chính" meeting_minutes: "Phút" @@ -93,7 +94,7 @@ vi: label_meeting: "Cuộc họp" label_meeting_plural: "Những cuộc họp" label_meeting_new: "Cuộc họp mới" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Tạo cuộc họp" label_meeting_copy: "Copy meeting" @@ -138,8 +139,10 @@ vi: label_past_meetings_short: "Đã qua" label_involvement: "Tham gia" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Lời mời đã qua" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Gửi để xem xét" label_icalendar: "Gửi iCalendar" @@ -180,10 +183,11 @@ vi: label_mail_all_participants: "Gửi email đến tất cả người tham gia" types: classic: "Cổ điển" - classic_text: "Tổ chức cuộc họp của bạn bằng một chương trình nghị sự và biên bản định dạng văn bản." - structured: "Dạng động" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Tổ chức cuộc họp của bạn dưới dạng danh sách các mục chương trình nghị sự, có thể liên kết chúng với một gói công việc." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Sao chép một cuộc họp hiện tại sẽ không sao chép các mục chương trình nghị sự liên quan, chỉ sao chép các chi tiết" copied: "Sao chép từ Cuộc họp #%{id}" meeting_section: @@ -192,9 +196,6 @@ vi: placeholder_title: "Phần mới" empty_text: "Kéo các mục vào đây hoặc tạo một cái mới" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -218,15 +219,15 @@ vi: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Đã gửi thông báo thành công" notice_timezone_missing: Chưa đặt múi giờ và %{zone} đã được chọn. Để chọn múi giowf của bạn, nhấn vào đây. diff --git a/modules/meeting/config/locales/crowdin/zh-CN.yml b/modules/meeting/config/locales/crowdin/zh-CN.yml index fd0c3a7cf3bf..9ce3e078511a 100644 --- a/modules/meeting/config/locales/crowdin/zh-CN.yml +++ b/modules/meeting/config/locales/crowdin/zh-CN.yml @@ -52,14 +52,15 @@ zh-CN: recurring_meeting: frequency: "频率" interval: "周期" - end_after: "结束于" + start_date: "开始日期:" + end_after: "结束定期会议于" iterations: "事件" errors: messages: invalid_time_format: "不是有效时间。所需格式:HH:MM" models: recurring_meeting: "定期会议" - structured_meeting: "会议(动态)" + structured_meeting: "One-time meeting" meeting_agenda_item: "议程项目" meeting_agenda: "议程" meeting_minutes: "会议记录" @@ -93,7 +94,7 @@ zh-CN: label_meeting: "会议" label_meeting_plural: "会议" label_meeting_new: "新增会议" - label_meeting_new_dynamic: "新动态会议" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "新的定期会议" label_meeting_create: "创建会议" label_meeting_copy: "复制会议" @@ -123,11 +124,11 @@ zh-CN: label_recurring_occurrence_delete_confirmation: > 任何不在模板中的会议信息都将丢失。要继续吗? label_recurring_meeting_restore: "恢复此事件" - label_recurring_meeting_more: "There are %{count} more scheduled meetings (%{schedule})." - label_recurring_meeting_more_singular: "There is %{count} more scheduled meeting (%{schedule})." - label_recurring_meeting_more_past: "There are %{count} more past meetings." - label_recurring_meeting_more_past_singular: "There is %{count} more past meeting." - label_recurring_meeting_show_more: "Show more" + label_recurring_meeting_more: "还有至少 %{count} 个预定会议 (%{schedule})。" + label_recurring_meeting_more_singular: "还有至少 %{count} 个预定会议 (%{schedule})。" + label_recurring_meeting_more_past: "有至少 %{count} 个过往会议。" + label_recurring_meeting_more_past_singular: "有至少 %{count} 个过往会议。" + label_recurring_meeting_show_more: "显示更多" label_recurring_meeting_series_edit: "编辑会议系列" label_recurring_meeting_series_delete: "删除会议系列" label_my_meetings: "我的会议" @@ -138,8 +139,10 @@ zh-CN: label_past_meetings_short: "过往" label_involvement: "参与" label_invitations: "邀请函" + label_invited_user: "受邀用户" label_past_invitations: "过去的邀请" label_attended: "已出席" + label_attended_user: "出席用户" label_created_by_me: "我创建的" label_notify: "发送待审阅" label_icalendar: "发送 iCalendar" @@ -180,10 +183,11 @@ zh-CN: label_mail_all_participants: "发送电子邮件给所有参与者" types: classic: "经典" - classic_text: "将您的会议以可格式化的文本议程和会议纪要的形式进行组织。" - structured: "动态" - recurring: "定期的" - structured_text: "将您的会议组织为议程项目列表,并可选地将其与工作包链接。" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" + recurring: "定期" + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "目前复制会议不会复制相关会议的议程项目,只会复制会议的详细信息。" copied: "从会议 #%{id} 复制" meeting_section: @@ -192,9 +196,6 @@ zh-CN: placeholder_title: "新建章节" empty_text: "拖动项目到此处或创建一个新项目" recurring_meeting: - interval: - instructions: > - 输入每次事件之间的天数或周数。 occurrence: infoline: "本次会议是定期会议系列的一部分。" error_no_next: "此会议没有下一个发生时间。" @@ -211,22 +212,22 @@ zh-CN: label_view_template: "查看模板" label_edit_template: "编辑模板" banner_html: > - You are currently editing a template of a meeting series: %{link}. Every new occurrence of a meeting in the series will use this template. Changes will not affect past or already created meetings. + 您正在编辑会议系列的模板: %{link}。系列会议中的每个新会议都将使用此模板。更改不会影响过往或已创建的会议。 frequency: every_weekday: "每个 %{day_of_the_week}" daily: "每日" - working_days: "Every working day" + working_days: "每个工作日" weekly: "每周" end_after: - specific_date: "特定日期" - iterations: "一些事件" + specific_date: "具体日期" + iterations: "具体事件" starts: "开始" in_words: daily_interval: "每 %{interval} 天" working_days: "每个工作日" - working_days_interval: "每 %{interval} 个工作日" - weekly: "每周 %{weekday}" - weekly_interval: "每 %{interval} 周的星期 %{weekday}" + weekly: "每 %{weekday}" + weekly_interval: "每 %{interval} 周在 %{weekday}" + frequency: "%{base} 在 %{time}" full: "%{base} 在 %{time},在 %{end_date} 结束" notice_successful_notification: "通知发送成功" notice_timezone_missing: 没有设定时区,预设时区为 %{zone}。要选择您的时区,请单击此处。 @@ -280,7 +281,7 @@ zh-CN: text_deleted_agenda_item: '删除的议程项目' label_initial_meeting_details: "会议" label_meeting_details: "会议详情" - label_meeting_series_details: "Meeting series details" + label_meeting_series_details: "会议系列详情" label_meeting_details_edit: "编辑会议详情" label_meeting_state: "会议状态" label_meeting_state_open: "开放" diff --git a/modules/meeting/config/locales/crowdin/zh-TW.yml b/modules/meeting/config/locales/crowdin/zh-TW.yml index f6d2cf5c2d36..5fa0cff293b8 100644 --- a/modules/meeting/config/locales/crowdin/zh-TW.yml +++ b/modules/meeting/config/locales/crowdin/zh-TW.yml @@ -50,16 +50,17 @@ zh-TW: meeting_section: title: "標題" recurring_meeting: - frequency: "Frequency" - interval: "Interval" - end_after: "End after" - iterations: "Occurrences" + frequency: "頻率" + interval: "間隔" + start_date: "開始於" + end_after: "系列結束後" + iterations: "出現次數" errors: messages: invalid_time_format: "不是有效時間。所需格式: HH:MM" models: - recurring_meeting: "Recurring meeting" - structured_meeting: "會議(動態)" + recurring_meeting: "重複性會議" + structured_meeting: "一次性會議" meeting_agenda_item: "議程項目" meeting_agenda: "會議大綱" meeting_minutes: "會議記錄" @@ -93,8 +94,8 @@ zh-TW: label_meeting: "會議" label_meeting_plural: "會議" label_meeting_new: "新增會議" - label_meeting_new_dynamic: "新的動態會議" - label_meeting_new_recurring: "New recurring meeting" + label_meeting_new_dynamic: "建立一次性會議" + label_meeting_new_recurring: "新的重複性會議" label_meeting_create: "新增會議" label_meeting_copy: "複製會議" label_meeting_edit: "編輯會議" @@ -108,52 +109,54 @@ zh-TW: label_meeting_date_time: "日期 / 時間" label_meeting_date_and_time: "日期和時間" label_meeting_diff: "比較" - label_recurring_meeting: "Recurring meeting" - label_recurring_meeting_part_of: "Part of a meeting series" - label_recurring_meeting_new: "New recurring meeting" - label_recurring_meeting_plural: "Recurring meetings" - label_template: "Template" - label_recurring_meeting_view: "View meeting series" - label_recurring_meeting_create: "Create from template" - label_recurring_meeting_copy: "Copy as one-off" - label_recurring_meeting_cancel: "Cancel this occurrence" - label_recurring_meeting_delete: "Delete occurrence" + label_recurring_meeting: "重複性會議" + label_recurring_meeting_part_of: "系列會議的一部分" + label_recurring_meeting_new: "新的重複性會議" + label_recurring_meeting_plural: "重複性會議" + label_template: "模板" + label_recurring_meeting_view: "檢視會議系列" + label_recurring_meeting_create: "從模板建立" + label_recurring_meeting_copy: "複製為一次性" + label_recurring_meeting_cancel: "取消此事件" + label_recurring_meeting_delete: "刪除此事件" label_recurring_meeting_delete_confirmation: > - This meeting is part of a series called %{name}. This will only delete this particular occurrence and not the entire series. Do you want to continue? + 此會議是 %{name}系列的一部分。這只會刪除此特定事件,而不會刪除整個系列。您要繼續嗎? label_recurring_occurrence_delete_confirmation: > - Any meeting information not in the template will be lost. Do you want to continue? - label_recurring_meeting_restore: "Restore this occurrence" - label_recurring_meeting_more: "There are %{count} more scheduled meetings (%{schedule})." - label_recurring_meeting_more_singular: "There is %{count} more scheduled meeting (%{schedule})." - label_recurring_meeting_more_past: "There are %{count} more past meetings." - label_recurring_meeting_more_past_singular: "There is %{count} more past meeting." - label_recurring_meeting_show_more: "Show more" - label_recurring_meeting_series_edit: "Edit meeting series" - label_recurring_meeting_series_delete: "Delete meeting series" - label_my_meetings: "My meetings" - label_all_meetings: "All meetings" + 任何不在範本中的會議資訊將會遺失。要繼續嗎? + label_recurring_meeting_restore: "恢復此事件" + label_recurring_meeting_more: "還有 %{count} 預定會議 (%{schedule})。" + label_recurring_meeting_more_singular: "還有 %{count} 預定會議 (%{schedule})。" + label_recurring_meeting_more_past: "還有 %{count} 更多過去的會議。" + label_recurring_meeting_more_past_singular: "還有 %{count} 更多過去的會議。" + label_recurring_meeting_show_more: "顯示更多" + label_recurring_meeting_series_edit: "編輯系列會議" + label_recurring_meeting_series_delete: "刪除系列會議" + label_my_meetings: "我的會議" + label_all_meetings: "所有會議" label_upcoming_meetings: "即將到來的會議" label_past_meetings: "過去的會議" label_upcoming_meetings_short: "即將開會" label_past_meetings_short: "過往會議" label_involvement: "參與\n" - label_invitations: "Invitations" + label_invitations: "邀请" + label_invited_user: "受邀用户" label_past_invitations: "先前的會議邀請" - label_attended: "Attended" - label_created_by_me: "Created by me" + label_attended: "出席" + label_attended_user: "出席使用者" + label_created_by_me: "由我建立" label_notify: "送出審閱" label_icalendar: "發送 iCalendar" label_icalendar_download: "下載 iCalendar " - label_view_meeting_series: "View meeting series" - label_meeting_series: "Meeting series" + label_view_meeting_series: "檢視會議" + label_meeting_series: "會議" label_version: "版本" label_time_zone: "時區" label_start_date: "開始日期" meeting: participants: - template: "These participants will be invited automatically to all future meetings as they are created." + template: "這些參與者將自動被邀請參加未來所有建立的會議。" attachments: - template: "These attached files will be included in all future meetings in the series." + template: "這些隨附的檔案將納入所有未來的系列會議中。" text: "所有會議參與者都可以使用附件, 您也可以將它們拖放到議程項目註釋中。" copy: title: "複製會議 %{title}" @@ -180,10 +183,11 @@ zh-TW: label_mail_all_participants: "發送電子郵件給所有參與者" types: classic: "經典" - classic_text: "以調整好的文字議程和程序來整理您的會議紀錄。" - structured: "動態" - recurring: "Recurring" - structured_text: "將您的會議整理成一個議程項目列表,並可選擇地將它們與一個工作項目連接起來。" + classic_text: "將會議組織為單一可格式化的文字議程和規程。" + structured: "一次性" + recurring: "重覆" + recurring_text: "為每次發生的事件建立具有動態範本的會議系列。" + structured_text: "將會議組織為動態的議程項目清單,可選擇將其連結到工作項目。" structured_text_copy: "目前複製會議不會複製相關會議的議程項目,只會複製會議的詳細信息。" copied: "從會議紀錄 #%{id} 中複製" meeting_section: @@ -192,42 +196,39 @@ zh-TW: placeholder_title: "新增章節" empty_text: "將項目拖曳至此處或建立新項目" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: - infoline: "This meeting is part of a recurring meeting series." - error_no_next: "There is no next occurrence for this meeting." - first_already_exists: "The first occurrence of this meeting series is already instantiated." + infoline: "此會議為定期舉行的系列會議之一。" + error_no_next: "本次會議無下次會議。" + first_already_exists: "此會議系列的第一次出現已經實體化。" first_created: > - The first meeting has been successfuly created from template. All future meetings will be created automatically at the time of the previous occurrence. + 第一次會議已從範本成功建立。以後所有的會議都會在前一次發生時自動建立。 template: - button_finalize: "Finish template" - blank_title: "Your meeting series template is empty" + button_finalize: "完成範本" + blank_title: "您的會議範本是空的" description: > - This template will be used whenever new meetings in the series get created. You can add agenda items, participants, and attachments to this template. + 每當在系列中建立新會議時,都會使用此範本。您可以在此範本中加入議程項目、與會者和附件。 blankslate_finalize: > - When you're done preparing this template, click the '%{button_title}' button above to finish the setup and schedule the first meeting of the series. - label_view_template: "View template" - label_edit_template: "Edit template" + 準備完此範本後,按一下上方的 '%{button_title}' 按鈕,即可完成設定並排定系列會議的第一次會議。 + label_view_template: "查看範本" + label_edit_template: "編輯範本" banner_html: > - You are currently editing a template of a meeting series: %{link}. Every new occurrence of a meeting in the series will use this template. Changes will not affect past or already created meetings. + 您目前正在編輯會議系列的範本: %{link}。系列會議中的每次新會議都會使用此範本。變更不會影響過去或已建立的會議。 frequency: - every_weekday: "Every %{day_of_the_week}" - daily: "Daily" - working_days: "Every working day" - weekly: "Weekly" + every_weekday: "每個 %{day_of_the_week}" + daily: "每日" + working_days: "每個工作天" + weekly: "每週" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" - starts: "Starts" + specific_date: "特定日期" + iterations: "出現數" + starts: "開始" in_words: - daily_interval: "Every %{interval} day" - working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" - full: "%{base} at %{time}, ends on %{end_date}" + daily_interval: "每 %{interval} 天" + working_days: "每個工作天" + weekly: "每週 %{weekday}" + weekly_interval: "每 %{interval} 週 %{weekday}" + frequency: "%{base} 在 %{time}" + full: "%{base} 於 %{time}, 結束於 %{end_date}" notice_successful_notification: "通知傳送成功" notice_timezone_missing: 沒有設定時區,預設時區為 %{zone} 。請按這裡選擇您的時區。 notice_meeting_updated: "本頁已由他人更新。重新載入以查看變更。" @@ -280,17 +281,17 @@ zh-TW: text_deleted_agenda_item: '已刪除的議程項目' label_initial_meeting_details: "會議" label_meeting_details: "會議詳情" - label_meeting_series_details: "Meeting series details" + label_meeting_series_details: "會議詳細資訊" label_meeting_details_edit: "編輯會議詳情" label_meeting_state: "會議狀態" label_meeting_state_open: "開啟" label_meeting_state_open_html: "開啟" label_meeting_state_closed: "關閉" label_meeting_state_closed_html: "關閉" - label_meeting_state_agenda_created: "Agenda created" - label_meeting_state_scheduled: "Scheduled" - label_meeting_state_cancelled: "Cancelled" - label_meeting_state_skipped: "Skipped" + label_meeting_state_agenda_created: "議程已建立" + label_meeting_state_scheduled: "已排程" + label_meeting_state_cancelled: "已取消" + label_meeting_state_skipped: "已略過" label_meeting_reopen_action: "重新開啟會議" label_meeting_close_action: "關閉會議" text_meeting_open_description: "本次會議已開放。您可以新增/移除議程項目並隨時編輯它們。會議結束後,關閉後鎖定起來。" diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml index afe8b3e90ba6..6c16dc89c19c 100644 --- a/modules/meeting/config/locales/en.yml +++ b/modules/meeting/config/locales/en.yml @@ -64,14 +64,15 @@ en: recurring_meeting: frequency: "Frequency" interval: "Interval" - end_after: "End after" + start_date: "Starts on" + end_after: "End series after" iterations: "Occurrences" errors: messages: invalid_time_format: "is not a valid time. Required format: HH:MM" models: recurring_meeting: "Recurring meeting" - structured_meeting: "Meeting (dynamic)" + structured_meeting: "One-time meeting" meeting_agenda_item: "Agenda item" meeting_agenda: "Agenda" meeting_minutes: "Minutes" @@ -110,7 +111,7 @@ en: label_meeting: "Meeting" label_meeting_plural: "Meetings" label_meeting_new: "New Meeting" - label_meeting_new_dynamic: "New dynamic meeting" + label_meeting_new_dynamic: "New one-time meeting" label_meeting_new_recurring: "New recurring meeting" label_meeting_create: "Create meeting" label_meeting_copy: "Copy meeting" @@ -158,8 +159,10 @@ en: label_past_meetings_short: "Past" label_involvement: "Involvement" label_invitations: "Invitations" + label_invited_user: "Invited user" label_past_invitations: "Past invitations" label_attended: "Attended" + label_attended_user: "Attended user" label_created_by_me: "Created by me" label_notify: "Send for review" label_icalendar: "Send iCalendar" @@ -202,10 +205,11 @@ en: label_mail_all_participants: "Send email to all participants" types: classic: "Classic" - classic_text: "Organize your meeting in a formattable text agenda and protocol." - structured: "Dynamic" + classic_text: "Organize your meeting as a single formattable text agenda and protocol." + structured: "One-time" recurring: "Recurring" - structured_text: "Organize your meeting as a list of agenda items, optionally linking them to a work package." + recurring_text: "Create meeting series with dynamic template for each occurrence." + structured_text: "Organize your meeting as a dynamic list of agenda items, optionally linking them to a work package." structured_text_copy: "Copying a meeting will currently not copy the associated meeting agenda items, just the details" copied: "Copied from Meeting #%{id}" @@ -216,9 +220,6 @@ en: empty_text: "Drag items here or create a new one" recurring_meeting: - interval: - instructions: > - Enter the number of days or weeks between each occurrence. occurrence: infoline: "This meeting is part of a recurring meeting series." error_no_next: "There is no next occurrence for this meeting." @@ -247,15 +248,15 @@ en: working_days: "Every working day" weekly: "Weekly" end_after: - specific_date: "A specific date" - iterations: "A number of occurrences" + specific_date: "a specific date" + iterations: "a number of occurrences" starts: "Starts" in_words: - daily_interval: "Every %{interval} day" + daily_interval: "Every %{interval} days" working_days: "Every working day" - working_days_interval: "Every %{interval} working day" - weekly: "Weekly on %{weekday}" - weekly_interval: "Every %{interval} week on %{weekday}" + weekly: "Every week on %{weekday}" + weekly_interval: "Every %{interval} weeks on %{weekday}" + frequency: "%{base} at %{time}" full: "%{base} at %{time}, ends on %{end_date}" notice_successful_notification: "Notification sent successfully" diff --git a/modules/meeting/config/routes.rb b/modules/meeting/config/routes.rb index 70dda4a74169..4d6b4b845704 100644 --- a/modules/meeting/config/routes.rb +++ b/modules/meeting/config/routes.rb @@ -64,6 +64,9 @@ post :delete_scheduled post :template_completed end + collection do + get :humanize_schedule, controller: "recurring_meetings/schedule", action: :humanize_schedule + end end resources :meetings do diff --git a/modules/meeting/lib/open_project/meeting/engine.rb b/modules/meeting/lib/open_project/meeting/engine.rb index eb36687dfc38..4668c82dc4cf 100644 --- a/modules/meeting/lib/open_project/meeting/engine.rb +++ b/modules/meeting/lib/open_project/meeting/engine.rb @@ -40,17 +40,20 @@ class Engine < ::Rails::Engine bundled: true do project_module :meetings do permission :view_meetings, - { meetings: %i[index show check_for_updates download_ics participants_dialog history], + { + meetings: %i[index show check_for_updates download_ics participants_dialog history], meeting_agendas: %i[history show diff], meeting_minutes: %i[history show diff], "meetings/menus": %i[show], work_package_meetings_tab: %i[index count], - recurring_meetings: %i[index show new create download_ics] }, + recurring_meetings: %i[index show new create download_ics] + }, permissible_on: :project permission :create_meetings, { meetings: %i[new create copy new_dialog], recurring_meetings: %i[new create copy init template_completed], + "recurring_meetings/schedule": %i[update_text], "meetings/menus": %i[show] }, permissible_on: :project, diff --git a/modules/meeting/spec/features/recurring_meetings/recurring_meeting_create_spec.rb b/modules/meeting/spec/features/recurring_meetings/recurring_meeting_create_spec.rb index d7fdb139152b..088f06039396 100644 --- a/modules/meeting/spec/features/recurring_meetings/recurring_meeting_create_spec.rb +++ b/modules/meeting/spec/features/recurring_meetings/recurring_meeting_create_spec.rb @@ -35,8 +35,7 @@ RSpec.describe "Recurring meetings creation", :js, - :with_cuprite, - with_flag: { recurring_meetings: true } do + :with_cuprite do include Components::Autocompleter::NgSelectAutocompleteHelpers shared_let(:project) { create(:project, enabled_module_names: %w[meetings]) } @@ -70,17 +69,22 @@ meetings_page.visit! expect(page).to have_current_path(meetings_page.path) meetings_page.click_on "add-meeting-button" - meetings_page.click_on "Recurring" + + page.within("action-list") do + meetings_page.click_on "Recurring" + end wait_for_network_idle meetings_page.set_title "Some title" - meetings_page.set_start_date "2024-12-31" + meetings_page.set_starts_on "2024-12-31" meetings_page.set_start_time "13:30" meetings_page.set_duration "1.5" meetings_page.set_end_date "2025-01-15" + expect(page).to have_text "Every week on Tuesday at 01:30 PM" + click_on "Create meeting" wait_for_network_idle expect_and_dismiss_flash(type: :success, message: "Successful creation.") diff --git a/modules/meeting/spec/features/recurring_meetings/recurring_meeting_crud_spec.rb b/modules/meeting/spec/features/recurring_meetings/recurring_meeting_crud_spec.rb index 35291cc7378d..4d4eda1669c7 100644 --- a/modules/meeting/spec/features/recurring_meetings/recurring_meeting_crud_spec.rb +++ b/modules/meeting/spec/features/recurring_meetings/recurring_meeting_crud_spec.rb @@ -35,8 +35,7 @@ RSpec.describe "Recurring meetings CRUD", :js, - :with_cuprite, - with_flag: { recurring_meetings: true } do + :with_cuprite do include Components::Autocompleter::NgSelectAutocompleteHelpers shared_let(:project) { create(:project, enabled_module_names: %w[meetings]) } @@ -121,13 +120,13 @@ it "can edit the details of a recurring meeting" do show_page.visit! - show_page.expect_subtitle text: "Weekly on Tuesday at 01:30 PM, ends on 01/14/2025" + show_page.expect_subtitle text: "Every week on Tuesday at 01:30 PM, ends on 01/14/2025" show_page.edit_meeting_series show_page.in_edit_dialog do page.select("Daily", from: "Frequency") meetings_page.set_start_time "11:00" - page.select("A number of occurrences", from: "End after") + page.select("a number of occurrences", from: "End series after") page.fill_in("Occurrences", with: "8") sleep 0.5 diff --git a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb index 9810d8af32ef..01e87ed8e85e 100644 --- a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb +++ b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb @@ -72,7 +72,7 @@ meetings_page.visit! expect(page).to have_current_path(meetings_page.path) # rubocop:disable RSpec/ExpectInHook meetings_page.click_on "add-meeting-button" - meetings_page.click_on "Dynamic" + meetings_page.click_on "One-time" meetings_page.set_title "Some title" meetings_page.set_start_date "2013-03-28" @@ -290,6 +290,7 @@ click_on("Save") end + wait_for_network_idle click_on("op-meetings-header-action-trigger") retry_block do diff --git a/modules/meeting/spec/models/meeting_spec.rb b/modules/meeting/spec/models/meeting_spec.rb index 0604716d9558..4f1a513957b3 100644 --- a/modules/meeting/spec/models/meeting_spec.rb +++ b/modules/meeting/spec/models/meeting_spec.rb @@ -207,4 +207,27 @@ expect(StructuredMeeting.acts_as_watchable_permission).to eq(:view_meetings) end end + + describe "duration" do + it "accepts a float" do + meeting.duration = 1.5 + expect(meeting).to be_valid + expect(meeting.duration).to eq(1.5) + expect(meeting.formatted_duration).to eq("1.5h") + end + + it "accepts a string to be parsed by chronic" do + meeting.duration = "30m" + expect(meeting).to be_valid + expect(meeting.duration).to eq(0.5) + expect(meeting.formatted_duration).to eq("0.5h") + end + + it "doesn't raise on nil" do + meeting.duration = nil + expect(meeting).not_to be_valid + expect(meeting.errors[:duration]).to include("is not a number.") + expect(meeting.formatted_duration).to be_nil + end + end end diff --git a/modules/meeting/spec/models/recurring_meeting_spec.rb b/modules/meeting/spec/models/recurring_meeting_spec.rb index 3c6e7f89fb1d..5497bace6a7a 100644 --- a/modules/meeting/spec/models/recurring_meeting_spec.rb +++ b/modules/meeting/spec/models/recurring_meeting_spec.rb @@ -36,6 +36,15 @@ expect(subject.errors[:interval]).to be_empty end + it "validates max value" do + subject.interval = 101 + expect(subject).not_to be_valid + expect(subject.errors[:interval]).to include("must be less than or equal to 100.") + + subject.interval = 100 + expect(subject).to be_valid + end + it "adds errors for invalid values", :aggregate_failures do subject.interval = 0 expect(subject).not_to be_valid @@ -55,6 +64,49 @@ end end + describe "iterations" do + subject { build(:recurring_meeting, end_after: "iterations") } + + it "does not validate if end_after is not iterations" do + subject.end_after = "specific_date" + subject.iterations = nil + expect(subject).to be_valid + end + + it "validates integer values >= 1" do + subject.iterations = 1 + expect(subject).to be_valid + expect(subject.errors[:iterations]).to be_empty + end + + it "validates max value" do + subject.iterations = 1001 + expect(subject).not_to be_valid + expect(subject.errors[:iterations]).to include("must be less than or equal to 1000.") + + subject.iterations = 1000 + expect(subject).to be_valid + end + + it "adds errors for invalid values", :aggregate_failures do + subject.iterations = 0 + expect(subject).not_to be_valid + expect(subject.errors[:iterations]).to include("must be greater than or equal to 1.") + + subject.iterations = -1 + expect(subject).not_to be_valid + expect(subject.errors[:iterations]).to include("must be greater than or equal to 1.") + + subject.iterations = 0.1 + expect(subject).not_to be_valid + expect(subject.errors[:iterations]).to include("is not an integer.") + + subject.iterations = "asdf" + expect(subject).not_to be_valid + expect(subject.errors[:iterations]).to include("is not a number.") + end + end + describe "daily schedule" do subject do build(:recurring_meeting, diff --git a/modules/meeting/spec/requests/recurring_meetings/recurring_meetings_schedule_spec.rb b/modules/meeting/spec/requests/recurring_meetings/recurring_meetings_schedule_spec.rb new file mode 100644 index 000000000000..33fb596bb52b --- /dev/null +++ b/modules/meeting/spec/requests/recurring_meetings/recurring_meetings_schedule_spec.rb @@ -0,0 +1,115 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" +require_relative "../../support/pages/recurring_meeting/show" + +RSpec.describe "Recurring meetings schedule text", + :skip_csrf, + type: :rails_request do + include Redmine::I18n + + shared_let(:project) { create(:project, enabled_module_names: %i[meetings]) } + shared_let(:user) do + create(:user, + preferences: { time_zone: "Europe/London" }, + member_with_permissions: { project => %i[view_meetings create_meetings] }) + end + let(:current_user) { user } + + let(:start_time_hour) { "10:00" } + let(:start_date) { "2024-12-05" } + let(:frequency) { "daily" } + let(:interval) { "1" } + let(:params) do + { meeting: { start_time_hour:, start_date:, frequency:, interval: } } + end + let(:format) { :html } + + subject do + get humanize_schedule_recurring_meetings_path(params:, format:) + response + end + + before do + login_as(current_user) + end + + describe "setting schedule" do + it "returns the update text" do + expect(subject).to have_http_status(:ok) + expect(subject.body).to include("Daily at 10:00 AM") + end + + context "when changing the frequency and interval" do + let(:frequency) { "weekly" } + let(:interval) { "2" } + + it "returns the update text" do + expect(subject).to have_http_status(:ok) + expect(subject.body).to include("Every 2 weeks on Thursday at 10:00 AM") + end + end + + context "when changing the interval" do + let(:interval) { "2" } + + it "returns the update text" do + expect(subject).to have_http_status(:ok) + expect(subject.body).to include("Every 2 days at 10:00 AM") + end + end + + context "when leaving the interval empty" do + let(:interval) { "" } + + it "falls back to the default" do + expect(subject).to have_http_status(:ok) + expect(subject.body).to include("Daily at 10:00 AM") + end + end + + context "when requesting with turbo" do + let(:format) { :turbo_stream } + + it "returns an update turbo stream" do + expect(subject).to have_http_status(:ok) + expect(subject.body).to include("turbo-stream") + expect(subject.body).to include("Daily at 10:00 AM") + end + end + end + + context "when user has no permissions to access" do + let(:current_user) { create(:user) } + + it "does not allow to request it" do + expect(subject).to have_http_status(:forbidden) + end + end +end diff --git a/modules/meeting/spec/support/pages/meetings/index.rb b/modules/meeting/spec/support/pages/meetings/index.rb index 40fcfdf69d41..624ed36a3322 100644 --- a/modules/meeting/spec/support/pages/meetings/index.rb +++ b/modules/meeting/spec/support/pages/meetings/index.rb @@ -52,12 +52,17 @@ def set_title(text) end def set_start_date(date) - fill_in "Date", with: date, fill_options: { clear: :backspace } + fill_in "Date", with: date + end + + def set_starts_on(date) + fill_in "Starts on", with: date end def set_start_time(time) input = page.find_by_id("meeting_start_time_hour") page.execute_script("arguments[0].value = arguments[1]", input.native, time) + page.execute_script("arguments[0].dispatchEvent(new Event('input'))", input.native) end def set_end_date(date) @@ -104,7 +109,7 @@ def expect_create_new_types click_on("add-meeting-button") expect(page).to have_link("Classic") - expect(page).to have_link("Dynamic") + expect(page).to have_link("One-time") end def expect_copy_action(meeting) diff --git a/modules/my_page/config/locales/crowdin/js-mn.yml b/modules/my_page/config/locales/crowdin/js-mn.yml index 41f773efc2cd..1a6749448729 100644 --- a/modules/my_page/config/locales/crowdin/js-mn.yml +++ b/modules/my_page/config/locales/crowdin/js-mn.yml @@ -1,4 +1,4 @@ mn: js: my_page: - label: "My page" + label: "Миний хуудас" diff --git a/modules/reporting/app/components/cost_reports/index_page_header_component.html.erb b/modules/reporting/app/components/cost_reports/index_page_header_component.html.erb index 4c59a126a115..92d133f1d002 100644 --- a/modules/reporting/app/components/cost_reports/index_page_header_component.html.erb +++ b/modules/reporting/app/components/cost_reports/index_page_header_component.html.erb @@ -5,16 +5,39 @@ if show_export_button? header.with_action_button(scheme: :default, - aria: { label: t(:export_to_excel)}, + aria: { label: t(:export_to_excel) }, title: t(:export_to_excel), mobile_icon: "op-file-xls-descriptions", mobile_label: t(:export_to_excel), tag: :a, - href: url_for({ controller: "cost_reports" , action: :index, format: 'xls', project_id: @project }) + href: url_for({ controller: "cost_reports", action: :index, format: 'xls', project_id: @project }), + data: { + controller: "costs--export", + "application-target": "dynamic", + "costs--export-job-status-dialog-url-value": job_status_dialog_path('_job_uuid_'), + action: "click->costs--export#download" + } ) do |button| button.with_leading_visual_icon(icon: "op-file-xls-descriptions") t(:export_to_excel) end + header.with_action_button(scheme: :default, + aria: { label: t("export.timesheet.button") }, + title: t("export.timesheet.button"), + mobile_icon: "op-file-xls-descriptions", + mobile_label: t("export.timesheet.button"), + tag: :a, + href: url_for({ controller: "cost_reports", action: :index, format: 'pdf', project_id: @project }), + data: { + controller: "costs--export", + "application-target": "dynamic", + "costs--export-job-status-dialog-url-value": job_status_dialog_path('_job_uuid_'), + action: "click->costs--export#download" + } + ) do |button| + button.with_leading_visual_icon(icon: "op-file-xls-descriptions") + t("export.timesheet.button") + end call_hook(:view_cost_report_toolbar) end end diff --git a/modules/reporting/app/controllers/cost_reports_controller.rb b/modules/reporting/app/controllers/cost_reports_controller.rb index edb12e8baf26..80cefdf73c98 100644 --- a/modules/reporting/app/controllers/cost_reports_controller.rb +++ b/modules/reporting/app/controllers/cost_reports_controller.rb @@ -76,23 +76,38 @@ def check_cache def index table + return if performed? - unless performed? - respond_to do |format| - format.html do - session[report_engine.name.underscore.to_sym].try(:delete, :name) - render locals: { menu_name: project_or_global_menu } - end + respond_to do |format| + format.html { render_html } + format.xls { export(:xls) } + format.pdf { export(:pdf) } + end + end - format.xls do - job_id = ::CostQuery::ScheduleExportService - .new(user: current_user) - .call(filter_params:, project: @project, cost_types: @cost_types) - .result + def render_html + session[session_name].try(:delete, :name) + # get rid of unsaved filters and grouping + store_query(@query) if @query&.id != session[session_name].try(:id) + render locals: { menu_name: project_or_global_menu } + end - redirect_to job_status_path(job_id) - end - end + def export(format) + job_id = ::CostQuery::ScheduleExportService + .new(user: current_user) + .call( + format:, + query_id: @query.id, + query_name: @query.name, + filter_params: filter_params, + project: @project, + cost_types: @cost_types + ).result + + if request.headers["Accept"]&.include?("application/json") + render json: { job_id: } + else + redirect_to job_status_path(job_id) end end @@ -241,7 +256,7 @@ def default_filter_parameters # Get the filter params with an optional project context def filter_params filters = http_filter_parameters if set_filter? - filters ||= session[report_engine.name.underscore.to_sym].try(:[], :filters) + filters ||= session[session_name].try(:[], :filters) filters ||= default_filter_parameters update_project_context!(filters) @@ -253,7 +268,7 @@ def filter_params # Return the active group bys def group_params groups = http_group_parameters if set_filter? - groups ||= session[report_engine.name.underscore.to_sym].try(:[], :groups) + groups ||= session[session_name].try(:[], :groups) groups || default_group_parameters end @@ -358,7 +373,8 @@ def determine_engine # save_private_cost_reports permission as well # # @Override - def allowed_in_report?(action, report, user = User.current) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity + # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity + def allowed_in_report?(action, report, user = User.current) # admins may do everything return true if user.admin? @@ -390,6 +406,7 @@ def allowed_in_report?(action, report, user = User.current) # rubocop:disable Me Array(permissions).any? { |permission| user.allowed_in_any_project?(permission) } end end + # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity private @@ -399,8 +416,8 @@ def find_optional_user def get_filter_class(name) filter = report_engine::Filter - .all - .detect { |cls| cls.to_s.demodulize.underscore == name.to_s } + .all + .detect { |cls| cls.to_s.demodulize.underscore == name.to_s } raise ArgumentError.new("Filter with name #{name} does not exist.") unless filter @@ -479,8 +496,8 @@ def force_default? # Prepare the query from the request def prepare_query determine_settings - @query = build_query(session[report_engine.name.underscore.to_sym][:filters], - session[report_engine.name.underscore.to_sym][:groups]) + @query = build_query(session[session_name][:filters], + session[session_name][:groups]) set_cost_type if @unit_id.present? end @@ -489,16 +506,16 @@ def prepare_query # Determine the query settings the current request and save it to # the session. def determine_settings - if force_default? - filters = default_filter_parameters - groups = default_group_parameters - session[report_engine.name.underscore.to_sym].try :delete, :name - else - filters = filter_params - groups = group_params - end - cookie = session[report_engine.name.underscore.to_sym] || {} - session[report_engine.name.underscore.to_sym] = cookie.merge(filters:, groups:) + return reset_settings if force_default? + + cookie = session[session_name] || {} + session[session_name] = cookie.merge(filters: filter_params, groups: group_params) + end + + def reset_settings + session[session_name].try :delete, :name + cookie = session[session_name] || {} + session[session_name] = cookie.merge(filters: default_filter_parameters, groups: default_group_parameters) end ## @@ -524,16 +541,25 @@ def build_query(filters, groups = {}) # Store query in the session def store_query(_query) cookie = {} - cookie[:groups] = @query.group_bys.inject({}) do |h, group| - ((h[:"#{group.type}s"] ||= []) << group.underscore_name.to_sym) && h - end - cookie[:filters] = @query.filters.inject(operators: {}, values: {}) do |h, filter| + cookie[:groups] = cookie_groups + cookie[:filters] = cookie_filters + cookie[:name] = @query.name if @query.name + cookie[:id] = @query.id + session[session_name] = cookie + end + + def cookie_filters + @query.filters.inject(operators: {}, values: {}) do |h, filter| h[:operators][filter.underscore_name.to_sym] = filter.operator.to_s h[:values][filter.underscore_name.to_sym] = filter.values h end - cookie[:name] = @query.name if @query.name - session[report_engine.name.underscore.to_sym] = cookie + end + + def cookie_groups + @query.group_bys.inject({}) do |h, group| + ((h[:"#{group.type}s"] ||= []) << group.underscore_name.to_sym) && h + end end ## @@ -566,4 +592,8 @@ def find_optional_report(query = "1=0") end rescue ActiveRecord::RecordNotFound end + + def session_name + @session_name ||= report_engine.name.underscore.to_sym + end end diff --git a/modules/reporting/app/models/cost_query.rb b/modules/reporting/app/models/cost_query.rb index 4d29547b7f6d..5317137f98b3 100644 --- a/modules/reporting/app/models/cost_query.rb +++ b/modules/reporting/app/models/cost_query.rb @@ -85,6 +85,25 @@ def self.exists_in?(project, user) public(project).or(private(project, user)).exists? end + # rubocop:disable Metrics/AbcSize + def self.build_query(project, filters, groups = {}) + query = CostQuery.new(project:) + query.tap do |q| + filters[:operators].each do |filter, operator| + unless filters[:values][filter] == ["<>"] + values = Array(filters[:values][filter]).map { |v| v == "<>" ? nil : v } + q.filter(filter.to_sym, + operator:, + values:) + end + end + end + groups[:columns].try(:reverse_each) { |c| query.column(c) } + groups[:rows].try(:reverse_each) { |r| query.row(r) } + query + end + # rubocop:enable Metrics/AbcSize + def serialize # have to take the reverse group_bys to retain the original order when deserializing self.serialized = { filters: filters.map(&:serialize).reject(&:nil?).sort_by(&:first), diff --git a/modules/reporting/app/services/cost_query/schedule_export_service.rb b/modules/reporting/app/services/cost_query/schedule_export_service.rb index 991a38334040..7d2f0a336535 100644 --- a/modules/reporting/app/services/cost_query/schedule_export_service.rb +++ b/modules/reporting/app/services/cost_query/schedule_export_service.rb @@ -33,21 +33,24 @@ def initialize(user:) self.user = user end - def call(filter_params:, project:, cost_types:) + def call(format:, query_id:, query_name:, filter_params:, project:, cost_types:) export_storage = ::CostQuery::Export.create - job = schedule_export(export_storage, filter_params, project, cost_types) + job = schedule_export(format, export_storage, query_id, query_name, filter_params, project, cost_types) ServiceResult.success result: job.job_id end private - def schedule_export(export_storage, filter_params, project, cost_types) - ::CostQuery::ExportJob.perform_later(export: export_storage, - user:, - mime_type: :xls, - query: filter_params, - project:, - cost_types:) + def schedule_export(format, export_storage, query_id, query_name, filter_params, project, cost_types) + job = format == :pdf ? ::CostQuery::PDF::ExportTimesheetJob : ::CostQuery::XLS::ExportJob + job.perform_later(export: export_storage, + user:, + mime_type: format, + query_id:, + query_name:, + query: filter_params, + project:, + cost_types:) end end diff --git a/modules/reporting/app/workers/cost_query/pdf/export_timesheet_job.rb b/modules/reporting/app/workers/cost_query/pdf/export_timesheet_job.rb new file mode 100644 index 000000000000..058cb2061369 --- /dev/null +++ b/modules/reporting/app/workers/cost_query/pdf/export_timesheet_job.rb @@ -0,0 +1,40 @@ +require "active_storage/filename" + +class CostQuery::PDF::ExportTimesheetJob < Exports::ExportJob + self.model = ::CostQuery + + def project + options[:project] + end + + def title + I18n.t("export.timesheet.title") + end + + private + + def export! + handle_export_result(export, pdf_report_result) + end + + def prepare! + CostQuery::Cache.check + self.query = CostQuery.build_query(project, query) + query.name = options[:query_name] + end + + def pdf_report_result + content = generate_timesheet + time = Time.current.strftime("%Y-%m-%d-T-%H-%M-%S") + export_title = "timesheet-#{time}.pdf" + ::Exports::Result.new(format: :pdf, + title: export_title, + mime_type: "application/pdf", + content:) + end + + def generate_timesheet + generator = ::CostQuery::PDF::TimesheetGenerator.new(query, project) + generator.generate! + end +end diff --git a/modules/reporting/app/workers/cost_query/pdf/timesheet_generator.rb b/modules/reporting/app/workers/cost_query/pdf/timesheet_generator.rb new file mode 100644 index 000000000000..647daa18814b --- /dev/null +++ b/modules/reporting/app/workers/cost_query/pdf/timesheet_generator.rb @@ -0,0 +1,383 @@ +class CostQuery::PDF::TimesheetGenerator + include WorkPackage::PDFExport::Common::Common + include WorkPackage::PDFExport::Export::Cover + include WorkPackage::PDFExport::Common::Logo + include WorkPackage::PDFExport::Export::Page + include WorkPackage::PDFExport::Export::Style + + H1_FONT_SIZE = 26 + H1_MARGIN_BOTTOM = 2 + HR_MARGIN_BOTTOM = 16 + TABLE_CELL_FONT_SIZE = 10 + TABLE_CELL_BORDER_COLOR = "BBBBBB".freeze + TABLE_CELL_PADDING = 4 + COMMENT_FONT_COLOR = "636C76".freeze + H2_FONT_SIZE = 20 + H2_MARGIN_BOTTOM = 10 + COLUMN_DATE_WIDTH = 66 + COLUMN_ACTIVITY_WIDTH = 100 + COLUMN_HOURS_WIDTH = 60 + COLUMN_TIME_WIDTH = 110 + COLUMN_WP_WIDTH = 190 + + attr_accessor :pdf + + def initialize(query, project) + @query = query + @project = project + @total_page_nr = nil + @page_count = 1 + setup_page! + end + + def heading + query.name || I18n.t(:"export.timesheet.timesheet") + end + + def footer_title + heading + end + + def cover_page_title + "OpenProject" + end + + def cover_page_heading + heading + end + + def cover_page_dates + start_date, end_date = all_entries.map(&:spent_on).minmax + "#{format_date(start_date)} - #{format_date(end_date)}" if start_date && end_date + end + + def cover_page_subheading + User.current&.name + end + + def project + @project + end + + def query + @query + end + + def options + {} + end + + def setup_page! + self.pdf = get_pdf + configure_page_size!(:portrait) + pdf.title = heading + end + + def generate! + render_doc + if wants_total_page_nrs? + @total_page_nr = pdf.page_count + @page_count + @page_count = 1 + setup_page! # clear current pdf + render_doc + end + pdf.render + rescue StandardError => e + Rails.logger.error { "Failed to generate PDF: #{e} #{e.message}}." } + error(I18n.t(:error_pdf_failed_to_export, error: e.message)) + end + + def render_doc + write_cover_page! if with_cover? + write_heading! + write_hr! + write_entries! + write_headers! + write_footers! + end + + def write_entries! + all_entries + .group_by(&:user) + .each do |user, result| + write_table(user, result) + end + end + + def all_entries + @all_entries ||= query + .each_direct_result + .map(&:itself) + .filter { |r| r.fields["type"] == "TimeEntry" } + .map { |r| TimeEntry.find(r.fields["id"]) } + end + + def build_table_rows(entries) + rows = [table_header_columns] + entries + .group_by(&:spent_on) + .sort + .each do |spent_on, lines| + rows.concat(build_table_day_rows(spent_on, lines)) + end + rows + end + + def build_table_day_rows(spent_on, entries) + day_rows = [] + entries.each do |entry| + day_rows.push(build_table_row(spent_on, entry)) + if entry.comments.present? + day_rows.push(build_table_row_comment(entry)) + end + end + day_rows + end + + def build_table_row(spent_on, entry) + [ + { content: format_date(spent_on), rowspan: entry.comments.present? ? 2 : 1 }, + entry.work_package.subject || "", + with_times_column? ? format_spent_on_time(entry) : nil, + format_hours(entry.hours), + entry.activity&.name || "" + ].compact + end + + def build_table_row_comment(entry) + [{ + content: entry.comments, + text_color: COMMENT_FONT_COLOR, + font_style: :italic, + colspan: table_columns_widths.size + }] + end + + def table_header_columns + [ + { content: TimeEntry.human_attribute_name(:spent_on), rowspan: 1 }, + I18n.t(:"activerecord.models.work_package"), + with_times_column? ? I18n.t(:"export.timesheet.time") : nil, + TimeEntry.human_attribute_name(:hours), + TimeEntry.human_attribute_name(:activity) + ].compact + end + + def table_columns_widths + @table_columns_widths ||= if with_times_column? + [COLUMN_DATE_WIDTH, COLUMN_WP_WIDTH, COLUMN_TIME_WIDTH, COLUMN_HOURS_WIDTH, + COLUMN_ACTIVITY_WIDTH] + else + [COLUMN_DATE_WIDTH, COLUMN_WP_WIDTH + COLUMN_TIME_WIDTH, COLUMN_HOURS_WIDTH, + COLUMN_ACTIVITY_WIDTH] + end + end + + def build_table(rows) + pdf.make_table( + rows, + header: true, + width: table_columns_widths.sum, + column_widths: table_columns_widths, + cell_style: { + size: TABLE_CELL_FONT_SIZE, + border_color: TABLE_CELL_BORDER_COLOR, + border_width: 0.5, + borders: %i[top bottom], + padding: [TABLE_CELL_PADDING, TABLE_CELL_PADDING, TABLE_CELL_PADDING + 2, TABLE_CELL_PADDING] + } + ) do |table| + adjust_borders_first_column(table) + adjust_borders_last_column(table) + adjust_borders_spanned_column(table) + adjust_border_header_row(table) + end + end + + def adjust_borders_first_column(table) + table.columns(0).borders = %i[top bottom left right] + end + + def adjust_borders_last_column(table) + table.columns(table_columns_widths.length - 1).style do |c| + c.borders = c.borders + [:right] + end + end + + def adjust_borders_spanned_column(table) + table.columns(1).style do |c| + if c.colspan > 1 + c.borders = %i[left right bottom] + c.padding = [0, TABLE_CELL_PADDING, TABLE_CELL_PADDING + 2, TABLE_CELL_PADDING] + row_nr = c.row - 1 + values = table.columns(1..-1).rows(row_nr..row_nr) + values.each do |cell| + cell.borders = cell.borders - [:bottom] + end + end + end + end + + def adjust_border_header_row(table) + table.rows(0).style do |c| + c.borders = c.borders + [:top] + c.font_style = :bold + end + end + + def split_group_rows(table_rows) + measure_table = build_table(table_rows) + groups = [] + index = 0 + while index < table_rows.length + row = table_rows[index] + rows = [row] + height = measure_table.row(index).height + index += 1 + if (row[0][:rowspan] || 1) > 1 + rows.push(table_rows[index]) + height += measure_table.row(index).height + index += 1 + end + groups.push({ rows:, height: }) + end + groups + end + + def write_table(user, entries) + rows = build_table_rows(entries) + # prawn-table does not support splitting a rowspan cell on page break, so we have to merge the first column manually + # for easier handling existing rowspan cells are grouped as one row + grouped_rows = split_group_rows(rows) + # start a new page if the username would be printed alone at the end of the page + pdf.start_new_page if available_space_from_bottom < grouped_rows[0][:height] + grouped_rows[1][:height] + username_height + write_username(user) + write_grouped_tables(grouped_rows) + end + + def available_space_from_bottom + margin_bottom = pdf.options[:bottom_margin] + 20 # 20 is the safety margin + pdf.y - margin_bottom + end + + def write_grouped_tables(grouped_rows) + header_row = grouped_rows[0] + current_table = [] + current_table_height = 0 + grouped_rows.each do |grouped_row| + grouped_row_height = grouped_row[:height] + if current_table_height + grouped_row_height >= available_space_from_bottom + write_grouped_row_table(current_table) + pdf.start_new_page + current_table = [header_row] + current_table_height = header_row[:height] + end + current_table.push(grouped_row) + current_table_height += grouped_row_height + end + write_grouped_row_table(current_table) + pdf.move_down(28) + end + + def write_grouped_row_table(grouped_rows) + current_table = [] + merge_first_columns(grouped_rows) + grouped_rows.map! { |row| current_table.concat(row[:rows]) } + build_table(current_table).draw + end + + def merge_first_columns(grouped_rows) + last_row = grouped_rows[1] + index = 2 + while index < grouped_rows.length + grouped_row = grouped_rows[index] + last_row = merge_first_rows(grouped_row, last_row) + index += 1 + end + end + + def merge_first_rows(grouped_row, last_row) + grouped_cell = grouped_row[:rows][0][0] + last_cell = last_row[:rows][0][0] + if grouped_cell[:content] == last_cell[:content] + last_cell[:rowspan] += grouped_cell[:rowspan] + grouped_row[:rows][0].shift + last_row + else + grouped_row + end + end + + def sorted_results + query.each_direct_result.map(&:itself) + end + + def write_hr! + hr_style = styles.cover_header_border + write_horizontal_line(pdf.cursor, hr_style[:height], hr_style[:color]) + pdf.move_down(HR_MARGIN_BOTTOM) + end + + def write_heading! + pdf.formatted_text([{ text: heading, size: H1_FONT_SIZE, style: :bold }]) + pdf.move_down(H1_MARGIN_BOTTOM) + end + + def username_height + 20 + 10 + end + + def write_username(user) + pdf.formatted_text([{ text: user.name, size: H2_FONT_SIZE }]) + pdf.move_down(H2_MARGIN_BOTTOM) + end + + def footer_date + if pdf.page_number == 1 + format_time(Time.zone.now) + else + format_date(Time.zone.now) + end + end + + def format_hours(hours) + return "" if hours < 0 + + DurationConverter.output(hours) + end + + def format_spent_on_time(entry) + start_timestamp = entry.start_timestamp + return "" if start_timestamp.nil? + + result = format_time(start_timestamp, include_date: false) + end_timestamp = entry.end_timestamp + return result if end_timestamp.nil? + + days_between_suffix = format_days_between(start_timestamp, end_timestamp) + "#{result} - #{format_time(end_timestamp, include_date: false)}#{days_between_suffix}" + end + + def format_days_between(start_timestamp, end_timestamp) + days_between = (end_timestamp.to_date - start_timestamp.to_date).to_i + if days_between.positive? + " (+#{days_formatter.format_value(days_between, nil).delete(' ')})" + end + end + + def days_formatter + @days_formatter ||= WorkPackage::Exports::Formatters::Days.new(nil) + end + + def with_times_column? + Setting.allow_tracking_start_and_end_times + end + + def with_cover? + true + end + + def wants_total_page_nrs? + true + end +end diff --git a/modules/reporting/app/workers/cost_query/export_job.rb b/modules/reporting/app/workers/cost_query/xls/export_job.rb similarity index 56% rename from modules/reporting/app/workers/cost_query/export_job.rb rename to modules/reporting/app/workers/cost_query/xls/export_job.rb index baf38d88896b..e9cdda62daab 100644 --- a/modules/reporting/app/workers/cost_query/export_job.rb +++ b/modules/reporting/app/workers/cost_query/xls/export_job.rb @@ -1,12 +1,8 @@ require "active_storage/filename" -class CostQuery::ExportJob < Exports::ExportJob +class CostQuery::XLS::ExportJob < Exports::ExportJob self.model = ::CostQuery - def title - I18n.t("export.cost_reports.title") - end - def project options[:project] end @@ -15,11 +11,15 @@ def cost_types options[:cost_types] end + def title + I18n.t("export.cost_reports.title") + end + private def prepare! CostQuery::Cache.check - self.query = build_query(query) + self.query = CostQuery.build_query(project, query) end def export! @@ -39,24 +39,4 @@ def xls_report_result mime_type: "application/vnd.ms-excel", content:) end - - # rubocop:disable Metrics/AbcSize - def build_query(filters, groups = {}) - query = CostQuery.new(project:) - query.tap do |q| - filters[:operators].each do |filter, operator| - unless filters[:values][filter] == ["<>"] - values = Array(filters[:values][filter]).map { |v| v == "<>" ? nil : v } - q.filter(filter.to_sym, - operator:, - values:) - end - end - end - groups[:columns].try(:reverse_each) { |c| query.column(c) } - groups[:rows].try(:reverse_each) { |r| query.row(r) } - query - end - - # rubocop:enable Metrics/AbcSize end diff --git a/modules/reporting/config/locales/crowdin/af.yml b/modules/reporting/config/locales/crowdin/af.yml index f617532533bc..57c062824a6c 100644 --- a/modules/reporting/config/locales/crowdin/af.yml +++ b/modules/reporting/config/locales/crowdin/af.yml @@ -86,6 +86,11 @@ af: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/ar.yml b/modules/reporting/config/locales/crowdin/ar.yml index 61c27bfd8a3c..6bc2fadeb24e 100644 --- a/modules/reporting/config/locales/crowdin/ar.yml +++ b/modules/reporting/config/locales/crowdin/ar.yml @@ -86,6 +86,11 @@ ar: validation_failure_date: "ليس تاريخًا صالحًا" validation_failure_integer: "ليس عددًا صحيحًا صالحًا" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/az.yml b/modules/reporting/config/locales/crowdin/az.yml index 4e5ffec447cd..8494a1d7445e 100644 --- a/modules/reporting/config/locales/crowdin/az.yml +++ b/modules/reporting/config/locales/crowdin/az.yml @@ -86,6 +86,11 @@ az: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/be.yml b/modules/reporting/config/locales/crowdin/be.yml index 8e2f2499f896..738a5431b765 100644 --- a/modules/reporting/config/locales/crowdin/be.yml +++ b/modules/reporting/config/locales/crowdin/be.yml @@ -86,6 +86,11 @@ be: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/bg.yml b/modules/reporting/config/locales/crowdin/bg.yml index 6078453933e1..2b6dbcff67d2 100644 --- a/modules/reporting/config/locales/crowdin/bg.yml +++ b/modules/reporting/config/locales/crowdin/bg.yml @@ -86,6 +86,11 @@ bg: validation_failure_date: "не е валидна дата" validation_failure_integer: "не е валидно цяло число" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Вашият износ на отчети за разходите XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/ca.yml b/modules/reporting/config/locales/crowdin/ca.yml index b916dcbeec3d..aef19f3a48d4 100644 --- a/modules/reporting/config/locales/crowdin/ca.yml +++ b/modules/reporting/config/locales/crowdin/ca.yml @@ -86,6 +86,11 @@ ca: validation_failure_date: "no és una data vàlida" validation_failure_integer: "no és un enter vàlid" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "La teva exportació de l'informe de costos XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/ckb-IR.yml b/modules/reporting/config/locales/crowdin/ckb-IR.yml index d35738b1e445..64b6bc7ffa5c 100644 --- a/modules/reporting/config/locales/crowdin/ckb-IR.yml +++ b/modules/reporting/config/locales/crowdin/ckb-IR.yml @@ -86,6 +86,11 @@ ckb-IR: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/cs.yml b/modules/reporting/config/locales/crowdin/cs.yml index 0324c1791dfb..3f93c723e73a 100644 --- a/modules/reporting/config/locales/crowdin/cs.yml +++ b/modules/reporting/config/locales/crowdin/cs.yml @@ -86,6 +86,11 @@ cs: validation_failure_date: "není platné datum" validation_failure_integer: "není platné číslo" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Váš export XLS zprávy o nákladech" reporting: diff --git a/modules/reporting/config/locales/crowdin/da.yml b/modules/reporting/config/locales/crowdin/da.yml index a3c882ab617d..41e76bce110e 100644 --- a/modules/reporting/config/locales/crowdin/da.yml +++ b/modules/reporting/config/locales/crowdin/da.yml @@ -86,6 +86,11 @@ da: validation_failure_date: "er en ugyldig dato" validation_failure_integer: "er et ugyldigt heltal" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/de.yml b/modules/reporting/config/locales/crowdin/de.yml index 6030bae93c88..c2095cf00632 100644 --- a/modules/reporting/config/locales/crowdin/de.yml +++ b/modules/reporting/config/locales/crowdin/de.yml @@ -86,6 +86,11 @@ de: validation_failure_date: "ist kein gültiges Datum" validation_failure_integer: "ist keine ganze Zahl" export: + timesheet: + title: "Ihr PDF-Export des Stundenzettels" + button: "Stundenzettel als PDF exportieren" + timesheet: "Stundenzettel" + time: "Stunden" cost_reports: title: "Kostenbericht als XLS-Export" reporting: diff --git a/modules/reporting/config/locales/crowdin/el.yml b/modules/reporting/config/locales/crowdin/el.yml index f9915dd7309f..7f3b0f679be9 100644 --- a/modules/reporting/config/locales/crowdin/el.yml +++ b/modules/reporting/config/locales/crowdin/el.yml @@ -86,6 +86,11 @@ el: validation_failure_date: "δεν είναι έγκυρη ημερομηνία" validation_failure_integer: "δεν είναι έγκυρος ακέραιος αριθμός" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/eo.yml b/modules/reporting/config/locales/crowdin/eo.yml index 9dcef2eba7c3..bce2b1795803 100644 --- a/modules/reporting/config/locales/crowdin/eo.yml +++ b/modules/reporting/config/locales/crowdin/eo.yml @@ -86,6 +86,11 @@ eo: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/es.yml b/modules/reporting/config/locales/crowdin/es.yml index 3f00d37bf8d0..267525b0eb41 100644 --- a/modules/reporting/config/locales/crowdin/es.yml +++ b/modules/reporting/config/locales/crowdin/es.yml @@ -86,6 +86,11 @@ es: validation_failure_date: "no es una fecha válida" validation_failure_integer: "no es un entero válido" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Su exportación de informes de costes XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/et.yml b/modules/reporting/config/locales/crowdin/et.yml index 4a183d25bf69..11fd40508e8d 100644 --- a/modules/reporting/config/locales/crowdin/et.yml +++ b/modules/reporting/config/locales/crowdin/et.yml @@ -86,6 +86,11 @@ et: validation_failure_date: "pole korrektne kuupäev" validation_failure_integer: "pole täisarv" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/eu.yml b/modules/reporting/config/locales/crowdin/eu.yml index 42288069c064..db594cb00694 100644 --- a/modules/reporting/config/locales/crowdin/eu.yml +++ b/modules/reporting/config/locales/crowdin/eu.yml @@ -86,6 +86,11 @@ eu: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/fa.yml b/modules/reporting/config/locales/crowdin/fa.yml index fa647885b55b..05b1ba74b22a 100644 --- a/modules/reporting/config/locales/crowdin/fa.yml +++ b/modules/reporting/config/locales/crowdin/fa.yml @@ -86,6 +86,11 @@ fa: validation_failure_date: "is not a valid date" validation_failure_integer: "عدد درست نیست" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/fi.yml b/modules/reporting/config/locales/crowdin/fi.yml index f830e2d37663..9a2748920c48 100644 --- a/modules/reporting/config/locales/crowdin/fi.yml +++ b/modules/reporting/config/locales/crowdin/fi.yml @@ -86,6 +86,11 @@ fi: validation_failure_date: "ei ole kelvollinen päivämäärä" validation_failure_integer: "ei ole kelvollinen kokonaisluku" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/fil.yml b/modules/reporting/config/locales/crowdin/fil.yml index bdb0afc98457..cf1237ed162b 100644 --- a/modules/reporting/config/locales/crowdin/fil.yml +++ b/modules/reporting/config/locales/crowdin/fil.yml @@ -86,6 +86,11 @@ fil: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/fr.yml b/modules/reporting/config/locales/crowdin/fr.yml index 056f59b49830..e003694e2fc5 100644 --- a/modules/reporting/config/locales/crowdin/fr.yml +++ b/modules/reporting/config/locales/crowdin/fr.yml @@ -86,6 +86,11 @@ fr: validation_failure_date: "n'est pas une date valide" validation_failure_integer: "n'est pas un nombre entier valide" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Exportation XLS de vos rapports de coûts" reporting: diff --git a/modules/reporting/config/locales/crowdin/he.yml b/modules/reporting/config/locales/crowdin/he.yml index 473775a2ca90..1b6c555c0731 100644 --- a/modules/reporting/config/locales/crowdin/he.yml +++ b/modules/reporting/config/locales/crowdin/he.yml @@ -86,6 +86,11 @@ he: validation_failure_date: "אינו תאריך בר תוקף" validation_failure_integer: "אינו מספר שלם חוקי" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/hi.yml b/modules/reporting/config/locales/crowdin/hi.yml index 71ab923ff234..b1d47b506e16 100644 --- a/modules/reporting/config/locales/crowdin/hi.yml +++ b/modules/reporting/config/locales/crowdin/hi.yml @@ -86,6 +86,11 @@ hi: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/hr.yml b/modules/reporting/config/locales/crowdin/hr.yml index 6c7b53f73e44..28a98ea6434b 100644 --- a/modules/reporting/config/locales/crowdin/hr.yml +++ b/modules/reporting/config/locales/crowdin/hr.yml @@ -86,6 +86,11 @@ hr: validation_failure_date: "nije valjan datum" validation_failure_integer: "nije valjan cijeli broj" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/hu.yml b/modules/reporting/config/locales/crowdin/hu.yml index f07d543052be..78d965eee2e0 100644 --- a/modules/reporting/config/locales/crowdin/hu.yml +++ b/modules/reporting/config/locales/crowdin/hu.yml @@ -86,6 +86,11 @@ hu: validation_failure_date: "nem érvényes dátum" validation_failure_integer: "nem érvényes egész szám" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Költségjelentés készítése XLS formában" reporting: diff --git a/modules/reporting/config/locales/crowdin/id.yml b/modules/reporting/config/locales/crowdin/id.yml index b9d31e7e6ec4..87ee230dbd6b 100644 --- a/modules/reporting/config/locales/crowdin/id.yml +++ b/modules/reporting/config/locales/crowdin/id.yml @@ -86,6 +86,11 @@ id: validation_failure_date: "validasi tanggal gagal" validation_failure_integer: "validasi bilangan bulat gagal" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Ekspor XLS Laporan Biaya Anda" reporting: diff --git a/modules/reporting/config/locales/crowdin/it.yml b/modules/reporting/config/locales/crowdin/it.yml index d68fba3b8275..1effcdbdcca4 100644 --- a/modules/reporting/config/locales/crowdin/it.yml +++ b/modules/reporting/config/locales/crowdin/it.yml @@ -86,6 +86,11 @@ it: validation_failure_date: "non è una data valida" validation_failure_integer: "non è un numero intero valido" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Esportazione XLS dei report sui costi" reporting: diff --git a/modules/reporting/config/locales/crowdin/ja.yml b/modules/reporting/config/locales/crowdin/ja.yml index d73d1a3f1d9e..f4e5a172fbfb 100644 --- a/modules/reporting/config/locales/crowdin/ja.yml +++ b/modules/reporting/config/locales/crowdin/ja.yml @@ -86,6 +86,11 @@ ja: validation_failure_date: "は有効な日付ではありません。" validation_failure_integer: "は有効な整数ではありません。" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "あなたのコストレポートXLSのエクスポート" reporting: diff --git a/modules/reporting/config/locales/crowdin/ka.yml b/modules/reporting/config/locales/crowdin/ka.yml index 93685fdcb025..17f4b561e06e 100644 --- a/modules/reporting/config/locales/crowdin/ka.yml +++ b/modules/reporting/config/locales/crowdin/ka.yml @@ -86,6 +86,11 @@ ka: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/kk.yml b/modules/reporting/config/locales/crowdin/kk.yml index 8bf1fb6095da..0879b51229e1 100644 --- a/modules/reporting/config/locales/crowdin/kk.yml +++ b/modules/reporting/config/locales/crowdin/kk.yml @@ -86,6 +86,11 @@ kk: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/ko.yml b/modules/reporting/config/locales/crowdin/ko.yml index ab4a55fcc858..41ea6afd4bc8 100644 --- a/modules/reporting/config/locales/crowdin/ko.yml +++ b/modules/reporting/config/locales/crowdin/ko.yml @@ -86,6 +86,11 @@ ko: validation_failure_date: "은(는) 유효한 날짜가 아닙니다." validation_failure_integer: "은(는) 유효한 정수가 아닙니다." export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "비용 리포트 XML로 내보내기" reporting: diff --git a/modules/reporting/config/locales/crowdin/lt.yml b/modules/reporting/config/locales/crowdin/lt.yml index 77c767edddeb..4463ae0a5c5f 100644 --- a/modules/reporting/config/locales/crowdin/lt.yml +++ b/modules/reporting/config/locales/crowdin/lt.yml @@ -86,6 +86,11 @@ lt: validation_failure_date: "nėra tinkama data" validation_failure_integer: "nėra tinkamas sveikas skaičius" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Jūsų kainos ataskaitų XLS eksportas" reporting: diff --git a/modules/reporting/config/locales/crowdin/lv.yml b/modules/reporting/config/locales/crowdin/lv.yml index 3d3b7742aad0..a3fd4fbbcd3b 100644 --- a/modules/reporting/config/locales/crowdin/lv.yml +++ b/modules/reporting/config/locales/crowdin/lv.yml @@ -86,6 +86,11 @@ lv: validation_failure_date: "nav derīgs datums" validation_failure_integer: "nav derīgs vesels skaitlis" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/mn.yml b/modules/reporting/config/locales/crowdin/mn.yml index a19f68253498..d6254bf6dff7 100644 --- a/modules/reporting/config/locales/crowdin/mn.yml +++ b/modules/reporting/config/locales/crowdin/mn.yml @@ -86,6 +86,11 @@ mn: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/ms.yml b/modules/reporting/config/locales/crowdin/ms.yml index 0d016ef01e5e..5f23570547a5 100644 --- a/modules/reporting/config/locales/crowdin/ms.yml +++ b/modules/reporting/config/locales/crowdin/ms.yml @@ -86,6 +86,11 @@ ms: validation_failure_date: "bukan tarikh yang sah" validation_failure_integer: "bukan integer yang sah" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Eksport Laporan Kos XLS anda" reporting: diff --git a/modules/reporting/config/locales/crowdin/ne.yml b/modules/reporting/config/locales/crowdin/ne.yml index e4653bd905e5..05f56d7be845 100644 --- a/modules/reporting/config/locales/crowdin/ne.yml +++ b/modules/reporting/config/locales/crowdin/ne.yml @@ -86,6 +86,11 @@ ne: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/nl.yml b/modules/reporting/config/locales/crowdin/nl.yml index 13c1214251bd..4886eb0a91c7 100644 --- a/modules/reporting/config/locales/crowdin/nl.yml +++ b/modules/reporting/config/locales/crowdin/nl.yml @@ -86,6 +86,11 @@ nl: validation_failure_date: "is geen geldige datum" validation_failure_integer: "is geen geldig geheel getal" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Jouw kostenrapporten XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/no.yml b/modules/reporting/config/locales/crowdin/no.yml index c2e8bf679c9e..385d44f3b806 100644 --- a/modules/reporting/config/locales/crowdin/no.yml +++ b/modules/reporting/config/locales/crowdin/no.yml @@ -86,6 +86,11 @@ validation_failure_date: "er ikke en gyldig dato" validation_failure_integer: "er ikke et gyldig heltall" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Din XLS-eksport av kostnadsrapporter" reporting: diff --git a/modules/reporting/config/locales/crowdin/pl.yml b/modules/reporting/config/locales/crowdin/pl.yml index 33ea7fac3472..2ed80df4401f 100644 --- a/modules/reporting/config/locales/crowdin/pl.yml +++ b/modules/reporting/config/locales/crowdin/pl.yml @@ -86,6 +86,11 @@ pl: validation_failure_date: "nie jest poprawną datą" validation_failure_integer: "nie jest prawidłową liczbą całkowitą" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Twój eksport raportów kosztów w formacie XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/pt-BR.yml b/modules/reporting/config/locales/crowdin/pt-BR.yml index 6d1af56ae022..133681a4225a 100644 --- a/modules/reporting/config/locales/crowdin/pt-BR.yml +++ b/modules/reporting/config/locales/crowdin/pt-BR.yml @@ -86,6 +86,11 @@ pt-BR: validation_failure_date: "não é uma data válida" validation_failure_integer: "não é um valor inteiro válido" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Exportação XLS dos seus relatórios de custos" reporting: diff --git a/modules/reporting/config/locales/crowdin/pt-PT.yml b/modules/reporting/config/locales/crowdin/pt-PT.yml index eb8aa480d16f..4e65251fce00 100644 --- a/modules/reporting/config/locales/crowdin/pt-PT.yml +++ b/modules/reporting/config/locales/crowdin/pt-PT.yml @@ -86,6 +86,11 @@ pt-PT: validation_failure_date: "não é uma data válida" validation_failure_integer: "não é um número inteiro válido" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "A sua exportação dos Relatórios de Custo XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/ro.yml b/modules/reporting/config/locales/crowdin/ro.yml index 5f31498f5544..cb21c3270e08 100644 --- a/modules/reporting/config/locales/crowdin/ro.yml +++ b/modules/reporting/config/locales/crowdin/ro.yml @@ -86,6 +86,11 @@ ro: validation_failure_date: "nu e o dată validă" validation_failure_integer: "nu e un întreg valid" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Exportul dumneavoastră de rapoarte de costuri XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/ru.yml b/modules/reporting/config/locales/crowdin/ru.yml index cf25ab9cc973..02fdaa9f09f4 100644 --- a/modules/reporting/config/locales/crowdin/ru.yml +++ b/modules/reporting/config/locales/crowdin/ru.yml @@ -86,6 +86,11 @@ ru: validation_failure_date: "не является допустимой датой" validation_failure_integer: "не является допустимым целым числом" export: + timesheet: + title: "Ваши табели учета рабочего времени, экспортированные в PDF" + button: "Экспорт табеля учета рабочего времени в PDF" + timesheet: "Табель учета рабочего времени" + time: "Время" cost_reports: title: "Экспорт ваших отчетов о затратах в XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/rw.yml b/modules/reporting/config/locales/crowdin/rw.yml index 6a276a232a8a..19c783f56867 100644 --- a/modules/reporting/config/locales/crowdin/rw.yml +++ b/modules/reporting/config/locales/crowdin/rw.yml @@ -86,6 +86,11 @@ rw: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/si.yml b/modules/reporting/config/locales/crowdin/si.yml index 95217d9ed61e..09b324f68034 100644 --- a/modules/reporting/config/locales/crowdin/si.yml +++ b/modules/reporting/config/locales/crowdin/si.yml @@ -86,6 +86,11 @@ si: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/sk.yml b/modules/reporting/config/locales/crowdin/sk.yml index 61797830140e..826a97504012 100644 --- a/modules/reporting/config/locales/crowdin/sk.yml +++ b/modules/reporting/config/locales/crowdin/sk.yml @@ -86,6 +86,11 @@ sk: validation_failure_date: "nie je platný dátum" validation_failure_integer: "nie je platné celé číslo" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Váš XLS export správy o nákladoch" reporting: diff --git a/modules/reporting/config/locales/crowdin/sl.yml b/modules/reporting/config/locales/crowdin/sl.yml index da32b0289575..8743ad06ceb5 100644 --- a/modules/reporting/config/locales/crowdin/sl.yml +++ b/modules/reporting/config/locales/crowdin/sl.yml @@ -86,6 +86,11 @@ sl: validation_failure_date: "ni veljaven datum" validation_failure_integer: "ni veljavno število" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/sr.yml b/modules/reporting/config/locales/crowdin/sr.yml index 7d67c2b20d9c..54409bbea091 100644 --- a/modules/reporting/config/locales/crowdin/sr.yml +++ b/modules/reporting/config/locales/crowdin/sr.yml @@ -86,6 +86,11 @@ sr: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/sv.yml b/modules/reporting/config/locales/crowdin/sv.yml index 13138c8c653c..8a989f5df991 100644 --- a/modules/reporting/config/locales/crowdin/sv.yml +++ b/modules/reporting/config/locales/crowdin/sv.yml @@ -86,6 +86,11 @@ sv: validation_failure_date: "inte är ett giltigt datum" validation_failure_integer: "är inte ett giltigt heltal" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/th.yml b/modules/reporting/config/locales/crowdin/th.yml index c145befd0d23..9e86a22d4db0 100644 --- a/modules/reporting/config/locales/crowdin/th.yml +++ b/modules/reporting/config/locales/crowdin/th.yml @@ -86,6 +86,11 @@ th: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/tr.yml b/modules/reporting/config/locales/crowdin/tr.yml index 27927363d31f..08170e99acb4 100644 --- a/modules/reporting/config/locales/crowdin/tr.yml +++ b/modules/reporting/config/locales/crowdin/tr.yml @@ -86,6 +86,11 @@ tr: validation_failure_date: "geçerli bir tarih değil" validation_failure_integer: "geçerli bir tamsayı değil" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Maliyet Raporlarınızın XLS çıktısı" reporting: diff --git a/modules/reporting/config/locales/crowdin/uk.yml b/modules/reporting/config/locales/crowdin/uk.yml index 1216f353b5b3..06b770cc8e67 100644 --- a/modules/reporting/config/locales/crowdin/uk.yml +++ b/modules/reporting/config/locales/crowdin/uk.yml @@ -86,6 +86,11 @@ uk: validation_failure_date: "є недійсною датою" validation_failure_integer: "не є дійсним цілим числом" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Експорт звітів про витрати у форматі XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/uz.yml b/modules/reporting/config/locales/crowdin/uz.yml index e64740d92200..32a28ee62f74 100644 --- a/modules/reporting/config/locales/crowdin/uz.yml +++ b/modules/reporting/config/locales/crowdin/uz.yml @@ -86,6 +86,11 @@ uz: validation_failure_date: "is not a valid date" validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" reporting: diff --git a/modules/reporting/config/locales/crowdin/vi.yml b/modules/reporting/config/locales/crowdin/vi.yml index 7a9b5ff2a4ba..b561f31aac02 100644 --- a/modules/reporting/config/locales/crowdin/vi.yml +++ b/modules/reporting/config/locales/crowdin/vi.yml @@ -86,6 +86,11 @@ vi: validation_failure_date: "không phải là một ngày hợp lệ" validation_failure_integer: "không phải là một số nguyên hợp lệ" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Xuất báo cáo chi phí của bạn sang XLS" reporting: diff --git a/modules/reporting/config/locales/crowdin/zh-CN.yml b/modules/reporting/config/locales/crowdin/zh-CN.yml index 65a1822a5020..818a44fb11a1 100644 --- a/modules/reporting/config/locales/crowdin/zh-CN.yml +++ b/modules/reporting/config/locales/crowdin/zh-CN.yml @@ -86,6 +86,11 @@ zh-CN: validation_failure_date: "不是有效的日期" validation_failure_integer: "不是有效的整数" export: + timesheet: + title: "您的 PDF 时间表导出" + button: "导出 PDF 时间表" + timesheet: "时间表" + time: "时间" cost_reports: title: "您的成本报告 XLS 导出" reporting: diff --git a/modules/reporting/config/locales/crowdin/zh-TW.yml b/modules/reporting/config/locales/crowdin/zh-TW.yml index 840da7555707..39ae5f42ceb1 100644 --- a/modules/reporting/config/locales/crowdin/zh-TW.yml +++ b/modules/reporting/config/locales/crowdin/zh-TW.yml @@ -86,6 +86,11 @@ zh-TW: validation_failure_date: "不是一個有效日期" validation_failure_integer: "不是一個有效的整數" export: + timesheet: + title: "您的時間表PDF匯出" + button: "匯出 PDF 時間表" + timesheet: "時間表" + time: "時間" cost_reports: title: "您的成本報表(以XLS匯出)" reporting: diff --git a/modules/reporting/config/locales/en.yml b/modules/reporting/config/locales/en.yml index f028c008e55a..1b56799a2c02 100644 --- a/modules/reporting/config/locales/en.yml +++ b/modules/reporting/config/locales/en.yml @@ -105,6 +105,11 @@ en: validation_failure_integer: "is not a valid integer" export: + timesheet: + title: "Your PDF timesheet export" + button: "Export PDF timesheet" + timesheet: "Timesheet" + time: "Time" cost_reports: title: "Your Cost Reports XLS export" diff --git a/modules/reporting/spec/features/export_timesheet_spec.rb b/modules/reporting/spec/features/export_timesheet_spec.rb new file mode 100644 index 000000000000..35f552fc9611 --- /dev/null +++ b/modules/reporting/spec/features/export_timesheet_spec.rb @@ -0,0 +1,64 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require_relative "../spec_helper" +require_relative "support/pages/cost_report_page" + +RSpec.describe "Timesheet PDF export", :js do + shared_let(:project) { create(:project) } + shared_let(:user) { create(:admin) } + shared_let(:cost_type) { create(:cost_type, name: "Post-war", unit: "cap", unit_plural: "caps") } + shared_let(:work_package) { create(:work_package, project:, subject: "Some task") } + shared_let(:cost_entry) { create(:cost_entry, user:, work_package:, project:, cost_type:) } + let(:report_page) { Pages::CostReportPage.new project } + + subject { @download_list.refresh_from(page).latest_download.to_s } # rubocop:disable RSpec/InstanceVariable + + before do + @download_list = DownloadList.new + login_as(user) + end + + after do + DownloadList.clear + end + + it "can download the PDF" do + report_page.visit! + click_on I18n.t("export.timesheet.button") + + expect(page).to have_content I18n.t("job_status_dialog.generic_messages.in_queue"), + wait: 10 + perform_enqueued_jobs + + expect(page).to have_text(I18n.t("export.succeeded"), + wait: 10) + + expect(subject).to have_text(".pdf") + end +end diff --git a/modules/reporting/spec/workers/cost_query/pdf/export_timesheet_job_spec.rb b/modules/reporting/spec/workers/cost_query/pdf/export_timesheet_job_spec.rb new file mode 100644 index 000000000000..3bafe2f2f073 --- /dev/null +++ b/modules/reporting/spec/workers/cost_query/pdf/export_timesheet_job_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" + +RSpec.describe CostQuery::PDF::ExportTimesheetJob do + let(:user) { build_stubbed(:user) } + let(:project) { build_stubbed(:project) } + + let(:initial_filter_params) do + { + project_context: project.id, + operators: { + user_id: "=", spent_on: ">d", project_id: "=" + }, + values: { + user_id: ["me"], spent_on: ["2024-03-30", ""], project_id: [project.id.to_s] + } + } + end + + before do + mock_permissions_for(user, &:allow_everything) + end + + # Performs a cost export with the given extra filters. + # + # @param extra_filters [Hash] A hash of attribute names and operator/value + # pairs to add to the filter. + # Example: `{ custom_field_17: ["=", "value"], user_id: ["=", "me"]}` + def perform_cost_export(extra_filters: {}) + query = initial_filter_params.deep_dup + extra_filters.each do |attribute_name, operator_and_value| + operator, value = operator_and_value + query[:operators][attribute_name] = operator + query[:values][attribute_name] = value + end + job = described_class.new( + export: CostQuery::Export.create, + user:, + mime_type: :pdf, + query:, + project:, + cost_types: [-1, 0] + ) + job.perform_now + job + end + + RSpec::Matchers.define :have_one_attachment_with_content_type do |expected_content_type| + def attachments(export_job) + export_job.status_reference.attachments + end + + match do |export_job| + attachments_content_types = attachments(export_job).pluck(:content_type) + attachments_content_types == [expected_content_type] + end + + failure_message do |export_job| + attachments_content_types = attachments(export_job).pluck(:content_type) + "expected that #{actual} would have one attachment with mime type #{expected.inspect}, " \ + "got #{attachments_content_types.inspect} instead" + end + end + + it "generates an PDF export successfully" do + job = perform_cost_export + + expect(job.job_status).to be_success, job.job_status.message + expect(job).to have_one_attachment_with_content_type("application/pdf") + end +end diff --git a/modules/reporting/spec/workers/cost_query/pdf/timesheet_generator_spec.rb b/modules/reporting/spec/workers/cost_query/pdf/timesheet_generator_spec.rb new file mode 100644 index 000000000000..064576698e21 --- /dev/null +++ b/modules/reporting/spec/workers/cost_query/pdf/timesheet_generator_spec.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" +require "pdf/inspector" + +RSpec.describe CostQuery::PDF::TimesheetGenerator do + include Redmine::I18n + let(:query) { create(:cost_query) } + let(:user) { create(:user, firstname: "Export", lastname: "User") } + let(:time_entry_user) { create(:user, firstname: "TimeEntry", lastname: "User") } + let(:project) { create(:project) } + let(:generator) { described_class.new(query, project) } + let(:export_time) { DateTime.new(2024, 12, 4, 23, 59) } + let(:export_time_formatted) { format_time(export_time, include_date: true) } + let(:export_date_formatted) { format_date(export_time) } + let(:user_time_entry) do + create(:time_entry, + project:, + user: user, + spent_on: Date.new(2024, 12, 0o1), + start_time: 8 * 60, + time_zone: "UTC") + end + let(:time_entry) do + create(:time_entry, + project:, + user: time_entry_user, + spent_on: Date.new(2024, 12, 0o1), + start_time: 9 * 60, + time_zone: "UTC") + end + let(:other_time_entry) do + create(:time_entry, + project:, + user: time_entry_user, + spent_on: Date.new(2024, 12, 0o1), + start_time: 10 * 60, + time_zone: "UTC") + end + let(:time_entry_with_comment) do + create(:time_entry, + project:, + user: time_entry_user, + comments: "This is a comment", + spent_on: Date.new(2024, 12, 0o2)) + end + let(:time_entry_without_time) do + create(:time_entry, + project:, + user: time_entry_user, + spent_on: Date.new(2024, 12, 0o3)) + end + let(:time_entries) { [user_time_entry, time_entry, other_time_entry, time_entry_with_comment, time_entry_without_time] } + + before do + User.current = user + allow(generator).to receive(:all_entries).and_return(time_entries) + end + + subject(:pdf) do + content = Timecop.freeze(export_time) do + generator.generate! + end + # If you want to actually see the PDF for debugging, uncomment the following line + # File.binwrite("TimesheetGenerator-test-preview.pdf", content) + PDF::Inspector::Text.analyze(content).strings.join(" ") + end + + def expected_cover_page + ["OpenProject", query.name, + time_entries.empty? ? nil : "#{format_date(time_entries.first.spent_on)} - #{format_date(time_entries.last.spent_on)}", + user.name, export_time_formatted].compact + end + + def expected_first_page_content + [query.name] + end + + def expected_table_header(with_times_column) + [ + I18n.t(:"activerecord.attributes.time_entry.spent_on"), + I18n.t(:"activerecord.models.work_package"), + with_times_column ? I18n.t(:"export.timesheet.time") : nil, + I18n.t(:"activerecord.attributes.time_entry.hours"), + I18n.t(:"activerecord.attributes.time_entry.activity") + ].compact + end + + def expected_page_footer(page_number) + [page_number, export_date_formatted, query.name] + end + + def expected_entry_row(t_entry, with_times_column) + [format_date(t_entry.spent_on)].concat(expected_entry_columns(t_entry, with_times_column)) + end + + def expected_entry_columns(t_entry, with_times_column) + time_column = generator.format_spent_on_time(t_entry) + [ + t_entry.work_package.subject, + with_times_column && time_column.present? ? time_column : nil, + generator.format_hours(t_entry.hours), + t_entry.activity.name, + t_entry.comments + ].compact + end + + def expected_document(with_times_column) + [ + *expected_cover_page, + *expected_first_page_content, + + user.name, + *expected_table_header(with_times_column), + *expected_entry_row(user_time_entry, with_times_column), + + time_entry.user.name, + *expected_table_header(with_times_column), + format_date(time_entry.spent_on), # merged date rows + *expected_entry_columns(time_entry, with_times_column), + *expected_entry_columns(other_time_entry, with_times_column), + *expected_entry_row(time_entry_with_comment, with_times_column), + *expected_entry_row(time_entry_without_time, with_times_column), + + *expected_page_footer("2/2") + ].join(" ") + end + + context "with allow_tracking_start_and_end_times", with_settings: { allow_tracking_start_and_end_times: true } do + it "renders the expected document" do + expect(subject).to eq expected_document(true) + end + end + + context "without allow_tracking_start_and_end_times", with_settings: { allow_tracking_start_and_end_times: false } do + it "renders the expected document" do + expect(subject).to eq expected_document(false) + end + end +end diff --git a/modules/reporting/spec/workers/cost_query/export_job_spec.rb b/modules/reporting/spec/workers/cost_query/xls/export_job_spec.rb similarity index 99% rename from modules/reporting/spec/workers/cost_query/export_job_spec.rb rename to modules/reporting/spec/workers/cost_query/xls/export_job_spec.rb index 9fd966b4dc1f..9591f99fa78e 100644 --- a/modules/reporting/spec/workers/cost_query/export_job_spec.rb +++ b/modules/reporting/spec/workers/cost_query/xls/export_job_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe CostQuery::ExportJob do +RSpec.describe CostQuery::XLS::ExportJob do let(:user) { build_stubbed(:user) } let(:project) { build_stubbed(:project) } diff --git a/modules/storages/app/services/storages/create_folder_service.rb b/modules/storages/app/services/storages/create_folder_service.rb new file mode 100644 index 000000000000..8c9f2ed1d352 --- /dev/null +++ b/modules/storages/app/services/storages/create_folder_service.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module Storages + class CreateFolderService < BaseService + using Peripherals::ServiceResultRefinements + + def self.call(storage:, user:, name:, parent_id:) + new.call(storage:, user:, name:, parent_id:) + end + + def call(storage:, user:, name:, parent_id:) + auth_strategy = Peripherals::Registry.resolve("#{storage}.authentication.user_bound").call(user: user) + + Peripherals::Registry + .resolve("#{storage}.commands.create_folder") + .call( + storage:, + auth_strategy:, + folder_name: name, + parent_location: parent_path(parent_id, storage, user) + ) + end + + private + + def parent_path(parent_id, storage, user) + case storage.short_provider_type + when "nextcloud" + location_from_file_info(parent_id, storage, user) + when "one_drive" + Peripherals::ParentFolder.new(parent_id) + else + raise "Unknown Storage Type" + end + end + + def location_from_file_info(parent_id, storage, user) + StorageFileService + .call(storage: storage, user: user, file_id: parent_id) + .match( + on_success: lambda { |folder_info| + path = URI.decode_uri_component(folder_info.location) + Peripherals::ParentFolder.new(path) + }, + on_failure: ->(error) { raise error } + ) + end + end +end diff --git a/modules/storages/config/locales/crowdin/ro.yml b/modules/storages/config/locales/crowdin/ro.yml index b56c684ef2b4..fc56702213d2 100644 --- a/modules/storages/config/locales/crowdin/ro.yml +++ b/modules/storages/config/locales/crowdin/ro.yml @@ -77,14 +77,14 @@ ro: attributes: nextcloud_sync_service: add_user_to_group: 'Add User to Group:' - create_folder: 'Managed Project Folder Creation:' + create_folder: 'Creare dosar proiect gestionat:' ensure_root_folder_permissions: 'Set Base Folder Permissions:' hide_inactive_folders: 'Hide Inactive Folders Step:' remote_folders: 'Read contents of the group folder:' remove_user_from_group: 'Remove User from Group:' rename_project_folder: 'Rename managed project Folder:' one_drive_sync_service: - create_folder: 'Managed Project Folder Creation:' + create_folder: 'Creare dosar proiect gestionat:' ensure_root_folder_permissions: 'Set Base Folder Permissions:' hide_inactive_folders: 'Hide Inactive Folders Step:' remote_folders: 'Read contents of the group folder:' diff --git a/modules/storages/config/locales/crowdin/ru.yml b/modules/storages/config/locales/crowdin/ru.yml index f90af0cc13d2..e0a24a8d9de5 100644 --- a/modules/storages/config/locales/crowdin/ru.yml +++ b/modules/storages/config/locales/crowdin/ru.yml @@ -63,7 +63,7 @@ ru: label: Изменить папку проекта project_folder_mode: automatic: Автоматическое управление - inactive: Нет определенной папки + inactive: Нет конкретной папки manual: Существующая папка управляется вручную remove_project: deletion_failure_flash: Не удалось удалить проект из хранилища. %{error} diff --git a/modules/storages/config/locales/crowdin/zh-TW.yml b/modules/storages/config/locales/crowdin/zh-TW.yml index fcc1668ef843..26abca30faee 100644 --- a/modules/storages/config/locales/crowdin/zh-TW.yml +++ b/modules/storages/config/locales/crowdin/zh-TW.yml @@ -124,7 +124,7 @@ zh-TW: not_found: "%{current_path} 沒有找到。" set_folders_permissions: permission_not_set: 無法在 %{path} 上設定權限。 - error: An unexpected error occurred. Please ensure that your Nextcloud instance is reachable and check OpenProject worker logs for more information + error: 發生意外錯誤。請確保您的 Nextcloud 可以連線,並檢查 OpenProject 日誌以取得更多資訊。 group_does_not_exist: "%{group} 不存在。請檢查您的 Nextcloud 實例配置。" insufficient_privileges: OpenProject 沒有足夠的權限將 %{user} 加入 %{group}。請檢查 Nextcloud 中的群組設定。 not_allowed: Nextcloud 封鎖該請求。 @@ -145,7 +145,7 @@ zh-TW: not_found: "%{current_path} 沒有找到。" set_folders_permissions: permission_not_set: 無法在 %{path} 上設定權限。 - error: An unexpected error occurred. Please ensure that OneDrive/SharePoint is reachable and check OpenProject worker logs for more information + error: 發生意外錯誤。請確保 OneDrive/SharePoint 可以存取,並檢查 OpenProject Worker 日誌以取得更多資訊。 not_allowed: OpenProject 不允許存取您的 OneDrive 磁碟機。請檢查 Azure 應用程式上設定的權限。 unauthorized: OpenProject 無法與 OneDrive 同步。請檢查您的儲存空間和 Azure 應用程式設定。 user_does_not_exist: "%{user} 在 Nextcloud 中不存在。" @@ -343,8 +343,8 @@ zh-TW: subtitle: 您正被重新導向 title: 整合設定完成 timeout: - link_text: health status of the file storage setup - subtitle: OpenProject could not provide you access to the project folder within the expected period of time. Please, try once again.

If that problem persists please contact your OpenProject administrator to check the %{storages_health_link}. + link_text: 檔案儲存之健康狀態 + subtitle: OpenProject 無法讓您在預期時間內存取專案資料夾。請再試一次。

如果問題仍然存在,請聯絡您的 OpenProject 管理員以檢查 %{storages_health_link}。 waiting: subtitle: 請稍候,這可能需要一些時間... title: 我們正在設定您在專案資料夾上的權限。 diff --git a/modules/storages/lib/api/v3/file_links/file_link_relation_representer.rb b/modules/storages/lib/api/v3/file_links/file_link_relation_representer.rb index f373be81cdda..58b725ad70eb 100644 --- a/modules/storages/lib/api/v3/file_links/file_link_relation_representer.rb +++ b/modules/storages/lib/api/v3/file_links/file_link_relation_representer.rb @@ -45,18 +45,6 @@ module FileLinkRelationRepresenter method: :post } end - - property :file_links, - embedded: true, - exec_context: :decorator, - if: ->(*) { embed_links && current_user.allowed_in_project?(:view_file_links, represented.project) }, - uncacheable: true - - def file_links - ::API::V3::FileLinks::FileLinkCollectionRepresenter.new(represented.file_links, - self_link: api_v3_paths.file_links(represented.id), - current_user:) - end end end end diff --git a/modules/storages/lib/api/v3/storage_files/storage_folders_api.rb b/modules/storages/lib/api/v3/storage_files/storage_folders_api.rb new file mode 100644 index 000000000000..9766923a5e05 --- /dev/null +++ b/modules/storages/lib/api/v3/storage_files/storage_folders_api.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module API + module V3 + module StorageFiles + class StorageFoldersAPI < ::API::OpenProjectAPI + using ::Storages::Peripherals::ServiceResultRefinements + + helpers ::Storages::Peripherals::StorageErrorHelper + + resources :folders do + params do + requires :name, type: String, desc: "Folder name" + requires :parent_id, type: String, desc: "Id of the parent folder" + end + + post do + ::Storages::CreateFolderService.call( + storage: @storage, + user: current_user, + name: params["name"], + parent_id: params["parent_id"] + ).match( + on_success: lambda { |storage_folder| + API::V3::StorageFiles::StorageFileRepresenter.new( + storage_folder, + @storage, + current_user: + ) + }, + on_failure: ->(error) { raise_error(error) } + ) + end + end + end + end + end +end diff --git a/modules/storages/lib/api/v3/storages/storages_api.rb b/modules/storages/lib/api/v3/storages/storages_api.rb index b5dedbcd20e7..f77b67fa4d24 100644 --- a/modules/storages/lib/api/v3/storages/storages_api.rb +++ b/modules/storages/lib/api/v3/storages/storages_api.rb @@ -50,6 +50,7 @@ class API::V3::Storages::StoragesAPI < API::OpenProjectAPI mount API::V3::StorageFiles::StorageFilesAPI mount API::V3::OAuthClient::OAuthClientCredentialsAPI mount API::V3::Storages::StorageOpenAPI + mount API::V3::StorageFiles::StorageFoldersAPI end end end diff --git a/modules/storages/lib/open_project/storages/engine.rb b/modules/storages/lib/open_project/storages/engine.rb index 1a40a918da0b..d60979349731 100644 --- a/modules/storages/lib/open_project/storages/engine.rb +++ b/modules/storages/lib/open_project/storages/engine.rb @@ -312,6 +312,10 @@ def self.external_file_permissions "#{storage_files(storage_id)}/#{file_id}" end + add_api_path :storage_folders do |storage_id| + "#{storage(storage_id)}/folders" + end + add_api_path :prepare_upload do |storage_id| "#{storage(storage_id)}/files/prepare_upload" end diff --git a/modules/storages/spec/requests/api/v3/storages/storage_folders_api_spec.rb b/modules/storages/spec/requests/api/v3/storages/storage_folders_api_spec.rb new file mode 100644 index 000000000000..fddfa2a9bdcb --- /dev/null +++ b/modules/storages/spec/requests/api/v3/storages/storage_folders_api_spec.rb @@ -0,0 +1,144 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" +require_module_spec_helper + +RSpec.describe "API v3 storage folders", :webmock, content_type: :json do + include API::V3::Utilities::PathHelper + include StorageServerHelpers + + let(:permissions) { %i(view_work_packages view_file_links manage_file_links) } + let(:project) { create(:project) } + + let(:current_user) do + create(:user, member_with_permissions: { project => permissions }) + end + + let(:oauth_application) { create(:oauth_application) } + let(:storage) { create(:nextcloud_storage_configured, creator: current_user, oauth_application:) } + let(:oauth_token) { create(:oauth_client_token, user: current_user, oauth_client: storage.oauth_client) } + let(:project_storage) { create(:project_storage, project:, storage:) } + + subject(:last_response) { post(path, body) } + + before do + oauth_application + project_storage + login_as current_user + end + + describe "POST /api/v3/storages/:storage_id/folders" do + let(:path) { api_v3_paths.storage_folders(storage.id) } + let(:body) { { parent_id: file_info.id, name: folder_name }.to_json } + let(:folder_name) { "TestFolder" } + + let(:response) do + Storages::StorageFile.new( + id: 1, + name: folder_name, + size: 128, + mime_type: "application/x-op-directory", + created_at: DateTime.now, + last_modified_at: DateTime.now, + created_by_name: "Obi-Wan Kenobi", + last_modified_by_name: "Obi-Wan Kenobi", + location: "/", + permissions: %i[readable] + ) + end + + let(:file_info) do + Storages::StorageFileInfo.new( + status: "OK", + status_code: 200, + id: SecureRandom.hex, + name: "/", + location: "/" + ) + end + + before do + file_info_mock = class_double(Storages::Peripherals::StorageInteraction::Nextcloud::FileInfoQuery) + allow(file_info_mock).to receive(:call).with( + storage: storage, + auth_strategy: instance_of(Storages::Peripherals::StorageInteraction::AuthenticationStrategies::Strategy), + file_id: file_info.id + ).and_return(ServiceResult.success(result: file_info)) + Storages::Peripherals::Registry.stub("nextcloud.queries.file_info", file_info_mock) + end + + context "with successful response" do + subject { last_response.body } + + before do + create_folder_mock = class_double(Storages::Peripherals::StorageInteraction::Nextcloud::CreateFolderCommand) + allow(create_folder_mock).to receive(:call).with( + storage: storage, + auth_strategy: instance_of(Storages::Peripherals::StorageInteraction::AuthenticationStrategies::Strategy), + folder_name:, + parent_location: instance_of(Storages::Peripherals::ParentFolder) + ).and_return(ServiceResult.success(result: response)) + Storages::Peripherals::Registry.stub("nextcloud.commands.create_folder", create_folder_mock) + end + + it "responds with appropriate JSON" do + expect(subject).to be_json_eql(response.id.to_json).at_path("id") + expect(subject).to be_json_eql(response.name.to_json).at_path("name") + expect(subject).to be_json_eql(response.permissions.to_json).at_path("permissions") + end + end + + context "with query failed" do + before do + create_folder_mock = class_double(Storages::Peripherals::StorageInteraction::Nextcloud::CreateFolderCommand) + allow(create_folder_mock).to receive(:call).with( + storage: storage, + auth_strategy: instance_of(Storages::Peripherals::StorageInteraction::AuthenticationStrategies::Strategy), + folder_name:, + parent_location: instance_of(Storages::Peripherals::ParentFolder) + ).and_return(ServiceResult.failure(result: error, errors: Storages::StorageError.new(code: error))) + Storages::Peripherals::Registry.stub("nextcloud.commands.create_folder", create_folder_mock) + end + + context "with authorization failure" do + let(:error) { :unauthorized } + + it { expect(last_response).to have_http_status(:internal_server_error) } + end + + context "with internal error" do + let(:error) { :error } + + it { expect(last_response).to have_http_status(:internal_server_error) } + end + end + end +end diff --git a/modules/storages/spec/services/storages/create_folder_service_spec.rb b/modules/storages/spec/services/storages/create_folder_service_spec.rb new file mode 100644 index 000000000000..d4c6a96ce2d0 --- /dev/null +++ b/modules/storages/spec/services/storages/create_folder_service_spec.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" +require_module_spec_helper + +RSpec.describe Storages::CreateFolderService do + subject(:service) { described_class.call(storage:, user:, name:, parent_id:) } + + let(:user) { create(:admin) } + let(:name) { "TestFolderName" } + + context "when storage is nextcloud" do + let(:storage) { create(:nextcloud_storage) } + let(:parent_id) { file_info.id } + + let(:file_info) do + Storages::StorageFileInfo.new( + status: "OK", + status_code: 200, + id: SecureRandom.hex, + name: "/", + location: "/Path/To/Parent/Next" + ) + end + + let(:create_folder_command) { class_double(Storages::Peripherals::StorageInteraction::Nextcloud::CreateFolderCommand) } + + before do + file_info_mock = class_double(Storages::Peripherals::StorageInteraction::Nextcloud::FileInfoQuery) + allow(file_info_mock).to receive(:call).with( + storage: storage, + auth_strategy: instance_of(Storages::Peripherals::StorageInteraction::AuthenticationStrategies::Strategy), + file_id: file_info.id + ).and_return(ServiceResult.success(result: file_info)) + Storages::Peripherals::Registry.stub("nextcloud.queries.file_info", file_info_mock) + + allow(create_folder_command).to receive(:call).and_return(ServiceResult.success) + Storages::Peripherals::Registry.stub("nextcloud.commands.create_folder", create_folder_command) + end + + it "calls the appropriate command with the expected parameters" do + service + + expect(create_folder_command).to have_received(:call).with( + storage:, + auth_strategy: instance_of(Storages::Peripherals::StorageInteraction::AuthenticationStrategies::Strategy), + folder_name: name, + parent_location: Storages::Peripherals::ParentFolder.new(file_info.location) + ).once + end + end + + context "when storage is one_drive" do + let(:storage) { create(:one_drive_storage) } + let(:parent_id) { file_info.id } + + let(:file_info) do + Storages::StorageFileInfo.new( + status: "OK", + status_code: 200, + id: "/Path/To/Parent/One", + name: "/" + ) + end + + let(:create_folder_command) { class_double(Storages::Peripherals::StorageInteraction::Nextcloud::CreateFolderCommand) } + + before do + allow(create_folder_command).to receive(:call).and_return(ServiceResult.success) + Storages::Peripherals::Registry.stub("one_drive.commands.create_folder", create_folder_command) + end + + it "calls the appropriate command with the expected parameters" do + service + + expect(create_folder_command).to have_received(:call).with( + storage:, + auth_strategy: instance_of(Storages::Peripherals::StorageInteraction::AuthenticationStrategies::Strategy), + folder_name: name, + parent_location: Storages::Peripherals::ParentFolder.new(file_info.id) + ).once + end + end +end diff --git a/spec/components/enterprise_edition/banner_component_spec.rb b/spec/components/enterprise_edition/banner_component_spec.rb new file mode 100644 index 000000000000..4bdf58bb2692 --- /dev/null +++ b/spec/components/enterprise_edition/banner_component_spec.rb @@ -0,0 +1,197 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2024 the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +# ++ + +require "rails_helper" + +RSpec.describe EnterpriseEdition::BannerComponent, type: :component do + let(:title) { "Some title" } + let(:description) { "Some description" } + let(:href) { "https://www.example.org" } + let(:link_title) { "Get more information" } + let(:ee_show_banners) { true } + let(:enforce_available_locales) { I18n.config.enforce_available_locales } + let(:i18n_upsale) do + { + title:, + link_title:, + some_enterprise_feature: { + description: + } + } + end + let(:static_links) do + { + enterprise_docs: { + some_enterprise_feature: { + href: + } + } + } + end + + let(:render_component) do + render_inline(described_class.new(:some_enterprise_feature)) + end + + let(:render_component_in_mo) do + I18n.with_locale :mo do + render_component + end + end + + before do + allow(EnterpriseToken) + .to receive(:show_banners?) + .and_return(ee_show_banners) + allow(OpenProject::Static::Links) + .to receive(:links) + .and_return(static_links) + + I18n.config.enforce_available_locales = !enforce_available_locales + + I18n.backend.store_translations( + :mo, + { + ee: { + upsale: i18n_upsale + } + } + ) + end + + after do + I18n.backend.translations.delete(:mo) + I18n.config.enforce_available_locales = enforce_available_locales + end + + shared_examples_for "renders the component" do + it "renders the component" do + render_component_in_mo + + expect(page).to have_css ".op-ee-banner--title-container", text: title + expect(page).to have_css ".op-ee-banner--description-container", text: description + expect(page).to have_link link_title, href: + end + end + + it_behaves_like "renders the component" + + context "with a description_html in the i18n file" do + let(:i18n_upsale) do + { + title:, + link_title:, + some_enterprise_feature: { + description_html: description + } + } + end + + it_behaves_like "renders the component" + end + + context "with a more specific title in the i18n file" do + let(:i18n_upsale) do + { + title: "The general title", + link_title:, + some_enterprise_feature: { + title:, + description: + } + } + end + + it_behaves_like "renders the component" + end + + context "with a more specific link title in the i18n file" do + let(:i18n_upsale) do + { + title:, + link_title: "The general link title", + some_enterprise_feature: { + link_title:, + description: + } + } + end + + it_behaves_like "renders the component" + end + + context "without a description key in the i18n file" do + let(:i18n_upsale) do + { + title:, + link_title:, + some_enterprise_feature: {} + } + end + + it "raises an error" do + expect { render_component_in_mo }.to raise_error(I18n::MissingTranslationData) + end + end + + context "without a link key in the static_link file" do + let(:static_links) do + { + enterprise_docs: { + some_enterprise_feature: {} + } + } + end + + it "raises an error" do + expect { render_component_in_mo }.to raise_error(RuntimeError) + end + end + + context "if banners are hidden" do + let(:ee_show_banners) { false } + + it "hides the component" do + render_component_in_mo + + expect(page).to have_no_css ".op-ee-banner" + end + end + + context "if banners are hidden but skip_render is overwritten" do + let(:ee_show_banners) { false } + let(:render_component) do + render_inline(described_class.new(:some_enterprise_feature, + skip_render: false)) + end + + it_behaves_like "renders the component" + end +end diff --git a/spec/features/notifications/notification_center/notification_center_reminder_spec.rb b/spec/features/notifications/notification_center/notification_center_reminder_spec.rb new file mode 100644 index 000000000000..015aa20a36f1 --- /dev/null +++ b/spec/features/notifications/notification_center/notification_center_reminder_spec.rb @@ -0,0 +1,64 @@ +require "spec_helper" +require "features/page_objects/notification" + +RSpec.describe "Notification center reminder, mention and date alert", + :js, + :with_cuprite, + with_ee: %i[date_alerts], + with_settings: { journal_aggregation_time_minutes: 0 } do + shared_let(:project) { create(:project) } + shared_let(:actor) { create(:user, firstname: "Actor", lastname: "User") } + shared_let(:user) do + create(:user, + member_with_permissions: { project => %w[view_work_packages] }) + end + shared_let(:work_package) { create(:work_package, project:, due_date: 1.day.ago) } + + shared_let(:notification_mention) do + create(:notification, + reason: :mentioned, + recipient: user, + resource: work_package, + actor:) + end + + shared_let(:notification_date_alert) do + create(:notification, + reason: :date_alert_due_date, + recipient: user, + resource: work_package) + end + + shared_let(:notification_reminder) do + reminder = create(:reminder, remindable: work_package, creator: user, note: "This is an important reminder") + notification = create(:notification, + reason: :reminder, + recipient: user, + resource: work_package) + create(:reminder_notification, reminder:, notification:) + notification + end + + let(:center) { Pages::Notifications::Center.new } + + before do + login_as user + visit notifications_center_path + wait_for_reload + end + + it "shows the reminder alert in own entry" do + center.within_item(notification_reminder) do + expect(page).to have_text("##{work_package.id}\n- #{project.name} -\nReminder") + expect(page).to have_no_text("Actor user") + expect(page).to have_text("a few seconds ago.\nNote: “This is an important reminder”") + end + end + + it "shows other notification reasons aggregated" do + center.within_item(notification_date_alert) do + expect(page).to have_text("##{work_package.id}\n- #{project.name} -\nDate alert, Mentioned") + expect(page).to have_no_text("Actor user") + end + end +end diff --git a/spec/features/notifications/notification_center/notification_center_sidemenu_spec.rb b/spec/features/notifications/notification_center/notification_center_sidemenu_spec.rb index faf5a6209aa5..c2cd4a832484 100644 --- a/spec/features/notifications/notification_center/notification_center_sidemenu_spec.rb +++ b/spec/features/notifications/notification_center/notification_center_sidemenu_spec.rb @@ -24,6 +24,7 @@ shared_let(:work_package4) { create(:work_package, project: project3, author: other_user) } shared_let(:work_package5) { create(:work_package, :is_milestone, project: project3, author: other_user) } shared_let(:work_package6) { create(:work_package, :is_milestone, project: project3, author: other_user) } + shared_let(:work_package7) { create(:work_package, project: project3, author: other_user) } let(:notification_watched) do create(:notification, @@ -67,9 +68,19 @@ reason: :shared) end + let(:notification_reminder) do + reminder = create(:reminder, remindable: work_package7, creator: other_user, note: "This is an important reminder") + notification = create(:notification, + recipient:, + resource: work_package7, + reason: :reminder) + create(:reminder_notification, reminder:, notification:) + notification + end + let(:notifications) do [notification_watched, notification_assigned, notification_responsible, notification_mentioned, notification_date, - notification_shared] + notification_shared, notification_reminder] end let(:center) { Pages::Notifications::Center.new } @@ -99,6 +110,7 @@ side_menu.expect_item_with_no_count "Watcher" side_menu.expect_item_with_no_count "Date alert" side_menu.expect_item_with_no_count "Shared" + side_menu.expect_item_with_no_count "Reminder" end end @@ -106,35 +118,37 @@ side_menu.expect_open # Expect standard filters - side_menu.expect_item_with_count "Inbox", 6 + side_menu.expect_item_with_count "Inbox", 7 side_menu.expect_item_with_count "Assignee", 1 side_menu.expect_item_with_count "Mentioned", 1 side_menu.expect_item_with_count "Accountable", 1 side_menu.expect_item_with_count "Watcher", 1 side_menu.expect_item_with_count "Date alert", 1 side_menu.expect_item_with_count "Shared", 1 + side_menu.expect_item_with_count "Reminder", 1 # Expect project filters side_menu.expect_item_with_count project.name, 1 side_menu.expect_item_with_count project2.name, 1 - side_menu.expect_item_with_count "... #{project3.name}", 4 + side_menu.expect_item_with_count "... #{project3.name}", 5 # Reading a notification... center.mark_notification_as_read notification_watched # ... will change the filter counts - side_menu.expect_item_with_count "Inbox", 5 + side_menu.expect_item_with_count "Inbox", 6 side_menu.expect_item_with_count "Assignee", 1 side_menu.expect_item_with_count "Mentioned", 1 side_menu.expect_item_with_count "Accountable", 1 side_menu.expect_item_with_count "Date alert", 1 side_menu.expect_item_with_count "Shared", 1 + side_menu.expect_item_with_count "Reminder", 1 side_menu.expect_item_with_no_count "Watcher" # ... and show only those projects with a notification side_menu.expect_no_item project.name side_menu.expect_item_with_count project2.name, 1 - side_menu.expect_item_with_count "... #{project3.name}", 4 + side_menu.expect_item_with_count "... #{project3.name}", 5 # Empty filter sets have a separate message side_menu.click_item "Watcher" @@ -152,6 +166,7 @@ side_menu.expect_item_with_no_count "Watcher" side_menu.expect_item_with_no_count "Date alert" side_menu.expect_item_with_no_count "Shared" + side_menu.expect_item_with_no_count "Reminder" side_menu.expect_no_item project.name side_menu.expect_no_item project2.name @@ -160,66 +175,74 @@ it "updates the content when a filter is clicked" do # All notifications are shown - center.expect_work_package_item *notifications + center.expect_work_package_item(*notifications) # Filter for "Watcher" side_menu.click_item "Watcher" side_menu.finished_loading center.expect_work_package_item notification_watched center.expect_no_item notification_assigned, notification_responsible, notification_mentioned, notification_date, - notification_shared + notification_shared, notification_reminder # Filter for "Assignee" side_menu.click_item "Assignee" side_menu.finished_loading center.expect_work_package_item notification_assigned center.expect_no_item notification_watched, notification_responsible, notification_mentioned, notification_date, - notification_shared + notification_shared, notification_reminder # Filter for "Accountable" side_menu.click_item "Accountable" side_menu.finished_loading center.expect_work_package_item notification_responsible center.expect_no_item notification_watched, notification_assigned, notification_mentioned, notification_date, - notification_shared + notification_shared, notification_reminder # Filter for "Mentioned" side_menu.click_item "Mentioned" side_menu.finished_loading center.expect_work_package_item notification_mentioned center.expect_no_item notification_watched, notification_assigned, notification_responsible, notification_date, - notification_shared + notification_shared, notification_reminder # Filter for "Date alert" side_menu.click_item "Date alert" side_menu.finished_loading center.expect_work_package_item notification_date center.expect_no_item notification_watched, notification_assigned, notification_responsible, notification_mentioned, - notification_shared + notification_shared, notification_reminder # Filter for "Shared" side_menu.click_item "Shared" side_menu.finished_loading center.expect_work_package_item notification_shared center.expect_no_item notification_watched, notification_assigned, notification_responsible, notification_mentioned, - notification_date + notification_date, notification_reminder + + # Filter for "Reminder" + side_menu.click_item "Reminder" + side_menu.finished_loading + center.expect_work_package_item notification_reminder + center.expect_no_item notification_watched, notification_assigned, notification_responsible, notification_mentioned, + notification_date, notification_shared # Filter for project1 side_menu.click_item project.name side_menu.finished_loading center.expect_work_package_item notification_watched center.expect_no_item notification_assigned, notification_responsible, notification_mentioned, notification_date, - notification_shared + notification_shared, notification_reminder # Filter for project3 side_menu.click_item "... #{project3.name}" side_menu.finished_loading - center.expect_work_package_item notification_responsible, notification_mentioned, notification_date, notification_shared + center.expect_work_package_item notification_responsible, notification_mentioned, notification_date, notification_shared, + notification_reminder center.expect_no_item notification_watched, notification_assigned # Reset by clicking on the Inbox side_menu.click_item "Inbox" side_menu.finished_loading - center.expect_work_package_item *notifications + center.expect_work_package_item(*notifications) end end diff --git a/spec/features/work_packages/details/relations/primerized_relations_spec.rb b/spec/features/work_packages/details/relations/primerized_relations_spec.rb index 7160370fd0e1..280045e8faee 100644 --- a/spec/features/work_packages/details/relations/primerized_relations_spec.rb +++ b/spec/features/work_packages/details/relations/primerized_relations_spec.rb @@ -83,12 +83,14 @@ project:) end - let(:full_wp_view) { Pages::FullWorkPackage.new(work_package) } let(:relations_tab) { Components::WorkPackages::Relations.new(work_package) } let(:relations_panel_selector) { ".detail-panel--relations" } let(:relations_panel) { find(relations_panel_selector) } let(:work_packages_page) { Pages::PrimerizedSplitWorkPackage.new(work_package) } let(:tabs) { Components::WorkPackages::PrimerizedTabs.new } + let(:additional_setup) do + # Nothing but contexts might overwrite it + end current_user { user } @@ -97,6 +99,7 @@ def label_for_relation_type(relation_type) end before do + additional_setup work_packages_page.visit_tab!("relations") expect_angular_frontend_initialized work_packages_page.expect_subject @@ -198,7 +201,7 @@ def label_for_relation_type(relation_type) end context "with the shown WorkPackage being the 'to' relation part" do - let(:another_wp) { create(:work_package, type: type2, subject: "related to main") } + let(:another_wp) { create(:work_package, type: type2, subject: "Successor of main") } let(:relation_to) do create(:relation, @@ -207,8 +210,7 @@ def label_for_relation_type(relation_type) relation_type: Relation::TYPE_FOLLOWS) end - before do - another_wp + let(:additional_setup) do relation_to end @@ -217,7 +219,6 @@ def label_for_relation_type(relation_type) wait_for_network_idle - relations_tab.expect_relation(another_wp) relations_tab.open_relation_dialog(another_wp) within "##{WorkPackageRelationsTab::WorkPackageRelationDialogComponent::DIALOG_ID}" do @@ -316,7 +317,7 @@ def label_for_relation_type(relation_type) results_selector: "body") expect_no_ng_option(autocomplete_field, - work_package.id, + work_package.subject, results_selector: "body") end end diff --git a/spec/features/work_packages/share/filter_spec.rb b/spec/features/work_packages/share/filter_spec.rb index c6682360059b..eaefdcbf6f75 100644 --- a/spec/features/work_packages/share/filter_spec.rb +++ b/spec/features/work_packages/share/filter_spec.rb @@ -276,20 +276,36 @@ it "only displays shares that match the current set of applied filters" do share_modal.expect_open + # Change all shared to have the "View" role. + retry_block do + share_modal.toggle_select_all + share_modal.bulk_update("View") + end + share_modal.toggle_select_all - share_modal.bulk_update("View") - share_modal.toggle_select_all + + # Filter for the View role share_modal.filter("role", "View") - share_modal.expect_shared_with(project_user) - share_modal.expect_shared_with(project_user2) - share_modal.expect_shared_with(inherited_project_user) - share_modal.expect_shared_with(non_project_user) - share_modal.expect_shared_with(shared_project_group) - share_modal.expect_shared_with(shared_non_project_group) + # Since all shares have the View role, all shares should be displayed. + + share_modal.expect_shared_with(project_user, "View") + share_modal.expect_shared_with(project_user2, "View") + share_modal.expect_shared_with(inherited_project_user, "View") + share_modal.expect_shared_with(non_project_user, "View") + share_modal.expect_shared_with(shared_project_group, "View") + share_modal.expect_shared_with(shared_non_project_group, "View") + + # Change one share to have the Comment role. share_modal.change_role(project_user, "Comment") + + # That share is no longer displayed as it does not match the current filter after the role change. + share_modal.expect_not_shared_with(project_user) + + # When filtering for the Comment role, only the changed share should be displayed. + share_modal.filter("role", "Comment") share_modal.expect_shared_with(project_user, "Comment") share_modal.expect_not_shared_with(project_user2) @@ -298,6 +314,8 @@ share_modal.expect_not_shared_with(shared_project_group) share_modal.expect_not_shared_with(shared_non_project_group) + # When filtering for the Edit role, no share matches and thus none should be displayed. + share_modal.filter("role", "Edit") share_modal.expect_empty_search_blankslate end diff --git a/spec/lib/api/v3/notifications/notification_representer_rendering_spec.rb b/spec/lib/api/v3/notifications/notification_representer_rendering_spec.rb index c0fb12c42cbd..bb3aef99788e 100644 --- a/spec/lib/api/v3/notifications/notification_representer_rendering_spec.rb +++ b/spec/lib/api/v3/notifications/notification_representer_rendering_spec.rb @@ -267,5 +267,60 @@ .at_path("_embedded/details") end end + + shared_examples_for "embeds a Values::Property for reminder note" do + it "embeds a Values::Property" do + expect(generated) + .to be_json_eql("Values::Property".to_json) + .at_path("_embedded/details/0/_type") + end + + it "has a note value for the `property` property" do + expect(generated) + .to be_json_eql("note".to_json) + .at_path("_embedded/details/0/property") + end + + it "has a reminder`s note for the value" do + expect(generated) + .to be_json_eql(notification.reminder.note.to_json) + .at_path("_embedded/details/0/value") + end + end + + context "for a reminder when embedding" do + let(:reminder) { build_stubbed(:reminder) } + let(:reason) { :reminder } + let(:embed_links) { true } + + before do + allow(notification).to receive(:reminder).and_return(reminder) + end + + it_behaves_like "embeds a Values::Property for reminder note" + end + + context "for a reminder when not embedding" do + let(:reminder) { build_stubbed(:reminder) } + let(:reason) { :reminder } + let(:embed_links) { false } + + before do + allow(notification).to receive(:reminder).and_return(reminder) + end + + it_behaves_like "embeds a Values::Property for reminder note" + end + + context "for a reminder with no notification" do + let(:reminder) { nil } + let(:reason) { :reminder } + + it "has an empty details array" do + expect(generated) + .to have_json_size(0) + .at_path("_embedded/details") + end + end end end diff --git a/spec/lib/custom_field_form_builder_spec.rb b/spec/lib/custom_field_form_builder_spec.rb index 00820ae90378..06337c5ed128 100644 --- a/spec/lib/custom_field_form_builder_spec.rb +++ b/spec/lib/custom_field_form_builder_spec.rb @@ -255,6 +255,7 @@ let(:project) { build_stubbed(:project) } let(:user1) { build_stubbed(:user) } let(:user2) { build_stubbed(:user) } + let(:scope) { instance_double(ActiveRecord::Relation) } let(:resource) { project } @@ -268,8 +269,12 @@ end allow(project) - .to(receive(:principals)) - .and_return([user1, user2]) + .to receive(:principals) + .and_return(scope) + + allow(scope) + .to receive(:select) + .and_return([user1, user2]) end it_behaves_like "wrapped in container", "select-container" do diff --git a/spec/lib/journal_formatter/custom_field_spec.rb b/spec/lib/journal_formatter/custom_field_spec.rb index e86d3fb90999..9287ee055570 100644 --- a/spec/lib/journal_formatter/custom_field_spec.rb +++ b/spec/lib/journal_formatter/custom_field_spec.rb @@ -469,6 +469,22 @@ def url_helper = Rails.application.routes.url_helpers it { expect(rendered).to be_html_eql(expected) } end + + describe "with a deleted item" do + let(:values) { [[luke.id, -100].join(","), luke.id.to_s] } + let(:original_value) { [luke.ancestry_path, I18n.t(:label_deleted_custom_item)].join(", ") } + let(:formatted_value) { luke.ancestry_path } + + let(:expected) do + I18n.t(:text_journal_changed_plain, + label: "#{custom_field.name}", + linebreak: "", + old: "#{original_value}", + new: "#{formatted_value}") + end + + it { expect(rendered).to be_html_eql(expected) } + end end end end diff --git a/spec/models/custom_actions/actions/custom_field_spec.rb b/spec/models/custom_actions/actions/custom_field_spec.rb index 05c68c594384..afc2c54b1f00 100644 --- a/spec/models/custom_actions/actions/custom_field_spec.rb +++ b/spec/models/custom_actions/actions/custom_field_spec.rb @@ -441,12 +441,17 @@ build_stubbed(:user), build_stubbed(:user)] end + let(:scope) { instance_double(ActiveRecord::Relation) } before do allow(Principal) .to receive(:in_visible_project_or_me) - .with(User.current) - .and_return(users) + .with(User.current) + .and_return(scope) + + allow(scope) + .to receive(:select) + .and_return(users) end context "for a non required field" do @@ -515,12 +520,17 @@ build_stubbed(:user), build_stubbed(:user)] end + let(:scope) { instance_double(ActiveRecord::Relation) } before do allow(Principal) .to receive(:in_visible_project_or_me) - .with(User.current) - .and_return(users) + .with(User.current) + .and_return(scope) + + allow(scope) + .to receive(:select) + .and_return(users) end it_behaves_like "associated custom action validations" do diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb index f448ba748120..67ecadbe568e 100644 --- a/spec/models/custom_field_spec.rb +++ b/spec/models/custom_field_spec.rb @@ -215,17 +215,27 @@ let(:project) { build_stubbed(:project) } let(:user1) { build_stubbed(:user) } let(:user2) { build_stubbed(:user) } + let(:in_visible_scope) { instance_double(ActiveRecord::Relation) } + let(:principals_scope) { instance_double(ActiveRecord::Relation) } context "for a user custom field" do before do field.field_format = "user" allow(project) .to receive(:principals) - .and_return([user1, user2]) + .and_return(principals_scope) + + allow(principals_scope) + .to receive(:select) + .and_return([user1, user2]) allow(Principal) .to receive(:in_visible_project_or_me) - .and_return([user2]) + .and_return(in_visible_scope) + + allow(in_visible_scope) + .to receive(:select) + .and_return([user2]) end context "for a project" do diff --git a/spec/requests/api/v3/work_packages/create_resource_spec.rb b/spec/requests/api/v3/work_packages/create_resource_spec.rb index cc6ff6015d5a..de07c44385a5 100644 --- a/spec/requests/api/v3/work_packages/create_resource_spec.rb +++ b/spec/requests/api/v3/work_packages/create_resource_spec.rb @@ -113,7 +113,7 @@ end it "creates a work package" do - expect(WorkPackage.all.count).to eq(1) + expect(WorkPackage.count).to eq(1) end it "uses the given parameters" do @@ -152,7 +152,7 @@ it_behaves_like "multiple errors", 422 it "does not create a work package" do - expect(WorkPackage.all.count).to eq(0) + expect(WorkPackage.count).to eq(0) end end @@ -176,7 +176,7 @@ end it "does not create a work package" do - expect(WorkPackage.all.count).to eq(0) + expect(WorkPackage.count).to eq(0) end end @@ -227,7 +227,7 @@ end it "does not create a work package" do - expect(WorkPackage.all.count).to eq(0) + expect(WorkPackage.count).to eq(0) end end @@ -310,7 +310,7 @@ expect(last_response.body).to be_json_eql( api_v3_paths.file_links(work_package.id).to_json ).at_path("_links/fileLinks/href") - expect(last_response.body).to be_json_eql("1").at_path("_embedded/fileLinks/total") + expect(last_response.body).to have_json_path("_links/addFileLink") end end end diff --git a/spec/support/components/sharing/share_modal.rb b/spec/support/components/sharing/share_modal.rb index d880da1ac960..11b846cb1b39 100644 --- a/spec/support/components/sharing/share_modal.rb +++ b/spec/support/components/sharing/share_modal.rb @@ -380,7 +380,7 @@ def select_not_existing_user_option(email) def expect_upsale_banner within_modal do expect(page) - .to have_text(I18n.t(:label_enterprise_addon)) + .to have_text(I18n.t(:"ee.upsale.title")) end end