WIP project settings for storages

pull/10133/head
Wieland Lindenthal 3 years ago
parent b8f185eaf5
commit a3e0231c94
No known key found for this signature in database
GPG Key ID: 7ACCABE64832A0C6
  1. 3
      app/models/project.rb
  2. 9
      config/initializers/menus.rb
  3. 15
      db/migrate/20220121090847_create_projects_storages.rb
  4. 33
      modules/storages/app/cells/storages/projects_storages_row_cell.rb
  5. 43
      modules/storages/app/cells/storages/projects_storages_table_cell.rb
  6. 2
      modules/storages/app/cells/storages/storages_row_cell.rb
  7. 9
      modules/storages/app/cells/storages/storages_table_cell.rb
  8. 88
      modules/storages/app/controllers/storages/admin/projects_storages_controller.rb
  9. 2
      modules/storages/app/controllers/storages/admin/storages_controller.rb
  10. 45
      modules/storages/app/controllers/storages/projects/settings_controller.rb
  11. 38
      modules/storages/app/models/storages/project_storage.rb
  12. 2
      modules/storages/app/models/storages/storage.rb
  13. 2
      modules/storages/app/views/storages/admin/index.html.erb
  14. 15
      modules/storages/app/views/storages/project_settings/index.html.erb
  15. 18
      modules/storages/app/views/storages/project_settings/new.html.erb
  16. 6
      modules/storages/config/routes.rb
  17. 18
      modules/storages/lib/open_project/storages/engine.rb

@ -88,6 +88,9 @@ class Project < ApplicationRecord
has_one :status, class_name: 'Projects::Status', dependent: :destroy
has_many :budgets, dependent: :destroy
has_many :notification_settings, dependent: :destroy
has_many :projects_storages, dependent: :destroy, class_name: 'Storages::ProjectStorage'
has_many :storages, through: :projects_storages
acts_as_nested_set order_column: :name, dependent: :destroy

@ -407,12 +407,6 @@ Redmine::MenuManager.map :admin_menu do |menu|
if: Proc.new { User.current.admin? },
caption: :label_setting_plural,
parent: :admin_backlogs
menu.push :storages_settings,
{ controller: '/storages/admin/storages', action: :index },
if: Proc.new { User.current.admin? },
caption: :project_module_storages,
icon: 'icon2 icon-hosting'
end
Redmine::MenuManager.map :project_menu do |menu|
@ -481,8 +475,7 @@ Redmine::MenuManager.map :project_menu do |menu|
categories: :label_work_package_category_plural,
repository: :label_repository,
time_entry_activities: :enumeration_activities,
storage: :label_required_disk_storage,
storages: :'storages.storage'
storage: :label_required_disk_storage
}.each do |key, caption|
menu.push :"settings_#{key}",
{ controller: "/projects/settings/#{key}", action: 'show' },

@ -0,0 +1,15 @@
class CreateProjectsStorages < ActiveRecord::Migration[6.1]
def change
create_table :projects_storages do |t|
t.bigint :project_id, null: false, foreign_key: true
t.bigint :storage_id, null: false, foreign_key: true
t.bigint :creator_id, null: false, foreign_key: true
t.timestamps
t.index :project_id
t.index :storage_id
t.index %i[project_id storage_id], unique: true
end
end
end

@ -0,0 +1,33 @@
module Storages
class ProjectsStoragesRowCell < ::RowCell
include ::IconsHelper
include ::AvatarHelper
include ::Redmine::I18n
def name
model.storage.name
end
def provider_type
model.storage.provider_type
end
def creator
icon = avatar model.creator, size: :mini
icon + model.creator.name
end
def button_links
[delete_link]
end
def delete_link
link_to '',
project_settings_projects_storage_path(project_id: model.project, id: model),
class: 'icon icon-delete',
data: { confirm: I18n.t(:text_are_you_sure) },
title: I18n.t(:button_delete),
method: :delete
end
end
end

@ -0,0 +1,43 @@
module Storages
class ProjectsStoragesTableCell < ::TableCell
include ::IconsHelper
class << self
def row_class
::Storages::ProjectsStoragesRowCell
end
end
columns :name, :provider_type, :creator, :created_at
def initial_sort
%i[created_at asc]
end
def sortable?
false
end
def inline_create_link
link_to(new_project_settings_projects_storage_path,
class: 'wp-inline-create--add-link',
title: I18n.t('storages.label_new_storage')) do
op_icon('icon icon-add')
end
end
def empty_row_message
I18n.t 'storages.no_results'
end
def headers
[
['name', { caption: Storages::Storage.human_attribute_name(:name) }],
['provider_type', { caption: I18n.t('storages.provider_types.label') }],
['creator', { caption: I18n.t('storages.label_creator') }],
['created_at', { caption: Storages::ProjectStorage.human_attribute_name(:created_at) }]
]
end
end
end

@ -1,5 +1,5 @@
module Storages
class RowCell < ::RowCell
class StoragesRowCell < ::RowCell
include ::IconsHelper
include ::AvatarHelper
include ::Redmine::I18n

@ -1,6 +1,13 @@
module Storages
class TableCell < ::TableCell
class StoragesTableCell < ::TableCell
include ::IconsHelper
class << self
def row_class
::Storages::StoragesRowCell
end
end
columns :name, :provider_type, :creator, :created_at
def initial_sort

