diff --git a/modules/documents/Gemfile.plugins b/modules/documents/Gemfile.plugins
new file mode 100644
index 0000000000..39f9d179f0
--- /dev/null
+++ b/modules/documents/Gemfile.plugins
@@ -0,0 +1,7 @@
+# Used by travis to bundle this plugin with the OpenProject core.
+# The tested plugin will be moved to the path `./plugins/this`
+# whereas OpenProject will be checked out to `.`.
+
+gem 'openproject-documents', path: 'plugins/this'
+
+# If the plugin has any dependencies declare them here:
diff --git a/modules/documents/README.md b/modules/documents/README.md
new file mode 100644
index 0000000000..b775b6a7d3
--- /dev/null
+++ b/modules/documents/README.md
@@ -0,0 +1,100 @@
+OpenProject Documents Plugin
+===========================
+
+This plugin adds features to connect and categorize documents with your project.
+
+Under `Modules >> Administration >> Enumerations` you can find the section `Document categories`
+where you can define several document categories that projects can use to categorize their documents.
+
+Documents can be enabled for every project individually. Simply activate the `Documents` module in the project settings.
+
+When you go to any of your projects you can see the entry `Documents` in the main menu. There you can
+attach new documents to the project by following the `New document` link located in the top right corner of the page.
+
+The form allows you to select one of the categories you defined earlier, choose a title and define a description.
+You can attach files from your local hard disk to the document entry which will make them available to anybody
+who has access to the document.
+
+Requirements
+------------
+
+The OpenProject Documents plug-in requires the [OpenProject Core](https://github.com/opf/openproject/) in version greater or equal to *3.0.0*.
+
+
+Installation
+------------
+
+For OpenProject Documents you need to add the following line to the `Gemfile.plugins` of OpenProject (if you use a different OpenProject version than OpenProject 5, adapt `:branch => "stable/5"` to your OpenProject version):
+
+`gem "openproject-documents", git: "https://github.com/opf/openproject-documents.git", :branch => "stable/5"`
+
+Afterwards, run:
+
+`bundle install`
+
+This plugin contains migrations. To migrate the database, run:
+
+`rake db:migrate`
+
+
+Tests
+-----
+
+Assuming you have to following directory structure:
+
+```
+.
+├── openproject
+├── openproject-documents
+```
+
+Replace the openproject-document ``Gemfile.plugins`` entry with the following:
+
+```
+gem "openproject-documents", path: "../openproject-documents"
+```
+
+You run the specs with the following commands:
+
+```
+cd openproject
+rake db:test:load # this needs to be done only once
+rspec ../openproject-documents
+```
+
+Deinstallation
+--------------
+
+Remove the line
+
+`gem "openproject-documents", git: "https://github.com/opf/openproject-documents.git", :branch => "stable/5"`
+
+from the file `Gemfile.plugins` and run:
+
+`bundle install`
+
+Please not that this leaves plugin data in the database. Currently, we do not support full uninstall of the plugin.
+
+
+Bug Reporting
+-------------
+
+If you find any bugs, you can create a bug ticket at
+
+https://www.openproject.org/projects/documents
+
+
+Development
+-----------
+
+To contribute, you can create pull request on the official repository at
+`https://github.com/opf/openproject-documents`
+
+Licence
+-------
+
+Copyright (C) 2009-2015 the OpenProject Foundation (OPF)
+Copyright (C) 2006-2013 Jean-Philippe Lang
+Copyright (C) 2010-2013 the ChiliProject Team
+
+This plugin is licensed under the GNU GPL v3. See doc/COPYRIGHT.md and doc/GPL.txt for details.
diff --git a/modules/documents/app/assets/stylesheets/documents/_global_rules.sass b/modules/documents/app/assets/stylesheets/documents/_global_rules.sass
new file mode 100644
index 0000000000..2612abdbc4
--- /dev/null
+++ b/modules/documents/app/assets/stylesheets/documents/_global_rules.sass
@@ -0,0 +1,34 @@
+/*-- copyright
+ * OpenProject Documents Plugin
+ *
+ * Former OpenProject Core functionality extracted into a plugin.
+ *
+ * Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+ *
+ * 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 doc/COPYRIGHT.rdoc for more details.
+ */
+
+dt.document:before
+ @include icon-mixin-notes
+
diff --git a/modules/documents/app/assets/stylesheets/documents/documents.sass b/modules/documents/app/assets/stylesheets/documents/documents.sass
new file mode 100644
index 0000000000..882305f6a1
--- /dev/null
+++ b/modules/documents/app/assets/stylesheets/documents/documents.sass
@@ -0,0 +1,48 @@
+/*-- copyright
+ * OpenProject Documents Plugin
+ *
+ * Former OpenProject Core functionality extracted into a plugin.
+ *
+ * Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+ *
+ * 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 doc/COPYRIGHT.rdoc for more details.
+ */
+
+.sidebar--document-sort label:last-of-type
+ margin-bottom: 2rem
+
+.document-category--inner-section
+ padding-top: 20px
+
+.document-category-elements
+ display: inline
+
+.document-category-elements--header
+ margin-bottom: 0.25rem
+
+.document-category-elements--date
+ margin-bottom: 0.75rem
+
+.document-category-elements .wiki
+ margin-bottom: 2rem
diff --git a/modules/documents/app/controllers/documents_controller.rb b/modules/documents/app/controllers/documents_controller.rb
new file mode 100644
index 0000000000..ecb74ff07d
--- /dev/null
+++ b/modules/documents/app/controllers/documents_controller.rb
@@ -0,0 +1,124 @@
+#-- encoding: UTF-8
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+class DocumentsController < ApplicationController
+ default_search_scope :documents
+ model_object Document
+ before_action :find_project_by_project_id, only: [:index, :new, :create]
+ before_action :find_model_object, except: [:index, :new, :create]
+ before_action :find_project_from_association, except: [:index, :new, :create]
+ before_action :authorize
+
+ def index
+ @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
+ documents = @project.documents
+ case @sort_by
+ when 'date'
+ @grouped = documents.group_by {|d| d.updated_on.to_date }
+ when 'title'
+ @grouped = documents.group_by {|d| d.title.first.upcase}
+ when 'author'
+ @grouped = documents.with_attachments.group_by {|d| d.attachments.last.author}
+ else
+ @grouped = documents.includes(:category).group_by(&:category)
+ end
+ render layout: false if request.xhr?
+ end
+
+ def show
+ @attachments = @document.attachments.order('created_at DESC')
+ end
+
+ def new
+ @document = @project.documents.build
+ @document.attributes = document_params
+ end
+
+ def create
+ @document = @project.documents.build
+ @document.attributes = document_params
+ @document.attach_files(permitted_params.attachments.to_h)
+
+ if @document.save
+ render_attachment_warning_if_needed(@document)
+ flash[:notice] = l(:notice_successful_create)
+ redirect_to project_documents_path(@project)
+ else
+ render action: 'new'
+ end
+ end
+
+ def edit
+ @categories = DocumentCategory.all
+ end
+
+ def update
+ @document.attributes = document_params
+ @document.attach_files(permitted_params.attachments.to_h)
+
+ if @document.save
+ render_attachment_warning_if_needed(@document)
+ flash[:notice] = l(:notice_successful_update)
+ redirect_to action: 'show', id: @document
+ else
+ render action: 'edit'
+ end
+ end
+
+ def destroy
+ @document.destroy
+ redirect_to controller: '/documents', action: 'index', project_id: @project
+ end
+
+ def add_attachment
+ @document.attach_files(permitted_params.attachments.to_h)
+ attachments = @document.attachments.select(&:new_record?)
+
+ @document.save
+ render_attachment_warning_if_needed(@document)
+
+ saved_attachments = attachments.select(&:persisted?)
+ if saved_attachments.present? && Setting.notified_events.include?('document_added')
+ users = saved_attachments.first.container.recipients
+ users.each do |user|
+ UserMailer.attachments_added(user, saved_attachments).deliver
+ end
+ end
+ redirect_to action: 'show', id: @document
+ end
+
+ private
+
+ def document_params
+ params.fetch(:document, {}).permit('category_id', 'title', 'description')
+ end
+end
diff --git a/modules/documents/app/mailers/documents_mailer.rb b/modules/documents/app/mailers/documents_mailer.rb
new file mode 100644
index 0000000000..efe049a3c8
--- /dev/null
+++ b/modules/documents/app/mailers/documents_mailer.rb
@@ -0,0 +1,55 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+class DocumentsMailer < UserMailer
+
+ def document_added(user, document)
+ @document = document
+
+ open_project_headers 'Project' => @document.project.identifier,
+ 'Type' => 'Document'
+
+ with_locale_for(user) do
+ subject = "[#{@document.project.name}] #{t(:label_document_new)}: #{@document.title}"
+ mail to: user.mail, subject: subject
+ end
+ end
+
+ def attachments_added(user, attachments)
+ container = attachments.first.container
+
+ @added_to = "#{Document.model_name.human}: #{container.title}"
+ @added_to_url = url_for(controller: '/documents', action: 'show', id: container.id)
+
+ super
+ end
+
+end
diff --git a/modules/documents/app/models/activity/document_activity_provider.rb b/modules/documents/app/models/activity/document_activity_provider.rb
new file mode 100644
index 0000000000..13709e0695
--- /dev/null
+++ b/modules/documents/app/models/activity/document_activity_provider.rb
@@ -0,0 +1,64 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+class Activity::DocumentActivityProvider < Activity::BaseActivityProvider
+ acts_as_activity_provider type: 'documents',
+ permission: :view_documents
+
+ def event_query_projection(activity)
+ [
+ activity_journal_projection_statement(:title, 'document_title', activity),
+ activity_journal_projection_statement(:project_id, 'project_id', activity)
+ ]
+ end
+
+ def event_title(event, _activity)
+ "#{Document.model_name.human}: #{event['document_title']}"
+ end
+
+ def event_type(_event, _activity)
+ 'document'
+ end
+
+ def event_path(event, _activity)
+ url_helpers.document_url(url_helper_parameter(event))
+ end
+
+ def event_url(event, _activity)
+ url_helpers.document_url(url_helper_parameter(event))
+ end
+
+ private
+
+ def url_helper_parameter(event)
+ event['journable_id']
+ end
+end
diff --git a/modules/documents/app/models/document.rb b/modules/documents/app/models/document.rb
new file mode 100644
index 0000000000..c5e29dbd1e
--- /dev/null
+++ b/modules/documents/app/models/document.rb
@@ -0,0 +1,97 @@
+#-- encoding: UTF-8
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+class Document < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :category, class_name: "DocumentCategory", foreign_key: "category_id"
+ acts_as_attachable delete_permission: :manage_documents,
+ add_permission: :manage_documents
+
+ acts_as_journalized
+ acts_as_event title: Proc.new { |o| "#{Document.model_name.human}: #{o.title}" },
+ url: Proc.new { |o| { controller: '/documents', action: 'show', id: o.id } },
+ datetime: :created_on,
+ author: ( Proc.new do |o|
+ o.attachments.find(:first, order: "#{Attachment.table_name}.created_at ASC").try(:author)
+ end)
+
+ acts_as_searchable columns: ['title', "#{table_name}.description"],
+ include: :project,
+ references: :projects
+
+ validates_presence_of :project, :title, :category
+ validates_length_of :title, maximum: 60
+
+ scope :visible, lambda {
+ includes(:project)
+ .references(:projects)
+ .merge(Project.allowed_to(User.current, :view_documents))
+ }
+
+ scope :with_attachments, lambda {
+ includes(:attachments)
+ .where('attachments.container_id is not NULL')
+ .references(:attachments)
+ }
+
+ after_initialize :set_default_category
+ after_create :notify_document_created
+
+ def visible?(user=User.current)
+ !user.nil? && user.allowed_to?(:view_documents, project)
+ end
+
+ def set_default_category
+ self.category ||= DocumentCategory.default if new_record?
+ end
+
+ def updated_on
+ unless @updated_on
+ # attachments has a default order that conflicts with `created_on DESC`
+ # #reorder removes that default order but rather than #unscoped keeps the
+ # scoping by this document
+ a = attachments.reorder('created_at DESC').first
+ @updated_on = (a && a.created_at) || created_on
+ end
+ @updated_on
+ end
+
+ private
+
+ def notify_document_created
+ return unless Setting.notified_events.include?('document_added')
+
+ recipients.each do |user|
+ DocumentsMailer.document_added(user, self).deliver_now
+ end
+ end
+end
diff --git a/modules/documents/app/models/document_category.rb b/modules/documents/app/models/document_category.rb
new file mode 100644
index 0000000000..2ff7f3fe43
--- /dev/null
+++ b/modules/documents/app/models/document_category.rb
@@ -0,0 +1,49 @@
+#-- encoding: UTF-8
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+class DocumentCategory < Enumeration
+ has_many :documents, foreign_key: 'category_id'
+
+ OptionName = :enumeration_doc_categories
+
+ def option_name
+ OptionName
+ end
+
+ def objects_count
+ documents.count
+ end
+
+ def transfer_relations(to)
+ documents.update_all("category_id = #{to.id}")
+ end
+end
diff --git a/modules/documents/app/models/document_category_custom_field.rb b/modules/documents/app/models/document_category_custom_field.rb
new file mode 100644
index 0000000000..6c4a945477
--- /dev/null
+++ b/modules/documents/app/models/document_category_custom_field.rb
@@ -0,0 +1,37 @@
+#-- encoding: UTF-8
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+class DocumentCategoryCustomField < CustomField
+ def type_name
+ :enumeration_doc_categories
+ end
+end
diff --git a/modules/documents/app/models/journal/document_journal.rb b/modules/documents/app/models/journal/document_journal.rb
new file mode 100644
index 0000000000..cbe8f7a798
--- /dev/null
+++ b/modules/documents/app/models/journal/document_journal.rb
@@ -0,0 +1,35 @@
+#-- encoding: UTF-8
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+class Journal::DocumentJournal < Journal::BaseJournal
+ self.table_name = "document_journals"
+end
diff --git a/modules/documents/app/seeders/enumeration_seeder.rb b/modules/documents/app/seeders/enumeration_seeder.rb
new file mode 100644
index 0000000000..9d3129c27a
--- /dev/null
+++ b/modules/documents/app/seeders/enumeration_seeder.rb
@@ -0,0 +1,50 @@
+#-- encoding: UTF-8
+#-- copyright
+# OpenProject is a project management system.
+# Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module BasicData
+ module Documents
+ class EnumerationsSeeder < Seeder
+ def seed_data!
+ category_names.each do |name|
+ DocumentCategory.create name: name
+ end
+ end
+
+ def category_names
+ category_i18n_keys.map { |key| I18n.t key }
+ end
+
+ def category_i18n_keys
+ ['documentation', 'specification', 'other'].map do |name|
+ ['enumeration', 'document_category', name].join('.')
+ end
+ end
+ end
+ end
+end
diff --git a/modules/documents/app/seeders/role_seeder.rb b/modules/documents/app/seeders/role_seeder.rb
new file mode 100644
index 0000000000..3ba418cb57
--- /dev/null
+++ b/modules/documents/app/seeders/role_seeder.rb
@@ -0,0 +1,24 @@
+module BasicData
+ module Documents
+ module RoleSeeder
+ def member
+ super.tap do |member|
+ member[:permissions].concat %i(
+ view_documents
+ manage_documents
+ )
+ end
+ end
+
+ def reader
+ super.tap do |reader|
+ reader[:permissions].concat %i(
+ view_documents
+ )
+ end
+ end
+ end
+
+ BasicData::RoleSeeder.prepend BasicData::Documents::RoleSeeder
+ end
+end
diff --git a/modules/documents/app/views/documents/_document.html.erb b/modules/documents/app/views/documents/_document.html.erb
new file mode 100644
index 0000000000..73b7f19846
--- /dev/null
+++ b/modules/documents/app/views/documents/_document.html.erb
@@ -0,0 +1,38 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+
diff --git a/modules/documents/app/views/documents/_form.html.erb b/modules/documents/app/views/documents/_form.html.erb
new file mode 100644
index 0000000000..b06bdfde20
--- /dev/null
+++ b/modules/documents/app/views/documents/_form.html.erb
@@ -0,0 +1,53 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<%= error_messages_for 'document' %>
+<% resource = ::API::V3::Documents::DocumentRepresenter.new(f.object,
+ current_user: current_user,
+ embed_links: true) %>
+
+
diff --git a/modules/documents/app/views/documents/edit.html.erb b/modules/documents/app/views/documents/edit.html.erb
new file mode 100644
index 0000000000..98a9871beb
--- /dev/null
+++ b/modules/documents/app/views/documents/edit.html.erb
@@ -0,0 +1,38 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<%= toolbar title: Document.model_name.human %>
+
+<%= labelled_tabular_form_for @document, url: document_path(@document), method: 'PATCH' do |f| -%>
+ <%= render partial: "documents/form", locals: { f: f } %>
+ <%= styled_button_tag l(:button_save), class: "-highlight -with-icon icon-checkmark" %>
+<% end %>
diff --git a/modules/documents/app/views/documents/index.html.erb b/modules/documents/app/views/documents/index.html.erb
new file mode 100644
index 0000000000..9adf4f5e8f
--- /dev/null
+++ b/modules/documents/app/views/documents/index.html.erb
@@ -0,0 +1,98 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<%= stylesheet_link_tag 'documents/documents.css' %>
+
+<%= toolbar title: l(:label_document_plural) do %>
+ <% if authorize_for(:documents, :new) %>
+
+
+<% end %>
+
+<% content_for :sidebar do %>
+ <%= form_tag({}, :method => :get, class: 'sidebar--document-sort') do %>
+
+ <% end %>
+<% end %>
+
+<%= nonced_javascript_tag do %>
+ jQuery(function($) {
+ $('.submit-this-form').click(function() {
+ $(this).closest('form').submit();
+ });
+ });
+<% end %>
+
+<% html_title(l(:label_document_plural)) -%>
diff --git a/modules/documents/app/views/documents/new.html.erb b/modules/documents/app/views/documents/new.html.erb
new file mode 100644
index 0000000000..6f63c1ba3a
--- /dev/null
+++ b/modules/documents/app/views/documents/new.html.erb
@@ -0,0 +1,39 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+<%= toolbar title: l(:label_document_new) %>
+
+<%= labelled_tabular_form_for @document, url: project_documents_path(@project), html: { multipart: true } do |f| -%>
+ <%= render :partial => 'documents/form', locals: { f: f } %>
+ <%= styled_button_tag l(:button_create), class: "-highlight -with-icon icon-checkmark" %>
+<% end %>
+
+
diff --git a/modules/documents/app/views/documents/show.html.erb b/modules/documents/app/views/documents/show.html.erb
new file mode 100644
index 0000000000..1e96833631
--- /dev/null
+++ b/modules/documents/app/views/documents/show.html.erb
@@ -0,0 +1,60 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<% html_title h(@document.title) -%>
+<%= toolbar title: @document.title,
+ subtitle: "#{@document.category.name} - #{format_date @document.created_on}" do %>
+ <% if authorize_for(:documents, :edit) %>
+
+
+<% resource = ::API::V3::Documents::DocumentRepresenter.new(@document,
+ current_user: current_user,
+ embed_links: true) %>
+<%= list_attachments(resource) %>
+
diff --git a/modules/documents/app/views/documents_mailer/document_added.html.erb b/modules/documents/app/views/documents_mailer/document_added.html.erb
new file mode 100644
index 0000000000..89c8f349de
--- /dev/null
+++ b/modules/documents/app/views/documents_mailer/document_added.html.erb
@@ -0,0 +1,35 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+
+
+<%= format_text @document.description %>
diff --git a/modules/documents/app/views/documents_mailer/document_added.text.erb b/modules/documents/app/views/documents_mailer/document_added.text.erb
new file mode 100644
index 0000000000..dfe6d94c69
--- /dev/null
+++ b/modules/documents/app/views/documents_mailer/document_added.text.erb
@@ -0,0 +1,36 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<%= @document.title %> (<%= @document.category.name %>)
+<%= project_documents_url(@document) %>
+
+<%= @document.description %>
diff --git a/modules/documents/app/views/help/wiki_syntax_detailed.html.erb b/modules/documents/app/views/help/wiki_syntax_detailed.html.erb
new file mode 100644
index 0000000000..d43658067d
--- /dev/null
+++ b/modules/documents/app/views/help/wiki_syntax_detailed.html.erb
@@ -0,0 +1,296 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<% content_for :styles do %>
+ body { font:80% Verdana,Tahoma,Arial,sans-serif; }
+ h1, h2, h3, h4 { font-family: Trebuchet MS,Georgia,"Times New Roman",serif; }
+ pre, code { font-size:120%; }
+ pre code { font-size:100%; }
+ pre {
+ margin: 1em 1em 1em 1.6em;
+ padding: 2px;
+ background-color: #fafafa;
+ border: 1px solid #dadada;
+ width:95%;
+ overflow-x: auto;
+ }
+ a.new { color: #b73535; }
+
+ .CodeRay .c { color:#666; }
+
+ .CodeRay .cl { color:#B06; font-weight:bold }
+ .CodeRay .dl { color:black }
+ .CodeRay .fu { color:#06B; font-weight:bold }
+
+ .CodeRay .il { background: #eee }
+ .CodeRay .il .idl { font-weight: bold; color: #888 }
+
+ .CodeRay .iv { color:#33B }
+ .CodeRay .r { color:#080; font-weight:bold }
+
+ .CodeRay .s { background-color:#fff0f0 }
+ .CodeRay .s .dl { color:#710 }
+<% end %>
+
+<% html_title "Wiki Formatting" %>
+
Wiki Formatting
+
+
Links
+
+
OpenProject links
+
+
OpenProject allows hyperlinking between issues, changesets and wiki pages from anywhere wiki formatting is used.
+
+
#124 displays a link to an issue: #124 (link is striked-through if the issue is closed)
+
##124 displays a link to an issue with context information: #12 New: Issue subject 2012-05-14 - 2012-05-23 (User Name - assigned to)
+
###124 displays a link to an issue with context information and an excerpt (first 3 lines) of the description
For things such as headlines, bold, tables, lists, OpenProject supports Textile syntax. See http://www.textism.com/tools/textile/ for information on using any of these features. A few samples are included below, but the engine is capable of much more of that.
!image_url! displays an image located at image_url (textile syntax)
+
!>image_url! right floating image
+
If you have an image attached to your wiki page, it can be displayed inline using its filename: !attached_image.png!
+
+
+
Headings
+
+
+h1. Heading
+h2. Subheading
+h3. Subsubheading
+
+
+
OpenProject assigns an anchor to each of those headings thus you can link to them with "#Heading", "#Subheading" and so forth.
+
+
+
Paragraphs
+
+
+p>. right aligned
+p=. centered
+
+
+
This is a centered paragraph.
+
+
+
Blockquotes
+
+
Start the paragraph with bq.
+
+
+bq. Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.
+To go live, all you need to add is a database and a web server.
+
+
+
Display:
+
+
+
Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern. To go live, all you need to add is a database and a web server.
+
+
+
+
Table of content
+
+
+{{toc}} => left aligned toc
+{{>toc}} => right aligned toc
+
+
+
Macros
+
+
OpenProject has the following builtin macros:
+
+
hello_world
Sample macro.
include
Include a wiki page. Example:
+
+
{{include(Foo)}}
macro_list
Displays a list of all available macros, including description if available.
+
+
+
Code highlighting
+
+
Code highlightment relies on CodeRay, a fast syntax highlighting library written completely in Ruby. It currently supports c, cpp, css, delphi, groovy, html, java, javascript, json, php, python, rhtml, ruby, scheme, sql, xml and yaml languages.
+
+
You can highlight code in your wiki page using this syntax:
+
+
+<pre><code class="ruby">
+ Place you code here.
+</code></pre>
+
diff --git a/modules/documents/app/views/hooks/documents/_activity_index_head.html.erb b/modules/documents/app/views/hooks/documents/_activity_index_head.html.erb
new file mode 100644
index 0000000000..1d14dbbf23
--- /dev/null
+++ b/modules/documents/app/views/hooks/documents/_activity_index_head.html.erb
@@ -0,0 +1,33 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<%= stylesheet_link_tag 'documents/documents.css' %>
diff --git a/modules/documents/app/views/my/blocks/_documents.html.erb b/modules/documents/app/views/my/blocks/_documents.html.erb
new file mode 100644
index 0000000000..1e097ade56
--- /dev/null
+++ b/modules/documents/app/views/my/blocks/_documents.html.erb
@@ -0,0 +1,48 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<% if defined? block_name %>
+ <%= content_for "#{block_name}-remove-block" %>
+<% end %>
+
+
+
+<% project_ids = @user.projects.select {|p| @user.allowed_to?(:view_documents, p)}.collect(&:id) %>
+<%= render(partial: 'documents/document',
+ collection: Document
+ .limit(10)
+ .order("#{Document.table_name}.created_on DESC")
+ .where("#{Document.table_name}.project_id in (#{project_ids.join(',')})")
+ .includes(:project)) unless project_ids.empty? %>
diff --git a/modules/documents/app/views/my_projects_overviews/blocks/_documents.html.erb b/modules/documents/app/views/my_projects_overviews/blocks/_documents.html.erb
new file mode 100644
index 0000000000..fc406f7ed0
--- /dev/null
+++ b/modules/documents/app/views/my_projects_overviews/blocks/_documents.html.erb
@@ -0,0 +1,46 @@
+<%#-- copyright
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
+
+++#%>
+
+<% if defined? block_name_id %>
+ <%= content_for block_name_id %>
+<% end %>
+
+
+
+
+<% if current_user.allowed_to?(:view_documents, @project)%>
+ <%= render(:partial => 'documents/document',
+ :collection => Document.where(project_id: @project.id).limit(10).order("created_on DESC")) %>
+<% end %>
diff --git a/modules/documents/config/locales/crowdin/ar.yml b/modules/documents/config/locales/crowdin/ar.yml
new file mode 100644
index 0000000000..544f3ed3f2
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/ar.yml
@@ -0,0 +1,19 @@
+ar:
+ activerecord:
+ models:
+ document: "الوثيقة"
+ default_doc_category_tech: "التوثيق التقني"
+ default_doc_category_user: "توثيق المستخدم"
+ enumeration_doc_categories: "فئات الوثائق"
+ enumeration:
+ document_category:
+ documentation: التوثيق
+ specification: المواصفة
+ other: أخرى
+ label_document_added: "تم إضافة وثيقة"
+ label_document_new: "وثيقة جديدة"
+ label_document_plural: "الوثائق"
+ label_documents: "الوثائق"
+ permission_manage_documents: "إدارة الوثائق"
+ permission_view_documents: "عرض الوثائق"
+ project_module_documents: "الوثائق"
diff --git a/modules/documents/config/locales/crowdin/bg.yml b/modules/documents/config/locales/crowdin/bg.yml
new file mode 100644
index 0000000000..7e8e61a0f7
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/bg.yml
@@ -0,0 +1,19 @@
+bg:
+ activerecord:
+ models:
+ document: "Документ"
+ default_doc_category_tech: "Техническа документация"
+ default_doc_category_user: "Документация за потребителя"
+ enumeration_doc_categories: "Document categories"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Specification
+ other: Other
+ label_document_added: "Документът е добавен"
+ label_document_new: "Нов документ"
+ label_document_plural: "Документи"
+ label_documents: "Документи"
+ permission_manage_documents: "Управление на документите"
+ permission_view_documents: "Преглед на документите"
+ project_module_documents: "Документи"
diff --git a/modules/documents/config/locales/crowdin/da.yml b/modules/documents/config/locales/crowdin/da.yml
new file mode 100644
index 0000000000..a133f54063
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/da.yml
@@ -0,0 +1,19 @@
+da:
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Teknisk dokumentation"
+ default_doc_category_user: "Brugerdokumentation"
+ enumeration_doc_categories: "Dokumentkategorier"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Specification
+ other: Other
+ label_document_added: "Dokument tilføjet"
+ label_document_new: "Nyt dokument"
+ label_document_plural: "Dokumenter"
+ label_documents: "Dokumenter"
+ permission_manage_documents: "Håndter dokumenter"
+ permission_view_documents: "Se dokumenter"
+ project_module_documents: "Dokumenter"
diff --git a/modules/documents/config/locales/crowdin/de.yml b/modules/documents/config/locales/crowdin/de.yml
new file mode 100644
index 0000000000..b5c06a946e
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/de.yml
@@ -0,0 +1,19 @@
+de:
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Technische Dokumentation"
+ default_doc_category_user: "Benutzerdokumentation"
+ enumeration_doc_categories: "Dokumentenkategorien"
+ enumeration:
+ document_category:
+ documentation: Dokumentation
+ specification: Spezifikation
+ other: Andere
+ label_document_added: "Dokument hinzugefügt"
+ label_document_new: "Neues Dokument"
+ label_document_plural: "Dokumente"
+ label_documents: "Dokumente"
+ permission_manage_documents: "Dokumente verwalten"
+ permission_view_documents: "Dokumente ansehen"
+ project_module_documents: "Dokumente"
diff --git a/modules/documents/config/locales/crowdin/es-ES.yml b/modules/documents/config/locales/crowdin/es-ES.yml
new file mode 100644
index 0000000000..56ef1db9de
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/es-ES.yml
@@ -0,0 +1,19 @@
+es:
+ activerecord:
+ models:
+ document: "Documento"
+ default_doc_category_tech: "Documentación técnica"
+ default_doc_category_user: "Documentacion para el usuario"
+ enumeration_doc_categories: "Categorías de documentos"
+ enumeration:
+ document_category:
+ documentation: Documentación
+ specification: Especificación
+ other: Otros
+ label_document_added: "Documento agregado"
+ label_document_new: "Nuevo documento"
+ label_document_plural: "Documentos"
+ label_documents: "Documentos"
+ permission_manage_documents: "Administrar documentos"
+ permission_view_documents: "Ver documentos"
+ project_module_documents: "Documentos"
diff --git a/modules/documents/config/locales/crowdin/et.yml b/modules/documents/config/locales/crowdin/et.yml
new file mode 100644
index 0000000000..3be9b0ce07
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/et.yml
@@ -0,0 +1,19 @@
+et:
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Tehniline dokumentatsioon"
+ default_doc_category_user: "Kasutaja dokumentatsioon"
+ enumeration_doc_categories: "Dokumentide kategooriad"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Specification
+ other: Other
+ label_document_added: "Dokument on lisatud"
+ label_document_new: "Uus dokument"
+ label_document_plural: "Dokumendid"
+ label_documents: "Dokumendid"
+ permission_manage_documents: "Dokumentide haldamine"
+ permission_view_documents: "Dokumentide vaatamine"
+ project_module_documents: "Dokumendid"
diff --git a/modules/documents/config/locales/crowdin/fi.yml b/modules/documents/config/locales/crowdin/fi.yml
new file mode 100644
index 0000000000..d20eb3d0d0
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/fi.yml
@@ -0,0 +1,19 @@
+fi:
+ activerecord:
+ models:
+ document: "Asiakirja"
+ default_doc_category_tech: "Tekniset asiakirjat"
+ default_doc_category_user: "Käyttöohjeet"
+ enumeration_doc_categories: "Tiedostoluokat"
+ enumeration:
+ document_category:
+ documentation: Käyttöohjeet
+ specification: Määrittely
+ other: Muut
+ label_document_added: "Asiakirja lisätty"
+ label_document_new: "Uusi asiakirja"
+ label_document_plural: "Asiakirjat"
+ label_documents: "Asiakirjat"
+ permission_manage_documents: "Hallitse asiakirjoja"
+ permission_view_documents: "Näytä asiakirjat"
+ project_module_documents: "Asiakirjat"
diff --git a/modules/documents/config/locales/crowdin/fil.yml b/modules/documents/config/locales/crowdin/fil.yml
new file mode 100644
index 0000000000..d68d56fd4f
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/fil.yml
@@ -0,0 +1,19 @@
+fil:
+ activerecord:
+ models:
+ document: "Dokumento"
+ default_doc_category_tech: "Teknikal na dokumentasyon"
+ default_doc_category_user: "Dokumento para sa mga gagamit"
+ enumeration_doc_categories: "Mga kategorya ng dokumento"
+ enumeration:
+ document_category:
+ documentation: Dokumentasyon
+ specification: Mga Detalye
+ other: Iba pa
+ label_document_added: "Idinagdag ang dokumento"
+ label_document_new: "Bagong dokumento"
+ label_document_plural: "Mga dokumento"
+ label_documents: "Mga dokumento"
+ permission_manage_documents: "Pamahalaan ang mga dokumento"
+ permission_view_documents: "Tingnan ang dokumento"
+ project_module_documents: "Mga dokumento"
diff --git a/modules/documents/config/locales/crowdin/fr.yml b/modules/documents/config/locales/crowdin/fr.yml
new file mode 100644
index 0000000000..d752a73f44
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/fr.yml
@@ -0,0 +1,19 @@
+fr:
+ activerecord:
+ models:
+ document: "Document"
+ default_doc_category_tech: "Documentation technique"
+ default_doc_category_user: "Documentation utilisateur"
+ enumeration_doc_categories: "Catégories de documents"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Spécification
+ other: Autre
+ label_document_added: "Document ajouté"
+ label_document_new: "Nouveau document"
+ label_document_plural: "Documents"
+ label_documents: "Documents"
+ permission_manage_documents: "Gérer les documents"
+ permission_view_documents: "Consulter les documents"
+ project_module_documents: "Documents"
diff --git a/modules/documents/config/locales/crowdin/hr.yml b/modules/documents/config/locales/crowdin/hr.yml
new file mode 100644
index 0000000000..d705ff4843
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/hr.yml
@@ -0,0 +1,19 @@
+hr:
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Tehnička dokumentacija"
+ default_doc_category_user: "Korisnička dokumentacija"
+ enumeration_doc_categories: "Kategorije dokumenata"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Specification
+ other: Other
+ label_document_added: "Dokument dodan"
+ label_document_new: "Novi dokument"
+ label_document_plural: "Dokumenti"
+ label_documents: "Dokumenti"
+ permission_manage_documents: "Upravljanje dokumentima"
+ permission_view_documents: "Pogledaj dokumente"
+ project_module_documents: "Dokumenti"
diff --git a/modules/documents/config/locales/crowdin/hu.yml b/modules/documents/config/locales/crowdin/hu.yml
new file mode 100644
index 0000000000..6a64966cc0
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/hu.yml
@@ -0,0 +1,19 @@
+hu:
+ activerecord:
+ models:
+ document: "Dokumentum"
+ default_doc_category_tech: "Technikai dokumentáció"
+ default_doc_category_user: "Felhasználói dokumentáció"
+ enumeration_doc_categories: "Dokumentum kategóriák"
+ enumeration:
+ document_category:
+ documentation: Dokumentáció
+ specification: Specifikáció
+ other: Egyéb
+ label_document_added: "Dokumentum hozzáadva"
+ label_document_new: "Új dokumentum"
+ label_document_plural: "Dokumentumok"
+ label_documents: "Dokumentumok"
+ permission_manage_documents: "Dokumentumok kezelése"
+ permission_view_documents: "Dokumetumok megtekintése"
+ project_module_documents: "Dokumentumok"
diff --git a/modules/documents/config/locales/crowdin/id.yml b/modules/documents/config/locales/crowdin/id.yml
new file mode 100644
index 0000000000..28a14a56be
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/id.yml
@@ -0,0 +1,19 @@
+id:
+ activerecord:
+ models:
+ document: "Dokumen"
+ default_doc_category_tech: "Dokumentasi teknis"
+ default_doc_category_user: "Dokumentasi pengguna"
+ enumeration_doc_categories: "Kategori dokumen"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Specification
+ other: Other
+ label_document_added: "Dokumen ditambahkan"
+ label_document_new: "Dokumen baru"
+ label_document_plural: "Dokumen"
+ label_documents: "Dokumen"
+ permission_manage_documents: "Kelola dokumen"
+ permission_view_documents: "Lihat dokumen"
+ project_module_documents: "Dokumen"
diff --git a/modules/documents/config/locales/crowdin/it.yml b/modules/documents/config/locales/crowdin/it.yml
new file mode 100644
index 0000000000..9ed792e097
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/it.yml
@@ -0,0 +1,19 @@
+it:
+ activerecord:
+ models:
+ document: "Documento"
+ default_doc_category_tech: "Documentazione tecnica"
+ default_doc_category_user: "Documentazione utente"
+ enumeration_doc_categories: "Categorie di documenti"
+ enumeration:
+ document_category:
+ documentation: Documentazione
+ specification: Specifiche
+ other: Altro
+ label_document_added: "Documento aggiunto"
+ label_document_new: "Nuovo Documento"
+ label_document_plural: "Documenti"
+ label_documents: "Documenti"
+ permission_manage_documents: "Gestione documenti"
+ permission_view_documents: "Visualizzare i documenti"
+ project_module_documents: "Documenti"
diff --git a/modules/documents/config/locales/crowdin/ja.yml b/modules/documents/config/locales/crowdin/ja.yml
new file mode 100644
index 0000000000..69efae24b1
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/ja.yml
@@ -0,0 +1,19 @@
+ja:
+ activerecord:
+ models:
+ document: "ドキュメント"
+ default_doc_category_tech: "技術文書"
+ default_doc_category_user: "ユーザー文書"
+ enumeration_doc_categories: "ドキュメントのカテゴリ"
+ enumeration:
+ document_category:
+ documentation: 文章
+ specification: 仕様
+ other: その他
+ label_document_added: "追加されたドキュメント"
+ label_document_new: "新しいドキュメント"
+ label_document_plural: "ドキュメント"
+ label_documents: "ドキュメント"
+ permission_manage_documents: "ドキュメントを管理"
+ permission_view_documents: "ドキュメントの表示"
+ project_module_documents: "ドキュメント"
diff --git a/modules/documents/config/locales/crowdin/ko.yml b/modules/documents/config/locales/crowdin/ko.yml
new file mode 100644
index 0000000000..e807863669
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/ko.yml
@@ -0,0 +1,19 @@
+ko:
+ activerecord:
+ models:
+ document: "문서"
+ default_doc_category_tech: "기술 설명서"
+ default_doc_category_user: "사용자 설명서"
+ enumeration_doc_categories: "문서 범주"
+ enumeration:
+ document_category:
+ documentation: 설명서
+ specification: 사양
+ other: 기타
+ label_document_added: "문서 추가됨"
+ label_document_new: "새 문서"
+ label_document_plural: "문서"
+ label_documents: "문서"
+ permission_manage_documents: "문서 관리"
+ permission_view_documents: "문서 보기"
+ project_module_documents: "문서"
diff --git a/modules/documents/config/locales/crowdin/lt.yml b/modules/documents/config/locales/crowdin/lt.yml
new file mode 100644
index 0000000000..b9a87fde0c
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/lt.yml
@@ -0,0 +1,19 @@
+lt:
+ activerecord:
+ models:
+ document: "Dokumentas"
+ default_doc_category_tech: "Techninė dokumentacija"
+ default_doc_category_user: "Vartotojo dokumentacija"
+ enumeration_doc_categories: "Dokumentų kategorijos"
+ enumeration:
+ document_category:
+ documentation: Dokumentacija
+ specification: Specifikacija
+ other: Kita
+ label_document_added: "Dokumentas pridėtas"
+ label_document_new: "Naujas dokumentas"
+ label_document_plural: "Dokumentai"
+ label_documents: "Dokumentai"
+ permission_manage_documents: "Valdyti dokumentus"
+ permission_view_documents: "Peržiūrėti dokumentus"
+ project_module_documents: "Dokumentai"
diff --git a/modules/documents/config/locales/crowdin/no.yml b/modules/documents/config/locales/crowdin/no.yml
new file mode 100644
index 0000000000..2d11c4b38e
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/no.yml
@@ -0,0 +1,19 @@
+"no":
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Teknisk dokumentasjon"
+ default_doc_category_user: "Brukerdokumentasjon"
+ enumeration_doc_categories: "Dokumentkategorier"
+ enumeration:
+ document_category:
+ documentation: Dokumentasjon
+ specification: Spesifikasjon
+ other: Andre
+ label_document_added: "Dokument lagt til"
+ label_document_new: "Nytt dokumenter"
+ label_document_plural: "Dokumenter"
+ label_documents: "Dokumenter"
+ permission_manage_documents: "Administrere dokumenter"
+ permission_view_documents: "Vise dokumenter"
+ project_module_documents: "Dokumenter"
diff --git a/modules/documents/config/locales/crowdin/pl.yml b/modules/documents/config/locales/crowdin/pl.yml
new file mode 100644
index 0000000000..7396db3cf6
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/pl.yml
@@ -0,0 +1,19 @@
+pl:
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Dokumentacja techniczna"
+ default_doc_category_user: "Dokumentacja użytkownika"
+ enumeration_doc_categories: "Kategoria dokumentu"
+ enumeration:
+ document_category:
+ documentation: Dokumentacja
+ specification: Specyfikacja
+ other: Inne
+ label_document_added: "Dodano dokument"
+ label_document_new: "Nowy dokument"
+ label_document_plural: "Dokumenty"
+ label_documents: "Dokumenty"
+ permission_manage_documents: "Zarządzanie dokumentami"
+ permission_view_documents: "Zobacz dokumenty"
+ project_module_documents: "Dokumenty"
diff --git a/modules/documents/config/locales/crowdin/pt-BR.yml b/modules/documents/config/locales/crowdin/pt-BR.yml
new file mode 100644
index 0000000000..05215b4fd3
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/pt-BR.yml
@@ -0,0 +1,19 @@
+pt-BR:
+ activerecord:
+ models:
+ document: "Documento"
+ default_doc_category_tech: "Documentação técnica"
+ default_doc_category_user: "Documentação do usuário"
+ enumeration_doc_categories: "Categorias de documento"
+ enumeration:
+ document_category:
+ documentation: Documentação
+ specification: Especificação
+ other: Outro
+ label_document_added: "Documento adicionado"
+ label_document_new: "Novo documento"
+ label_document_plural: "Documentos"
+ label_documents: "Documentos"
+ permission_manage_documents: "Gerenciar documentos"
+ permission_view_documents: "Visualizar documentos"
+ project_module_documents: "Documentos"
diff --git a/modules/documents/config/locales/crowdin/pt-PT.yml b/modules/documents/config/locales/crowdin/pt-PT.yml
new file mode 100644
index 0000000000..196f981d71
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/pt-PT.yml
@@ -0,0 +1,19 @@
+pt:
+ activerecord:
+ models:
+ document: "Documento"
+ default_doc_category_tech: "Documentação técnica"
+ default_doc_category_user: "Documentação de utilizador"
+ enumeration_doc_categories: "Categorias de documentos"
+ enumeration:
+ document_category:
+ documentation: Documentação
+ specification: Especificação
+ other: Outro
+ label_document_added: "Documento adicionado"
+ label_document_new: "Novo documento"
+ label_document_plural: "Documentos"
+ label_documents: "Documentos"
+ permission_manage_documents: "Gerir documentos"
+ permission_view_documents: "Ver documentos"
+ project_module_documents: "Documentos"
diff --git a/modules/documents/config/locales/crowdin/ru.yml b/modules/documents/config/locales/crowdin/ru.yml
new file mode 100644
index 0000000000..d2af39b838
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/ru.yml
@@ -0,0 +1,19 @@
+ru:
+ activerecord:
+ models:
+ document: "Документ"
+ default_doc_category_tech: "Техническая документация"
+ default_doc_category_user: "Документация пользователя"
+ enumeration_doc_categories: "Категории документов"
+ enumeration:
+ document_category:
+ documentation: Документация
+ specification: Спецификация
+ other: Прочее
+ label_document_added: "Документ добавлен"
+ label_document_new: "Новый документ"
+ label_document_plural: "Документы"
+ label_documents: "Документы"
+ permission_manage_documents: "Управление документами"
+ permission_view_documents: "Просмотр документов"
+ project_module_documents: "Документы"
diff --git a/modules/documents/config/locales/crowdin/sk.yml b/modules/documents/config/locales/crowdin/sk.yml
new file mode 100644
index 0000000000..1cb9d6fc3c
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/sk.yml
@@ -0,0 +1,19 @@
+sk:
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Technická dokumentácia"
+ default_doc_category_user: "Používateľská dokumentácia"
+ enumeration_doc_categories: "Kategórie dokumentu"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Specification
+ other: Other
+ label_document_added: "Dokument pridaný"
+ label_document_new: "Nový dokument"
+ label_document_plural: "Dokumenty"
+ label_documents: "Dokumenty"
+ permission_manage_documents: "Správa dokumentov"
+ permission_view_documents: "Zobrazenie dokumentov"
+ project_module_documents: "Dokumenty"
diff --git a/modules/documents/config/locales/crowdin/sv-SE.yml b/modules/documents/config/locales/crowdin/sv-SE.yml
new file mode 100644
index 0000000000..9a9b3ac551
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/sv-SE.yml
@@ -0,0 +1,19 @@
+sv:
+ activerecord:
+ models:
+ document: "Dokument"
+ default_doc_category_tech: "Teknisk dokumentation"
+ default_doc_category_user: "Användardokumentation"
+ enumeration_doc_categories: "Dokumentkategorier"
+ enumeration:
+ document_category:
+ documentation: Dokumentation
+ specification: Specifikation
+ other: Andra
+ label_document_added: "Dokumentet tillagt"
+ label_document_new: "Nytt dokument"
+ label_document_plural: "Dokument"
+ label_documents: "Dokument"
+ permission_manage_documents: "Hantera dokument"
+ permission_view_documents: "Visa dokument"
+ project_module_documents: "Dokument"
diff --git a/modules/documents/config/locales/crowdin/tr.yml b/modules/documents/config/locales/crowdin/tr.yml
new file mode 100644
index 0000000000..fae7c686a7
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/tr.yml
@@ -0,0 +1,19 @@
+tr:
+ activerecord:
+ models:
+ document: "Belge"
+ default_doc_category_tech: "Teknik belgeler"
+ default_doc_category_user: "Kullanıcı belgeleri"
+ enumeration_doc_categories: "Belge kategorileri"
+ enumeration:
+ document_category:
+ documentation: Belgeleme
+ specification: Şartname
+ other: Diğer
+ label_document_added: "Belge eklendi"
+ label_document_new: "Yeni belge"
+ label_document_plural: "Belgeler"
+ label_documents: "Belgeler"
+ permission_manage_documents: "Belgeleri yönetme"
+ permission_view_documents: "Belgeleri görüntüleme"
+ project_module_documents: "Belgeler"
diff --git a/modules/documents/config/locales/crowdin/zh-CN.yml b/modules/documents/config/locales/crowdin/zh-CN.yml
new file mode 100644
index 0000000000..e9634d8c36
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/zh-CN.yml
@@ -0,0 +1,19 @@
+zh-CN:
+ activerecord:
+ models:
+ document: "文档"
+ default_doc_category_tech: "技术文档"
+ default_doc_category_user: "用户文档"
+ enumeration_doc_categories: "文档类别"
+ enumeration:
+ document_category:
+ documentation: 文档
+ specification: 技术规范
+ other: ' 其它'
+ label_document_added: "文档已添加"
+ label_document_new: "新建文档"
+ label_document_plural: "文档"
+ label_documents: "文档"
+ permission_manage_documents: "管理文档"
+ permission_view_documents: "查看文档"
+ project_module_documents: "文档"
diff --git a/modules/documents/config/locales/crowdin/zh-TW.yml b/modules/documents/config/locales/crowdin/zh-TW.yml
new file mode 100644
index 0000000000..9e0fce83b8
--- /dev/null
+++ b/modules/documents/config/locales/crowdin/zh-TW.yml
@@ -0,0 +1,19 @@
+zh-TW:
+ activerecord:
+ models:
+ document: "文件"
+ default_doc_category_tech: "技術文件"
+ default_doc_category_user: "使用者文件"
+ enumeration_doc_categories: "文件類別"
+ enumeration:
+ document_category:
+ documentation: 說明文件
+ specification: 技術規格
+ other: 其他
+ label_document_added: "文件已新增"
+ label_document_new: "建立新文件"
+ label_document_plural: "文件"
+ label_documents: "文件"
+ permission_manage_documents: "管理文件"
+ permission_view_documents: "檢視文件"
+ project_module_documents: "文件"
diff --git a/modules/documents/config/locales/en.yml b/modules/documents/config/locales/en.yml
new file mode 100644
index 0000000000..da7569f40d
--- /dev/null
+++ b/modules/documents/config/locales/en.yml
@@ -0,0 +1,54 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+en:
+ activerecord:
+ models:
+ document: "Document"
+
+ default_doc_category_tech: "Technical documentation"
+ default_doc_category_user: "User documentation"
+
+ enumeration_doc_categories: "Document categories"
+ enumeration:
+ document_category:
+ documentation: Documentation
+ specification: Specification
+ other: Other
+
+ label_document_added: "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"
diff --git a/modules/documents/config/routes.rb b/modules/documents/config/routes.rb
new file mode 100644
index 0000000000..7a58f31c0a
--- /dev/null
+++ b/modules/documents/config/routes.rb
@@ -0,0 +1,42 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+OpenProject::Application.routes.draw do
+ resources :projects, only: [] do
+ resources :documents, only: [:create, :new, :index]
+ end
+
+ resources :documents, except: [:create, :new, :index] do
+ member do
+ post 'add_attachment'
+ end
+ end
+end
diff --git a/modules/documents/db/migrate/20180323140208_to_v710_aggregated_documents_migrations.rb b/modules/documents/db/migrate/20180323140208_to_v710_aggregated_documents_migrations.rb
new file mode 100644
index 0000000000..c01285e7b1
--- /dev/null
+++ b/modules/documents/db/migrate/20180323140208_to_v710_aggregated_documents_migrations.rb
@@ -0,0 +1,66 @@
+#-- copyright
+# OpenProject Reporting Plugin
+#
+# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# version 3.
+#
+# 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.
+#++
+
+require Rails.root.join("db","migrate","migration_utils","migration_squasher").to_s
+# This migration aggregates the migrations detailed in MIGRATION_FILES
+class ToV710AggregatedDocumentsMigrations < ActiveRecord::Migration[5.1]
+
+ MIGRATION_FILES = <<-MIGRATIONS
+ 20130807085604_create_document_journals.rb
+ 20130814131242_create_documents_tables.rb
+ 20140320140001_legacy_document_journal_data.rb
+ MIGRATIONS
+
+ def up
+ Migration::MigrationSquasher.squash(migrations) do
+ create_table "documents", id: :integer do |t|
+ t.integer "project_id", :default => 0, :null => false
+ t.integer "category_id", :default => 0, :null => false
+ t.string "title", :limit => 60, :default => "", :null => false
+ t.text "description"
+ t.datetime "created_on"
+ end
+ add_index "documents", ["category_id"], :name => "index_documents_on_category_id"
+ add_index "documents", ["created_on"], :name => "index_documents_on_created_on"
+ add_index "documents", ["project_id"], :name => "documents_project_id"
+
+ create_table :document_journals, id: :integer do |t|
+ t.integer :journal_id, :null => false
+ t.integer :project_id, :default => 0, :null => false
+ t.integer :category_id, :default => 0, :null => false
+ t.string :title, :limit => 60, :default => "", :null => false
+ t.text :description
+ t.datetime :created_on
+ end
+ end
+ end
+
+ def down
+ drop_table :documents
+ drop_table :document_journals
+ end
+
+ private
+
+ def migrations
+ MIGRATION_FILES.split.map do |m|
+ m.gsub(/_.*\z/, '')
+ end
+ end
+end
diff --git a/modules/documents/doc/CHANGELOG.md b/modules/documents/doc/CHANGELOG.md
new file mode 100644
index 0000000000..ab4a51fba3
--- /dev/null
+++ b/modules/documents/doc/CHANGELOG.md
@@ -0,0 +1,69 @@
+
+
+# Changelog
+
+## 3.0.8
+
+* `#7679` Fix: Permissions not nested in 'documents' project module
+* `#5650` Fix: Acts as event datetime
+
+## 1.0.1
+
+* `#5361` Add missing journal data migration
+
+## 1.0.0
+
+* `#3329` Refactor Duplicated Code Journals
+* `#5190` Public Release Documents plugin
+* Adaptations for new icon font
+
+## 1.0.0.pre5
+
+* `#2402` Activated migrations running from the plugin
+* Additional namespacing of hook partials to prevent clashes on activity view
+
+## 1.0.0.pre4
+
+* `#1875` Added document block to my project page
+
+## 1.0.0.pre3
+
+* Removed hard wiring to specific core version
+
+## 1.0.0.pre2
+
+* `#1602` Adaptions to Core acts_as_journalized_changes
+
+## 1.0.0.pre1
+
+* `#1631` Initial creation of Documents plugin
diff --git a/modules/documents/doc/COPYRIGHT.md b/modules/documents/doc/COPYRIGHT.md
new file mode 100644
index 0000000000..06e4c258cf
--- /dev/null
+++ b/modules/documents/doc/COPYRIGHT.md
@@ -0,0 +1,63 @@
+OpenProject Documents Plugin
+
+This plugin adds features to connect and categorize documents with your project.
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+version 3.
+
+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.
+
+---
+
+OpenProject is a derivative work based on ChiliProject, whose Copyright follows.
+
+ChiliProject is a project management system.
+
+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.
+
+---
+
+ChiliProject is a derivative work based on Redmine, whose Copyright follows.
+
+Redmine - project management software
+Copyright (C) 2006-2013 Jean-Philippe Lang
+
+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.
diff --git a/modules/documents/doc/COPYRIGHT_short.md b/modules/documents/doc/COPYRIGHT_short.md
new file mode 100644
index 0000000000..889081eeb1
--- /dev/null
+++ b/modules/documents/doc/COPYRIGHT_short.md
@@ -0,0 +1,28 @@
+OpenProject Documents Plugin
+
+Former OpenProject Core functionality extracted into a plugin.
+
+Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+
+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 doc/COPYRIGHT.rdoc for more details.
diff --git a/modules/documents/doc/GPL.txt b/modules/documents/doc/GPL.txt
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/documents/doc/GPL.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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 3 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, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/documents/frontend/module/hal/resources/document-resource.ts b/modules/documents/frontend/module/hal/resources/document-resource.ts
new file mode 100644
index 0000000000..7bd122747e
--- /dev/null
+++ b/modules/documents/frontend/module/hal/resources/document-resource.ts
@@ -0,0 +1,50 @@
+// -- copyright
+// OpenProject Documents Plugin
+//
+// Former OpenProject Core functionality extracted into a plugin.
+//
+// Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+//
+// 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 doc/COPYRIGHT.rdoc for more details.
+// ++
+
+// This resource exists solely for the purpose of uploading attachments via the
+// WYSIWYIG editor.
+import {HalResource} from 'core-app/modules/hal/resources/hal-resource';
+import {Attachable} from 'core-app/modules/hal/resources/mixins/attachable-mixin';
+
+export interface DocumentResourceLinks {
+ addAttachment(attachment:HalResource):Promise;
+}
+
+class DocumentBaseResource extends HalResource {
+ public $links:DocumentResourceLinks;
+
+ private attachmentsBackend = false;
+}
+
+export const DocumentResource = Attachable(DocumentBaseResource);
+
+export interface DocumentResource extends DocumentBaseResource {
+}
diff --git a/modules/documents/frontend/module/main.ts b/modules/documents/frontend/module/main.ts
new file mode 100644
index 0000000000..503c7f5e3a
--- /dev/null
+++ b/modules/documents/frontend/module/main.ts
@@ -0,0 +1,57 @@
+// -- copyright
+// OpenProject Documents Plugin
+//
+// Former OpenProject Core functionality extracted into a plugin.
+//
+// Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+//
+// 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 doc/COPYRIGHT.rdoc for more details.
+// ++
+
+import {APP_INITIALIZER, Injector, NgModule} from '@angular/core';
+import {OpenProjectPluginContext} from "core-app/modules/plugins/plugin-context";
+import {DocumentResource} from './hal/resources/document-resource';
+import {multiInput} from 'reactivestates';
+
+export function initializeDocumentPlugin() {
+ return () => {
+ window.OpenProject.getPluginContext()
+ .then((pluginContext:OpenProjectPluginContext) => {
+ let halResourceService = pluginContext.services.halResource;
+ halResourceService.registerResource('Document', { cls: DocumentResource });
+
+ let states = pluginContext.services.states;
+ states.add('documents', multiInput());
+ });
+ };
+}
+
+
+@NgModule({
+ providers: [
+ { provide: APP_INITIALIZER, useFactory: initializeDocumentPlugin, deps: [Injector], multi: true },
+ ],
+})
+export class PluginModule {
+}
diff --git a/modules/documents/lib/api/v3/attachments/attachments_by_document_api.rb b/modules/documents/lib/api/v3/attachments/attachments_by_document_api.rb
new file mode 100644
index 0000000000..e8baf8dbc7
--- /dev/null
+++ b/modules/documents/lib/api/v3/attachments/attachments_by_document_api.rb
@@ -0,0 +1,52 @@
+#-- copyright
+# OpenProject is a project management system.
+# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
+#
+# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
+#++
+
+module API
+ module V3
+ module Attachments
+ class AttachmentsByDocumentAPI < ::API::OpenProjectAPI
+ resources :attachments do
+ helpers API::V3::Attachments::AttachmentsByContainerAPI::Helpers
+
+ helpers do
+ def container
+ document
+ end
+
+ def get_attachment_self_path
+ api_v3_paths.attachments_by_document(container.id)
+ end
+ end
+
+ get &API::V3::Attachments::AttachmentsByContainerAPI.read
+ post &API::V3::Attachments::AttachmentsByContainerAPI.create
+ end
+ end
+ end
+ end
+end
diff --git a/modules/documents/lib/api/v3/documents/document_representer.rb b/modules/documents/lib/api/v3/documents/document_representer.rb
new file mode 100644
index 0000000000..7ff06406c6
--- /dev/null
+++ b/modules/documents/lib/api/v3/documents/document_representer.rb
@@ -0,0 +1,60 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module API
+ module V3
+ module Documents
+ class DocumentRepresenter < ::API::Decorators::Single
+ include API::Decorators::LinkedResource
+ include API::Caching::CachedRepresenter
+ include ::API::V3::Attachments::AttachableRepresenterMixin
+
+ self_link title_getter: ->(*) { represented.title }
+
+ property :id
+
+ property :title
+
+ associated_resource :project,
+ link: ->(*) do
+ {
+ href: api_v3_paths.project(represented.project.id),
+ title: represented.project.name
+ }
+ end
+
+ def _type
+ 'Document'
+ end
+ end
+ end
+ end
+end
diff --git a/modules/documents/lib/api/v3/documents/documents_api.rb b/modules/documents/lib/api/v3/documents/documents_api.rb
new file mode 100644
index 0000000000..3af2a63e4a
--- /dev/null
+++ b/modules/documents/lib/api/v3/documents/documents_api.rb
@@ -0,0 +1,56 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module API
+ module V3
+ module Documents
+ class DocumentsAPI < ::API::OpenProjectAPI
+ resources :documents do
+ helpers do
+ def document
+ Document.visible.find(params[:id])
+ end
+ end
+
+ route_param :id do
+ get do
+ ::API::V3::Documents::DocumentRepresenter.new(document,
+ current_user: current_user,
+ embed_links: true)
+ end
+
+ mount ::API::V3::Attachments::AttachmentsByDocumentAPI
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/modules/documents/lib/open_project/documents.rb b/modules/documents/lib/open_project/documents.rb
new file mode 100644
index 0000000000..0e82d37d2e
--- /dev/null
+++ b/modules/documents/lib/open_project/documents.rb
@@ -0,0 +1,36 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject
+ module Documents
+ require "open_project/documents/engine"
+ end
+end
diff --git a/modules/documents/lib/open_project/documents/engine.rb b/modules/documents/lib/open_project/documents/engine.rb
new file mode 100644
index 0000000000..ee939b1d15
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/engine.rb
@@ -0,0 +1,104 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject::Documents
+ class Engine < ::Rails::Engine
+ engine_name :openproject_documents
+
+ include OpenProject::Plugins::ActsAsOpEngine
+
+ register 'openproject-documents',
+ author_url: "http://www.openproject.com",
+ global_assets: { css: 'documents/global_rules' },
+ requires_openproject: ">= 4.0.0" do
+
+ menu :project_menu, :documents,
+ { controller: '/documents', action: 'index' },
+ param: :project_id,
+ caption: :label_document_plural,
+ icon: 'icon2 icon-notes'
+
+ project_module :documents do |_map|
+ permission :manage_documents, {
+ documents: [:new, :create, :edit, :update, :destroy, :add_attachment]
+ }, require: :loggedin
+ permission :view_documents, documents: [:index, :show, :download]
+ end
+
+ Redmine::Notifiable.all << Redmine::Notifiable.new('document_added')
+
+ Redmine::Activity.map do |activity|
+ activity.register :documents, class_name: 'Activity::DocumentActivityProvider', default: false
+ end
+
+ Redmine::Search.register :documents
+ end
+
+ patches [:CustomFieldsHelper, :Project]
+
+ add_api_path :document do |id|
+ "#{root}/documents/#{id}"
+ end
+
+ add_api_path :attachments_by_document do |id|
+ "#{document(id)}/attachments"
+ end
+
+ add_api_endpoint 'API::V3::Root' do
+ mount ::API::V3::Documents::DocumentsAPI
+ end
+
+ assets %w(documents/documents.css)
+
+ # Add documents to allowed search params
+ additional_permitted_attributes search: %i(documents)
+
+ initializer "documents.register_hooks" do
+ require 'open_project/documents/hooks'
+ end
+
+ config.to_prepare do
+ require_dependency 'document'
+ require_dependency 'document_category'
+ require_dependency 'document_category_custom_field'
+
+ # Have to apply this one by hand and not via op_engine patches method
+ # becauses the op_engine method does not allow for patching something
+ # in the lib/open_project directory. Bummer.
+ require_relative 'patches/text_formatting_patch'
+ require_dependency 'open_project/documents/patches/text_formatting_patch'
+ ::OpenProject::Documents::Patches::ColonSeparatorPatch.mixin!
+ ::OpenProject::Documents::Patches::HashSeparatorPatch.mixin!
+
+ require_dependency 'open_project/documents/patches/textile_converter_patch'
+ end
+ end
+end
diff --git a/modules/documents/lib/open_project/documents/hooks.rb b/modules/documents/lib/open_project/documents/hooks.rb
new file mode 100644
index 0000000000..e38c642cf3
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/hooks.rb
@@ -0,0 +1,37 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject::Documents
+ class Hooks < Redmine::Hook::ViewListener
+ render_on :activity_index_head,
+ partial: 'hooks/documents/activity_index_head'
+ end
+end
diff --git a/modules/documents/lib/open_project/documents/patches.rb b/modules/documents/lib/open_project/documents/patches.rb
new file mode 100644
index 0000000000..c4bff1a671
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/patches.rb
@@ -0,0 +1,35 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject::Documents
+ module Patches
+ end
+end
diff --git a/modules/documents/lib/open_project/documents/patches/custom_fields_helper_patch.rb b/modules/documents/lib/open_project/documents/patches/custom_fields_helper_patch.rb
new file mode 100644
index 0000000000..af4d50c930
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/patches/custom_fields_helper_patch.rb
@@ -0,0 +1,52 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject::Documents::Patches
+ module CustomFieldsHelperPatch
+ def self.included(base)
+ base.prepend InstanceMethods
+ end
+
+ module InstanceMethods
+ def custom_fields_tabs
+ super << {
+ name: 'DocumentCategoryCustomField',
+ partial: 'custom_fields/tab',
+ label: DocumentCategory::OptionName
+ }
+ end
+ end
+ end
+end
+
+unless CustomFieldsHelper.included_modules.include?(OpenProject::Documents::Patches::CustomFieldsHelperPatch)
+ CustomFieldsHelper.send(:include, OpenProject::Documents::Patches::CustomFieldsHelperPatch)
+end
diff --git a/modules/documents/lib/open_project/documents/patches/project_patch.rb b/modules/documents/lib/open_project/documents/patches/project_patch.rb
new file mode 100644
index 0000000000..934b1a3f47
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/patches/project_patch.rb
@@ -0,0 +1,43 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject::Documents::Patches
+ module ProjectPatch
+ def self.included(base)
+ base.class_eval do
+
+ has_many :documents, dependent: :destroy
+ end
+ end
+ end
+end
+
+Project.send(:include, OpenProject::Documents::Patches::ProjectPatch)
diff --git a/modules/documents/lib/open_project/documents/patches/text_formatting_patch.rb b/modules/documents/lib/open_project/documents/patches/text_formatting_patch.rb
new file mode 100644
index 0000000000..184947ef46
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/patches/text_formatting_patch.rb
@@ -0,0 +1,87 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject::Documents::Patches
+ module HashSeparatorPatch
+ def self.mixin!
+ base = ::OpenProject::TextFormatting::Matchers::LinkHandlers::HashSeparator
+ base.prepend InstanceMethods
+ base.singleton_class.prepend ClassMethods
+ end
+
+ module InstanceMethods
+ def render_document
+ if document = Document.visible.find_by_id(oid)
+ link_to document.title,
+ { only_path: context[:only_path],
+ controller: '/documents',
+ action: 'show',
+ id: document },
+ class: 'document'
+ end
+ end
+ end
+
+ module ClassMethods
+ def allowed_prefixes
+ super + %w[document]
+ end
+ end
+ end
+
+ module ColonSeparatorPatch
+ def self.mixin!
+ base = ::OpenProject::TextFormatting::Matchers::LinkHandlers::ColonSeparator
+ base.prepend InstanceMethods
+ base.singleton_class.prepend ClassMethods
+ end
+
+ module InstanceMethods
+ def render_document
+ name = identifier.gsub(%r{^"(.*)"$}, "\\1")
+ if document = project.documents.visible.find_by_title(name)
+ link_to document.title,
+ { only_path: context[:only_path],
+ controller: '/documents',
+ action: 'show',
+ id: document },
+ class: 'document'
+ end
+ end
+ end
+
+ module ClassMethods
+ def allowed_prefixes
+ super + %w[document]
+ end
+ end
+ end
+end
diff --git a/modules/documents/lib/open_project/documents/patches/textile_converter_patch.rb b/modules/documents/lib/open_project/documents/patches/textile_converter_patch.rb
new file mode 100644
index 0000000000..25dce3d9cb
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/patches/textile_converter_patch.rb
@@ -0,0 +1,42 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#+
+
+module OpenProject::Documents::Patches
+ module TextileConverterPatch
+ def models_to_convert
+ super.merge(::Document => [:description])
+ end
+ end
+end
+
+::OpenProject::TextFormatting::Formats::Markdown::TextileConverter.prepend(
+ ::OpenProject::Documents::Patches::TextileConverterPatch
+)
diff --git a/modules/documents/lib/open_project/documents/version.rb b/modules/documents/lib/open_project/documents/version.rb
new file mode 100644
index 0000000000..ea135af577
--- /dev/null
+++ b/modules/documents/lib/open_project/documents/version.rb
@@ -0,0 +1,36 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+module OpenProject
+ module Documents
+ VERSION = "8.2.0"
+ end
+end
diff --git a/modules/documents/lib/openproject-documents.rb b/modules/documents/lib/openproject-documents.rb
new file mode 100644
index 0000000000..4472b8ebc9
--- /dev/null
+++ b/modules/documents/lib/openproject-documents.rb
@@ -0,0 +1,32 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'open_project/documents'
diff --git a/modules/documents/openproject-documents.gemspec b/modules/documents/openproject-documents.gemspec
new file mode 100644
index 0000000000..691cc77086
--- /dev/null
+++ b/modules/documents/openproject-documents.gemspec
@@ -0,0 +1,18 @@
+# encoding: UTF-8
+$:.push File.expand_path("../lib", __FILE__)
+
+require 'open_project/documents/version'
+# Describe your gem and declare its dependencies:
+Gem::Specification.new do |s|
+ s.name = "openproject-documents"
+ s.version = OpenProject::Documents::VERSION
+ s.authors = "OpenProject GmbH"
+ s.email = "info@openproject.com"
+ s.homepage = "https://community.openproject.org/projects/documents"
+ s.summary = "OpenProject Documents"
+ s.description = "An OpenProject plugin to allow creation of documents in projects"
+ s.license = "GPLv3"
+
+ s.files = Dir["{app,config,db,lib,doc}/**/*", "README.md"]
+ s.test_files = Dir["spec/**/*"]
+end
diff --git a/modules/documents/spec/api/v3/documents/document_representer_rendering_spec.rb b/modules/documents/spec/api/v3/documents/document_representer_rendering_spec.rb
new file mode 100644
index 0000000000..2683d9b7cd
--- /dev/null
+++ b/modules/documents/spec/api/v3/documents/document_representer_rendering_spec.rb
@@ -0,0 +1,108 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'spec_helper'
+
+describe ::API::V3::Documents::DocumentRepresenter, 'rendering' do
+ include ::API::V3::Utilities::PathHelper
+
+ let(:document) do
+ FactoryBot.build_stubbed(:document) do |wp|
+ allow(wp)
+ .to receive(:project)
+ .and_return(project)
+ end
+ end
+ let(:project) { FactoryBot.build_stubbed(:project) }
+ let(:user) { FactoryBot.build_stubbed(:user) }
+ let(:representer) do
+ described_class.create(document, current_user: user, embed_links: true)
+ end
+ let(:permissions) { all_permissions }
+ let(:all_permissions) { %i(manage_documents) }
+
+ subject { representer.to_json }
+
+ before do
+ allow(user)
+ .to receive(:allowed_to?) do |permission, project|
+ permissions.include?(permission)
+ end
+ end
+
+ describe '_links' do
+ it_behaves_like 'has a titled link' do
+ let(:link) { 'self' }
+ let(:href) { api_v3_paths.document document.id }
+ let(:title) { document.title }
+ end
+
+ it_behaves_like 'has an untitled link' do
+ let(:link) { :attachments }
+ let(:href) { api_v3_paths.attachments_by_document document.id }
+ end
+
+ it_behaves_like 'has a titled link' do
+ let(:link) { :project }
+ let(:title) { project.name }
+ let(:href) { api_v3_paths.project project.id }
+ end
+
+ it_behaves_like 'has an untitled action link' do
+ let(:link) { :addAttachment }
+ let(:href) { api_v3_paths.attachments_by_document document.id }
+ let(:method) { :post }
+ let(:permission) { :manage_documents }
+ end
+ end
+
+ describe 'properties' do
+ it_behaves_like 'property', :_type do
+ let(:value) { 'Document' }
+ end
+
+ it_behaves_like 'property', :id do
+ let(:value) { document.id }
+ end
+
+ it_behaves_like 'property', :title do
+ let(:value) { document.title }
+ end
+ end
+
+ describe '_embedded' do
+ it 'has project embedded' do
+ expect(subject)
+ .to be_json_eql(project.name.to_json)
+ .at_path('_embedded/project/name')
+ end
+ end
+end
diff --git a/modules/documents/spec/application_helper_spec.rb b/modules/documents/spec/application_helper_spec.rb
new file mode 100644
index 0000000000..76f06afe97
--- /dev/null
+++ b/modules/documents/spec/application_helper_spec.rb
@@ -0,0 +1,128 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'spec_helper'
+
+describe ApplicationHelper do
+ include ApplicationHelper
+ include ActionView::Helpers
+ include ActionDispatch::Routing
+ include Rails.application.routes.url_helpers
+
+
+ describe ".format_text" do
+ let(:project) { FactoryBot.create :valid_project }
+ let(:identifier) { project.identifier }
+ let(:role) {
+ FactoryBot.create(:role, permissions: [
+ :view_work_packages, :edit_work_packages, :view_documents, :browse_repository, :view_changesets, :view_wiki_pages
+ ])
+ }
+ let(:project_member) {
+ FactoryBot.create :user, member_in_project: project,
+ member_through_role: role
+ }
+ let(:document) {
+ FactoryBot.create :document,
+ title: 'Test document',
+ project: project
+ }
+
+ before do
+ @project = project
+ allow(User).to receive(:current).and_return project_member
+ end
+
+ after do
+ allow(User).to receive(:current).and_call_original
+ end
+
+ context "Simple Document links" do
+ let(:document_link) {
+ link_to('Test document',
+ { controller: 'documents', action: 'show', id: document.id },
+ class: 'document')
+ }
+
+ context "Plain link" do
+ subject { format_text("document##{document.id}") }
+
+ it { is_expected.to eq("
#{document_link}
") }
+ end
+
+ context "Link with document name" do
+ subject { format_text("document##{document.id}") }
+
+ it { is_expected.to eq("
#{document_link}
") }
+ end
+
+ context "Escaping plain link" do
+ subject { format_text("!document##{document.id}") }
+
+ it { is_expected.to eq("
document##{document.id}
") }
+ end
+
+ context "Escaping link with document name" do
+ subject { format_text('!document:"Test document"') }
+
+ it { is_expected.to eq('
document:"Test document"
') }
+ end
+ end
+
+ context 'Cross-Project Document Links' do
+ let(:the_other_project) { FactoryBot.create :valid_project }
+
+ context "By name without project" do
+ subject { format_text("document:\"#{document.title}\"", project: the_other_project) }
+
+ it { is_expected.to eq('
document:"Test document"
') }
+ end
+
+ context "By id and given project" do
+ subject { format_text("#{identifier}:document##{document.id}", project: the_other_project) }
+
+ it { is_expected.to eq("
") }
+ end
+
+ context "By name and given project" do
+ subject { format_text("#{identifier}:document:\"#{document.title}\"", project: the_other_project) }
+
+ it { is_expected.to eq("
") }
+ end
+
+ context "Invalid link" do
+ subject { format_text("invalid:document:\"Test document\"", project: the_other_project) }
+
+ it { is_expected.to eq('
invalid:document:"Test document"
') }
+ end
+ end
+ end
+end
diff --git a/modules/documents/spec/assets/attachments/testfile.txt b/modules/documents/spec/assets/attachments/testfile.txt
new file mode 100644
index 0000000000..84f601ee68
--- /dev/null
+++ b/modules/documents/spec/assets/attachments/testfile.txt
@@ -0,0 +1,2 @@
+this is a text file for upload tests
+with multiple lines
diff --git a/modules/documents/spec/controllers/documents_controller_spec.rb b/modules/documents/spec/controllers/documents_controller_spec.rb
new file mode 100644
index 0000000000..3758877617
--- /dev/null
+++ b/modules/documents/spec/controllers/documents_controller_spec.rb
@@ -0,0 +1,226 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe DocumentsController do
+
+ render_views
+
+ let(:admin) { FactoryBot.create(:admin)}
+ let(:project) { FactoryBot.create(:project, name: "Test Project")}
+ let(:user) { FactoryBot.create(:user)}
+ let(:role) { FactoryBot.create(:role, permissions: [:view_documents]) }
+
+ let(:default_category){
+ FactoryBot.create(:document_category, project: project, name: "Default Category")
+ }
+
+ let(:document) {
+ FactoryBot.create(:document, title: "Sample Document", project: project, category: default_category)
+ }
+
+ before do
+ allow(User).to receive(:current).and_return admin
+ end
+
+ describe "index" do
+ let(:long_description) {
+ <<-LOREM.strip_heredoc
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.\
+ Ut egestas, mi vehicula varius varius, ipsum massa fermentum orci,\
+ eget tristique ante sem vel mi. Nulla facilisi.\
+ Donec enim libero, luctus ac sagittis sit amet, vehicula sagittis magna.\
+ Duis ultrices molestie ante, eget scelerisque sem iaculis vitae.\
+ Etiam fermentum mauris vitae metus pharetra condimentum fermentum est pretium.\
+ Proin sollicitudin elementum quam quis pharetra.\
+ Aenean facilisis nunc quis elit volutpat mollis.\
+ Aenean eleifend varius euismod. Ut dolor est, congue eget dapibus eget, elementum eu odio.\
+ Integer et lectus neque, nec scelerisque nisi. EndOfLineHere
+
+ Praesent a nunc lorem, ac porttitor eros.
+ LOREM
+ }
+
+ before do
+ document.update_attributes(description: long_description)
+ get :index, params: { project_id: project.identifier }
+ end
+
+ it "should render the index-template successfully" do
+ expect(response).to be_success
+ expect(response).to render_template("index")
+ end
+
+ it "should group documents by category, if no other sorting is given " do
+ expect(assigns(:grouped)).not_to be_nil
+ expect(assigns(:grouped).keys.map(&:name)).to eql [default_category.name]
+ end
+
+ it "should render documents with long descriptions properly" do
+
+ expect(response.body).to have_css('.wiki p')
+ expect(response.body).to have_css('.wiki p', text: (document.description.split("\n").first + '...'))
+ expect(response.body).to have_css('.wiki p', text: /EndOfLineHere.../)
+ end
+
+ end
+
+ describe 'new' do
+ before do
+ get :new, params: { project_id: project.id }
+ end
+
+ it 'show the new document form' do
+ expect(response).to render_template(partial: 'documents/_form')
+ end
+ end
+
+ describe "create" do
+
+ let(:document_attributes) {
+ FactoryBot.attributes_for(:document, title: "New Document",
+ project_id: project.id,
+ category_id: default_category.id)
+ }
+
+
+ before do
+ ActionMailer::Base.deliveries.clear
+ allow(Setting).to receive(:notified_events).and_return(Setting.notified_events.dup << 'document_added')
+ end
+
+ it "should create a new document with valid arguments" do
+ expect do
+ post :create, params: { project_id: project.identifier,
+ document: FactoryBot.attributes_for(:document, title: "New Document",
+ project_id: project.id,
+ category_id: default_category.id
+ ) }
+
+ end.to change{Document.count}.by 1
+ end
+
+ it "should create a new document with valid arguments" do
+ expect do
+ post :create,
+ params: {
+ project_id: project.identifier,
+ document: document_attributes
+ }
+ end.to change{Document.count}.by 1
+ end
+
+ describe "with attachments" do
+
+ before do
+ notify_project = project
+ FactoryBot.create(:member, project: notify_project, user: user, roles: [role])
+
+ post :create,
+ params: {
+ project_id: notify_project.identifier,
+ document: FactoryBot.attributes_for(:document, title: "New Document",
+ project_id: notify_project.id,
+ category_id: default_category.id
+ ),
+ attachments: { '1' => { description: "sample file", file: file_attachment } }
+ }
+ end
+
+ it "should add an attachment" do
+ document = Document.last
+
+ expect(document.attachments.count).to eql 1
+ attachment = document.attachments.first
+ expect(attachment.description).to eql "sample file"
+ expect(attachment.filename).to eql "testfile.txt"
+ end
+
+ it "should redirect to the documents-page" do
+ expect(response).to redirect_to project_documents_path(project.identifier)
+ end
+
+ it "should send out mails with notifications to members of the project with :view_documents-permission" do
+ expect(ActionMailer::Base.deliveries.size).to eql 1
+ end
+ end
+ end
+
+ describe 'show' do
+ before do
+ document
+ get :show, params: { id: document.id }
+ end
+
+ it "should delete the document and redirect back to documents-page of the project" do
+ expect(response).to be_success
+ expect(response).to render_template('show')
+ end
+ end
+
+ describe '#add_attachment' do
+ before do
+ document
+ post :add_attachment,
+ params: {
+ id: document.id,
+ attachments: { '1' => { description: "sample file", file: file_attachment } }
+ }
+ end
+
+ it "should delete the document and redirect back to documents-page of the project" do
+ expect(response).to be_redirect
+ document.reload
+ expect(document.attachments.length).to eq(1)
+ end
+ end
+
+ describe "destroy" do
+ before do
+ document
+ end
+
+ it "should delete the document and redirect back to documents-page of the project" do
+ expect{
+ delete :destroy, params: { id: document.id }
+ }.to change{Document.count}.by -1
+
+ expect(response).to redirect_to "/projects/#{project.identifier}/documents"
+ expect{Document.find(document.id)}.to raise_error ActiveRecord::RecordNotFound
+ end
+ end
+
+ def file_attachment
+ test_document = "#{OpenProject::Documents::Engine.root}/spec/assets/attachments/testfile.txt"
+ Rack::Test::UploadedFile.new(test_document, "text/plain")
+ end
+end
diff --git a/modules/documents/spec/factories/document_category_factory.rb b/modules/documents/spec/factories/document_category_factory.rb
new file mode 100644
index 0000000000..d2b4271ad9
--- /dev/null
+++ b/modules/documents/spec/factories/document_category_factory.rb
@@ -0,0 +1,37 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+FactoryBot.define do
+ factory :document_category do
+ project
+ sequence(:name) { |n| "I am Category No. #{n}" }
+ end
+end
diff --git a/modules/documents/spec/factories/document_factory.rb b/modules/documents/spec/factories/document_factory.rb
new file mode 100644
index 0000000000..da5364c98b
--- /dev/null
+++ b/modules/documents/spec/factories/document_factory.rb
@@ -0,0 +1,39 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+FactoryBot.define do
+ factory :document do
+ project
+ category factory: :document_category
+ sequence(:description) { |n| "I am a document's description No. #{n}" }
+ sequence(:title) { |n| "I am the document No. #{n}" }
+ end
+end
diff --git a/modules/documents/spec/features/attachment_upload_spec.rb b/modules/documents/spec/features/attachment_upload_spec.rb
new file mode 100644
index 0000000000..3532088a55
--- /dev/null
+++ b/modules/documents/spec/features/attachment_upload_spec.rb
@@ -0,0 +1,90 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'spec_helper'
+require 'features/page_objects/notification'
+
+describe 'Upload attachment to documents', js: true do
+ let!(:user) do
+ FactoryBot.create :user,
+ member_in_project: project,
+ member_with_permissions: %i[view_documents
+ manage_documents]
+ end
+ let!(:category) do
+ FactoryBot.create(:document_category)
+ end
+ let(:project) { FactoryBot.create(:project) }
+ let(:attachments) { ::Components::Attachments.new }
+ let(:image_fixture) { Rails.root.join('spec/fixtures/files/image.png') }
+ let(:editor) { ::Components::WysiwygEditor.new }
+
+ before do
+ login_as(user)
+ end
+
+ it 'can upload an image' do
+ visit project_documents_path(project)
+
+ within '.toolbar-items' do
+ click_on 'Document'
+ end
+
+ select(category.name, from: 'Category')
+ fill_in "Title", with: 'New documentation'
+
+ # adding an image
+ editor.drag_attachment image_fixture, 'Image uploaded on creation'
+
+ expect(page).to have_selector('attachment-list-item', text: 'image.png')
+
+ click_on 'Create'
+
+ expect(page).to have_selector('#content img', count: 1)
+ expect(page).to have_content('Image uploaded on creation')
+
+ click_on 'New documentation'
+
+ within '.toolbar-items' do
+ click_on 'Edit'
+ end
+
+ editor.drag_attachment image_fixture, 'Image uploaded the second time'
+ expect(page).to have_selector('attachment-list-item', text: 'image.png', count: 2)
+
+ click_on 'Save'
+
+ expect(page).to have_selector('#content img', count: 2)
+ expect(page).to have_content('Image uploaded on creation')
+ expect(page).to have_content('Image uploaded the second time')
+ expect(page).to have_selector('attachment-list-item', text: 'image.png', count: 2)
+ end
+end
diff --git a/modules/documents/spec/features/documents_widget_spec.rb b/modules/documents/spec/features/documents_widget_spec.rb
new file mode 100644
index 0000000000..c8180db92a
--- /dev/null
+++ b/modules/documents/spec/features/documents_widget_spec.rb
@@ -0,0 +1,72 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require_relative '../spec_helper'
+
+describe 'Documents widget', type: :feature, js: true do
+ let(:project) { FactoryBot.create(:project) }
+ let(:user) do
+ FactoryBot.create(:user,
+ member_in_project: project,
+ member_through_role: role)
+ end
+ let(:role) { FactoryBot.create(:role, permissions: [:edit_project]) }
+
+ before do
+ allow(User)
+ .to receive(:current)
+ .and_return(user)
+ end
+
+ if Redmine::Plugin.registered_plugins[:openproject_my_project_page]
+ it 'has a "Document" widget on the my project page' do
+ visit my_projects_overview_path project
+
+ select 'Documents', from: 'block-select'
+
+ within '#list-hidden' do
+ expect(page).to have_content('Documents')
+ end
+
+ expect(page.find('#block-select option', text: 'Documents')['disabled']).to eql 'true'
+ end
+ end
+
+ it 'has a "Document" widget on the my page' do
+ visit my_page_layout_path
+
+ select 'Documents', from: 'block-options'
+ click_button 'Add'
+
+ expect(page).to have_selector('.widget-box--header-title', text: 'Documents', wait: 10)
+ expect(page.find('#block-options option', text: 'Documents')['disabled']).to eql 'true'
+ end
+end
diff --git a/modules/documents/spec/lib/acts_as_journalized/journaled_spec.rb b/modules/documents/spec/lib/acts_as_journalized/journaled_spec.rb
new file mode 100644
index 0000000000..912eae41da
--- /dev/null
+++ b/modules/documents/spec/lib/acts_as_journalized/journaled_spec.rb
@@ -0,0 +1,50 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'spec_helper'
+
+describe "Journalized Objects" do
+ before(:each) do
+ @type ||= FactoryBot.create(:type_feature)
+ @project ||= FactoryBot.create(:project_with_types)
+ @current = FactoryBot.create(:user, login: "user1", mail: "user1@users.com")
+ allow(User).to receive(:current).and_return @current
+ end
+
+ it 'should work with documents' do
+ @document ||= FactoryBot.create(:document)
+
+ initial_journal = @document.journals.first
+ recreated_journal = @document.recreate_initial_journal!
+
+ expect(initial_journal).to be_identical(recreated_journal)
+ end
+end
diff --git a/modules/documents/spec/lib/redmine/access_control_spec.rb b/modules/documents/spec/lib/redmine/access_control_spec.rb
new file mode 100644
index 0000000000..e2c2939a37
--- /dev/null
+++ b/modules/documents/spec/lib/redmine/access_control_spec.rb
@@ -0,0 +1,51 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Redmine::AccessControl do
+
+ describe 'manage documents permission' do
+ it 'should be part of the documents project module' do
+ permission = Redmine::AccessControl.permission(:manage_documents)
+
+ expect(permission.project_module).to eql(:documents)
+ end
+ end
+
+ describe 'view documents permission' do
+ it 'should be part of the documents project module' do
+ permission = Redmine::AccessControl.permission(:view_documents)
+
+ expect(permission.project_module).to eql(:documents)
+ end
+ end
+
+end
diff --git a/modules/documents/spec/mailers/documents_mailer_spec.rb b/modules/documents/spec/mailers/documents_mailer_spec.rb
new file mode 100644
index 0000000000..9210965a13
--- /dev/null
+++ b/modules/documents/spec/mailers/documents_mailer_spec.rb
@@ -0,0 +1,64 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe DocumentsMailer do
+
+ let(:user) {
+ FactoryBot.create(:user, firstname: 'Test', lastname: "User", mail: 'test@test.com')
+ }
+ let(:project) { FactoryBot.create(:project, name: "TestProject") }
+ let(:document) {
+ FactoryBot.create(:document, project: project, description: "Test Description", title: "Test Title" )
+ }
+ let(:mail) { DocumentsMailer.document_added(user, document) }
+
+ describe "document added-mail" do
+ it "renders the subject" do
+ expect(mail.subject).to eql '[TestProject] New document: Test Title'
+ end
+
+ it "should render the receivers mail" do
+ expect(mail.to.count).to eql 1
+ expect(mail.to.first).to eql user.mail
+ end
+
+ it "should render the document-info into the body" do
+ expect(mail.body.encoded).to match(document.description)
+ expect(mail.body.encoded).to match(document.title)
+ end
+
+ end
+
+
+
+
+end
diff --git a/modules/documents/spec/models/document_category_spec.rb b/modules/documents/spec/models/document_category_spec.rb
new file mode 100644
index 0000000000..f2c2627161
--- /dev/null
+++ b/modules/documents/spec/models/document_category_spec.rb
@@ -0,0 +1,68 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+require File.dirname(__FILE__) + '/../spec_helper'
+
+
+describe DocumentCategory do
+
+ let(:project) {FactoryBot.create(:project)}
+
+ it "should be an enumeration" do
+ expect(DocumentCategory.ancestors).to include Enumeration
+ end
+
+ it "should order documents by the category they are created with" do
+ uncategorized = FactoryBot.create :document_category, name: "Uncategorized", project: project
+ user_documentation = FactoryBot.create :document_category, name: "User documentation"
+
+ FactoryBot.create_list :document, 2, category: uncategorized, project: project
+
+ expect(DocumentCategory.find_by_name(uncategorized.name).objects_count).to eql 2
+ expect(DocumentCategory.find_by_name(user_documentation.name).objects_count).to eql 0
+
+ end
+
+ it "should file the categorizations under the option name :enumeration_doc_categories" do
+ expect(DocumentCategory.new.option_name).to eql :enumeration_doc_categories
+ end
+
+ it "should only allow one category to be the default-category" do
+ old_default = FactoryBot.create :document_category, name: "old default", project: project, is_default: true
+
+ expect{
+ FactoryBot.create :document_category, name: "new default", project: project, is_default: true
+ old_default.reload
+ }.to change{old_default.is_default?}.from(true).to(false)
+
+
+ end
+
+end
diff --git a/modules/documents/spec/models/document_spec.rb b/modules/documents/spec/models/document_spec.rb
new file mode 100644
index 0000000000..cd3d971de8
--- /dev/null
+++ b/modules/documents/spec/models/document_spec.rb
@@ -0,0 +1,128 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+require File.dirname(__FILE__) + '/../spec_helper'
+
+
+describe Document do
+
+ let(:documentation_category) { FactoryBot.create :document_category, name: 'User documentation'}
+ let(:project) { FactoryBot.create :project}
+ let(:user) { FactoryBot.create(:user)}
+ let(:admin) { FactoryBot.create(:admin)}
+
+ let(:mail) do
+ mock = Object.new
+ allow(mock).to receive(:deliver_now)
+ mock
+ end
+
+ context "validation" do
+
+ it { is_expected.to validate_presence_of :project}
+ it { is_expected.to validate_presence_of :title}
+ it { is_expected.to validate_presence_of :category}
+
+ end
+
+ describe "create with a valid document" do
+ let(:valid_document) {Document.new(title: "Test", project: project, category: documentation_category)}
+
+ it "should add a document" do
+ expect{
+ valid_document.save
+ }.to change{Document.count}.by 1
+ end
+
+ it "should send out email-notifications" do
+ allow(valid_document).to receive(:recipients).and_return([user])
+ Setting.notified_events = Setting.notified_events << 'document_added'
+
+ expect{
+ valid_document.save
+ }.to change{ActionMailer::Base.deliveries.size}.by 1
+ end
+
+ it "should send notifications to the recipients of the project" do
+ allow(project).to receive(:notified_users).and_return([admin])
+ document = FactoryBot.create(:document, project: project)
+
+ expect(document.recipients).not_to be_empty
+ expect(document.recipients.count).to eql 1
+ expect(document.recipients.map(&:mail)).to include admin.mail
+ end
+
+ it "should set a default-category, if none is given" do
+ default_category = FactoryBot.create :document_category, name: 'Technical documentation', is_default: true
+ document = Document.new(project: project, title: "New Document")
+ expect(document.category).to eql default_category
+ expect{
+ document.save
+ }.to change{Document.count}.by 1
+ end
+
+ it "with attachments should change the updated_on-date on the document to the attachment's date" do
+ 3.times do
+ FactoryBot.create(:attachment, container: valid_document)
+ end
+
+ valid_document.reload
+ expect(valid_document.attachments.size).to eql 3
+ expect(valid_document.attachments.map(&:created_at).max).to eql valid_document.updated_on
+ end
+
+ it "without attachments, the updated-on-date is taken from the document's date" do
+ document = FactoryBot.create(:document, project: project)
+ expect(document.attachments).to be_empty
+ expect(document.created_on).to eql document.updated_on
+ end
+ end
+
+ describe "acts as event" do
+ let(:now) { Time.zone.now }
+ let(:document) {
+ FactoryBot.build(:document,
+ created_on: now)
+ }
+
+ it { expect(document.event_datetime.to_i).to eq(now.to_i) }
+ end
+
+ it "calls the DocumentsMailer, when a new document has been added" do
+ document = FactoryBot.build(:document)
+ # make sure, that we have actually someone to notify
+ allow(document).to receive(:recipients).and_return([user])
+ # ... and notifies are actually sent out
+ Setting.notified_events = Setting.notified_events << 'document_added'
+ expect(DocumentsMailer).to receive(:document_added).and_return(mail)
+
+ document.save
+ end
+end
diff --git a/modules/documents/spec/requests/api/v3/attachments/attachments_by_documents_resource_spec.rb b/modules/documents/spec/requests/api/v3/attachments/attachments_by_documents_resource_spec.rb
new file mode 100644
index 0000000000..50e2b69b7c
--- /dev/null
+++ b/modules/documents/spec/requests/api/v3/attachments/attachments_by_documents_resource_spec.rb
@@ -0,0 +1,142 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'spec_helper'
+require 'rack/test'
+
+describe 'API v3 Attachments by document resource', type: :request do
+ include Rack::Test::Methods
+ include API::V3::Utilities::PathHelper
+ include FileHelpers
+
+ let(:current_user) do
+ FactoryBot.create(:user,
+ member_in_project: project,
+ member_through_role: role)
+ end
+ let(:project) { FactoryBot.create(:project) }
+ let(:role) { FactoryBot.create(:role, permissions: permissions) }
+ let(:permissions) { [:view_documents] }
+ let(:document) { FactoryBot.create(:document, project: project) }
+
+ subject(:response) { last_response }
+
+ before do
+ allow(User).to receive(:current).and_return current_user
+ end
+
+ describe '#get' do
+ let(:get_path) { api_v3_paths.attachments_by_document document.id }
+
+ before do
+ FactoryBot.create_list(:attachment, 2, container: document)
+ get get_path
+ end
+
+ it 'should respond with 200' do
+ expect(subject.status).to eq(200)
+ end
+
+ it_behaves_like 'API V3 collection response', 2, 2, 'Attachment'
+ end
+
+ describe '#post' do
+ let(:permissions) { %i[view_documents manage_documents] }
+
+ let(:request_path) { api_v3_paths.attachments_by_document document.id }
+ let(:request_parts) { { metadata: metadata, file: file } }
+ let(:metadata) { { fileName: 'cat.png' }.to_json }
+ let(:file) { mock_uploaded_file(name: 'original-filename.txt') }
+ let(:max_file_size) { 1 } # given in kiB
+
+ before do
+ allow(Setting).to receive(:attachment_max_size).and_return max_file_size.to_s
+ post request_path, request_parts
+ end
+
+ it 'should respond with HTTP Created' do
+ expect(subject.status).to eq(201)
+ end
+
+ it 'should return the new attachment' do
+ expect(subject.body).to be_json_eql('Attachment'.to_json).at_path('_type')
+ end
+
+ it 'ignores the original file name' do
+ expect(subject.body).to be_json_eql('cat.png'.to_json).at_path('fileName')
+ end
+
+ context 'metadata section is missing' do
+ let(:request_parts) { { file: file } }
+
+ it_behaves_like 'invalid request body', I18n.t('api_v3.errors.multipart_body_error')
+ end
+
+ context 'file section is missing' do
+ # rack-test won't send a multipart request without a file being present
+ # however as long as we depend on correctly named sections this test should do just fine
+ let(:request_parts) { { metadata: metadata, wrongFileSection: file } }
+
+ it_behaves_like 'invalid request body', I18n.t('api_v3.errors.multipart_body_error')
+ end
+
+ context 'metadata section is no valid JSON' do
+ let(:metadata) { '"fileName": "cat.png"' }
+
+ it_behaves_like 'parse error'
+ end
+
+ context 'metadata is missing the fileName' do
+ let(:metadata) { Hash.new.to_json }
+
+ it_behaves_like 'constraint violation' do
+ let(:message) { "fileName #{I18n.t('activerecord.errors.messages.blank')}" }
+ end
+ end
+
+ context 'file is too large' do
+ let(:file) { mock_uploaded_file(content: 'a' * 2.kilobytes) }
+ let(:expanded_localization) do
+ I18n.t('activerecord.errors.messages.file_too_large', count: max_file_size.kilobytes)
+ end
+
+ it_behaves_like 'constraint violation' do
+ let(:message) { "File #{expanded_localization}" }
+ end
+ end
+
+ context 'only allowed to view documents' do
+ let(:permissions) { [:view_documents] }
+
+ it_behaves_like 'unauthorized access'
+ end
+ end
+end
\ No newline at end of file
diff --git a/modules/documents/spec/requests/api/v3/documents/documents_resource_spec.rb b/modules/documents/spec/requests/api/v3/documents/documents_resource_spec.rb
new file mode 100644
index 0000000000..2b134c508c
--- /dev/null
+++ b/modules/documents/spec/requests/api/v3/documents/documents_resource_spec.rb
@@ -0,0 +1,84 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'spec_helper'
+require 'rack/test'
+
+describe 'API v3 documents resource', type: :request do
+ include Rack::Test::Methods
+ include API::V3::Utilities::PathHelper
+
+ let(:current_user) do
+ FactoryBot.create(:user, member_in_project: project, member_through_role: role)
+ end
+ let(:document) { FactoryBot.create(:document, project: project) }
+ let(:project) { FactoryBot.create(:project) }
+ let(:role) { FactoryBot.create(:role, permissions: permissions) }
+ let(:permissions) { %i(view_documents) }
+
+ subject(:response) { last_response }
+
+ before do
+ login_as(current_user)
+ end
+
+ describe 'GET /api/v3/wiki_pages/:id' do
+ let(:path) { api_v3_paths.document(document.id) }
+
+ before do
+ get path
+ end
+
+ it 'returns 200 OK' do
+ expect(subject.status)
+ .to eql(200)
+ end
+
+ it 'returns the wiki page' do
+ expect(subject.body)
+ .to be_json_eql('Document'.to_json)
+ .at_path('_type')
+
+ expect(subject.body)
+ .to be_json_eql(document.id.to_json)
+ .at_path('id')
+ end
+
+ context 'when lacking permissions' do
+ let(:permissions) { [] }
+
+ it 'returns 404 NOT FOUND' do
+ expect(subject.status)
+ .to eql(404)
+ end
+ end
+ end
+end
diff --git a/modules/documents/spec/routing/documents_routing_spec.rb b/modules/documents/spec/routing/documents_routing_spec.rb
new file mode 100644
index 0000000000..3042923968
--- /dev/null
+++ b/modules/documents/spec/routing/documents_routing_spec.rb
@@ -0,0 +1,78 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+require 'spec_helper'
+
+describe DocumentsController do
+ describe "routing" do
+ it {
+ expect(get('/projects/567/documents')).to route_to(controller: 'documents',
+ action: 'index',
+ project_id: '567' )
+ }
+
+ it {
+ expect(get('/projects/567/documents/new')).to route_to(controller: 'documents',
+ action: 'new',
+ project_id: '567' )
+ }
+
+ it {
+ expect(get('/documents/22')).to route_to(controller: 'documents',
+ action: 'show',
+ id: '22')
+ }
+
+ it {
+ expect(get('/documents/22/edit')).to route_to(controller: 'documents',
+ action: 'edit',
+ id: '22')
+ }
+
+ it {
+ expect(post('/projects/567/documents')).to route_to(controller: 'documents',
+ action: 'create',
+ project_id: '567')
+ }
+
+ it {
+ expect(put('/documents/567')).to route_to(controller: 'documents',
+ action: 'update',
+ id: '567')
+ }
+
+ it {
+ expect(delete('/documents/567')).to route_to(controller: 'documents',
+ action: 'destroy',
+ id: '567')
+ }
+ end
+end
diff --git a/modules/documents/spec/spec_helper.rb b/modules/documents/spec/spec_helper.rb
new file mode 100644
index 0000000000..17f1e43851
--- /dev/null
+++ b/modules/documents/spec/spec_helper.rb
@@ -0,0 +1,33 @@
+#-- copyright
+# OpenProject Documents Plugin
+#
+# Former OpenProject Core functionality extracted into a plugin.
+#
+# Copyright (C) 2009-2014 the OpenProject Foundation (OPF)
+#
+# 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 doc/COPYRIGHT.rdoc for more details.
+#++
+
+# -- load spec_helper from OpenProject core
+require "spec_helper"