@ -0,0 +1,88 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
class Storages::Admin::ProjectsStoragesController < ApplicationController
layout 'admin'
before_action :find_optional_project
before_action :authorize
menu_item :settings_projects_storages
def index
@projects_storages = Storages::ProjectStorage.where(project: @project).includes(:storage)
render '/storages/project_settings/index'
end
def new
@project_storage = Storages::ProjectStorage.new(project: @project)
@available_storages = Storages::Storage.where.not(storage_id: @project.projects_storages.pluck(:storage_id))
render '/storages/project_settings/new'
end
def create
combined_params = permitted_project_storage_params
.to_h
.reverse_merge(creator_id: User.current.id, project_id: @project.id)
@project_storage = Storages::ProjectStorage.create combined_params
redirect_to project_settings_projects_storages_path
end
def destroy
@project_storage = Storages::ProjectStorage.find(params[:id])
@project_storage.destroy
redirect_to project_settings_projects_storages_path
end
def default_breadcrumb
# t(:project_module_storages)
end
def show_local_breadcrumb
true
end
current_menu_item :index do
:settings_projects_storages
end
private
def permitted_project_storage_params
params
.require(:storages_project_storage)
.permit('storage_id')
end
end

@ -31,7 +31,7 @@
class Storages::Admin::StoragesController < ApplicationController
layout 'admin'
before_action :require_admin
menu_item :storages_settings
menu_item :storages_admin_settings
def index
@storages = Storages::Storage.all

@ -0,0 +1,45 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
class Storages::Projects::SettingsController < Projects::SettingsController
menu_item :project_settings_storages
def index
# tbd
end
def create
# tbd
end
def delete
# tbd
end
end

@ -0,0 +1,38 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
class Storages::ProjectStorage < ApplicationRecord
self.table_name = 'projects_storages'
belongs_to :project, class_name: 'Project'
belongs_to :storage, class_name: 'Storages::Storage'
belongs_to :creator, class_name: 'User'
validates :project, uniqueness: { scope: :storage }
end

@ -31,6 +31,8 @@
class Storages::Storage < ApplicationRecord
has_many :file_links, class_name: 'Storages::FileLink'
belongs_to :creator, class_name: 'User'
has_many :projects_storages, dependent: :destroy, class_name: 'Storages::ProjectStorage'
has_many :projects, through: :projects_storages
has_secure_token :identifier
PROVIDER_TYPES = %w[nextcloud].freeze

@ -12,4 +12,4 @@
</li>
<% end %>
<%= rails_cell ::Storages::TableCell, @storages %>
<%= rails_cell ::Storages::StoragesTableCell, @storages %>

@ -0,0 +1,15 @@
<% html_title t(:label_administration), t("project_module_storages") %>
<%= toolbar title: t("project_module_storages") do %>
<li class="toolbar-item">
<%= link_to new_project_settings_projects_storage_path,
{ class: 'button -alt-highlight',
aria: { label: t(:'storages.label_new_storage') },
title: t(:'ifc_models.label_new_storage') } do %>
<%= op_icon('button--icon icon-add') %>
<span class="button--text"><%= ::Storages::Storage.model_name.human %></span>
<% end %>
</li>
<% end %>
<%= rails_cell ::Storages::ProjectsStoragesTableCell, @projects_storages %>

@ -0,0 +1,18 @@
<% html_title t(:label_administration), t("project_module_storages") %>
<% local_assigns[:additional_breadcrumb] = t('storages.label_new_storage') %>
<%= toolbar title: t("storages.label_new_storage") %>
<%= labelled_tabular_form_for @project_storage, url: project_settings_projects_storages_path do |f| -%>
<%= error_messages_for_contract @project_storage, @errors %>
<section class="form--section">
<div class="form--field -required">
<%= f.select :storage_id,
@available_storages.map { |storage| ["#{storage.name} (#{storage.provider_type})", storage.id] },
selected: @available_storages.first.id,
container_class: '-slim' %>
</div>
</section>
<%= styled_button_tag t(:button_create), class: "-highlight -with-icon icon-checkmark" %>
<% end %>

@ -2,4 +2,10 @@ OpenProject::Application.routes.draw do
scope 'admin/settings' do
resources :storages, controller: 'storages/admin/storages'
end
scope 'projects/:project_id', as: 'project' do
namespace 'settings' do
resources :projects_storages, controller: '/storages/admin/projects_storages', only: %i[index new create destroy]
end
end
end

@ -35,15 +35,23 @@ module OpenProject::Storages
{},
dependencies: %i[view_file_links]
permission :manage_storage_in_project,
{},
dependencies: %i[select_project_modules]
{ 'storages/admin/projects_storages': %i[index new create destroy] },
dependencies: %i[]
end
# Menu extensions
menu :admin_menu,
:storages_admin_settings,
{ controller: '/storages/admin/storages', action: :index },
if: Proc.new { User.current.admin? },
caption: :project_module_storages,
icon: 'icon2 icon-hosting'
menu :project_menu,
:storages,
{ controller: '/storages/storages', action: 'index' },
caption: :'storages.label_storage'
:settings_projects_storages,
{ controller: '/storages/admin/projects_storages', action: 'index' },
caption: :'storages.label_storage',
parent: :settings
end
end
end

Loading…
Cancel
Save