Skip to content

Commit

Permalink
Allow to share issues with organizations members
Browse files Browse the repository at this point in the history
  • Loading branch information
nanego committed Oct 17, 2024
1 parent 45f816f commit 6f841f7
Show file tree
Hide file tree
Showing 20 changed files with 550 additions and 18 deletions.
18 changes: 16 additions & 2 deletions app/controllers/organizations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
class OrganizationsController < ApplicationController

before_action :find_organization_by_id, only: [:show, :edit, :update, :destroy, :add_users, :remove_user, :autocomplete_for_user]
before_action :require_admin_or_manager, :except => [:index, :show, :autocomplete_users, :fetch_users_by_orga]
before_action :require_login, :only => [:index, :show, :autocomplete_users]
before_action :require_admin_or_manager, :except => [:index, :show, :autocomplete_users, :fetch_users_by_orga, :search]
before_action :require_login, :only => [:index, :show, :autocomplete_users, :search]
before_action :find_project_by_project_id, :only => [:autocomplete_users]
after_action :update_fullname_and_identifier_of_children, only: [:update]

accept_api_auth :search

layout 'admin'

def index
Expand All @@ -16,6 +18,18 @@ def index
render :layout => (User.current.admin? ? 'admin' : 'base')
end

def search
q = params['organization']
@organizations = Organization.order('lft').where("LOWER(name_with_parents) LIKE LOWER(?)", "%#{q}%")

respond_to do |format|
format.api do
# @offset, @limit = api_offset_and_limit
@organizations_count = @organizations.count
end
end
end

def show
@projects = @organization.projects.active

Expand Down
6 changes: 6 additions & 0 deletions app/models/issues_organization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class IssuesOrganization < ActiveRecord::Base

belongs_to :issue
belongs_to :organization

end
2 changes: 2 additions & 0 deletions app/models/organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Organization < ActiveRecord::Base
has_many :team_leaders, through: :organization_team_leaders, :source => :user
has_many :organization_notifications
has_many :notified_projects, through: :organization_notifications, :source => :project
has_many :issues_organizations, dependent: :destroy
has_many :issues, through: :issues_organizations

safe_attributes :name, :parent_id, :description, :mail, :direction, :name_with_parents, :notified, :top_department_in_ldap

Expand Down
11 changes: 11 additions & 0 deletions app/overrides/issues/_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Deface::Override.new :virtual_path => 'issues/_form',
:original => 'ee65ebb813ba3bbf55bc8dc6279f431dbb405c48',
:name => 'add-organizations-to-issue-form',
:insert_after => '.attributes',
:partial => 'issues/select_organizations'

Deface::Override.new :virtual_path => 'issues/_form_with_positions',
:original => 'ee65ebb813ba3bbf55bc8dc6279f431dbb405c48',
:name => 'add-organizations-to-issue-form',
:insert_after => '.attributes',
:partial => 'issues/select_organizations'
5 changes: 5 additions & 0 deletions app/overrides/issues/show.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Deface::Override.new :virtual_path => 'issues/show',
:original => 'ee65ebb813ba3bbf55bc8dc6279f431dbb405c48',
:name => 'show-organizations-in-issue-description',
:insert_after => '.attributes',
:partial => 'issues/show_organizations'
61 changes: 61 additions & 0 deletions app/views/issues/_select_organizations.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<% if User.current.allowed_to?(:share_issues_with_organizations, @issue.project) %>

<p id="organizations_form">
<%= f.select :organization_ids,
options_from_collection_for_select(@issue.organizations, 'id', 'name_with_parents', @issue.organizations.map(&:id)),
{ label: l("field_issue_organizations") },
{ multiple: true, include_blank: true }
%>
</p>

<script>
let data = [];
<% @issue.organizations.each do |organization| %>
data.push({id: '<%= organization.id %>', text: '<%= organization.name_with_parents %>'});
<% end %>
$("#issue_organization_ids").select2({
containerCss: {width: '500px', minwidth: '500px'},
width: 'style',
data: data,
minimumInputLength: 3,
language: {
inputTooShort: function () {
return "Entrez au moins 3 caractères";
},
noResults: function () {
return "Aucune organisation ne correspond à cette recherche";
}
},
ajax: {
url: "/organizations/search.json?key=<%= User.current.api_key %>",
dataType: 'json',
delay: 250,
method: 'GET',
data: function (params) {
return {
organization: params.term
};
},
processResults: function (data, params) {
return {
results: data.organizations.map(function (org) {
return {
id: org.id,
text: org.name_with_parents
};
})
};
},
cache: true
}
}).on('select2:open', function () {
// Forcer le focus dans la zone de texte interne de select2 lorsqu'il s'ouvre
let searchField = $(this).data('select2').dropdown.$search || $(this).data('select2').selection.$search;
if (searchField) {
searchField.focus();
}
});

</script>

<% end %>
8 changes: 8 additions & 0 deletions app/views/issues/_show_organizations.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<% if @issue.organizations.present? %>
<hr>
<label class="label" id="label_related_organizations"><%= l("field_issue_organizations") %></label>
<span class="value">
<%= @issue.organizations.map { |o| link_to_organization(o, link_ancestors: false, title: o.users.active.map(&:to_s).join(', ')) }.to_sentence.html_safe %>
</span>
<% end %>

13 changes: 13 additions & 0 deletions app/views/organizations/search.api.rsb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
api.array :organizations, api_meta(:total_count => @organizations_count, :offset => @offset, :limit => @limit) do
@organizations.each do |organization|
api.organization do
api.id organization.id
api.name organization.name
api.name_with_parents organization.name_with_parents
api.identifier organization.identifier

api.created_at organization.created_at
api.updated_at organization.updated_at
end
end
end
6 changes: 6 additions & 0 deletions assets/stylesheets/organizations.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ textarea#organization_description{
#tab-content-managers #principals {max-height: 400px; overflow: auto;}
input#manager_search {width:90%}

#label_related_organizations {
min-width: 175px;
font-weight: bold;
display: inline-block;
}

.ldap_sync_orga {
border-radius: 10px;
width: 10px;
Expand Down
2 changes: 2 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ fr:
field_parent_organization: "Organisation parent"
field_hidden_on_overview: "Cacher sur l'aperçu des projets"
field_direction: "Est une direction"
field_issue_organizations: "Organisations concernées"
text_hide_groups_admin_menu: "Cacher les 'Groupes'"
undefined: "Indéterminé"
update_user_orga: "Modifier l'organisation de %{username} :"
Expand Down Expand Up @@ -59,3 +60,4 @@ fr:
inherited_from_parent_project: "Hérité du projet parent"
field_top_department_in_ldap: "Département racine dans le LDAP"
field_updated_by_organization: Mise à jour par un membre de
permission_share_issues_with_organizations: "Partager des demandes avec des organisations"
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
post :ldap_sync_check_status
get :add_organization_from_ldap
post :add_all_organizations_from_ldap
get :search
end
end
namespace :organizations do
Expand Down
16 changes: 16 additions & 0 deletions db/migrate/20240918141300_add_organizations_to_issues.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class AddOrganizationsToIssues < ActiveRecord::Migration[4.2]

def self.up
create_table :issues_organizations do |t|
t.column :organization_id, :integer, :null => false
t.column :issue_id, :integer, :null => false
end unless ActiveRecord::Base.connection.table_exists? 'issues_organizations'
add_index :issues_organizations, [:organization_id] unless ActiveRecord::Base.connection.index_exists?(:issues_organizations, [:organization_id])
add_index :issues_organizations, [:issue_id] unless ActiveRecord::Base.connection.index_exists?(:issues_organizations, [:issue_id])
end

def self.down
drop_table :issues_organizations
end

end
3 changes: 3 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
'hide_groups_admin_menu' => "0",
'default_team_leader_role' => nil
}, :partial => 'settings/organizations_settings'
project_module :issue_tracking do
permission :share_issues_with_organizations, {}, :require => :member
end
end

Redmine::MenuManager.map :admin_menu do |menu|
Expand Down
1 change: 1 addition & 0 deletions lib/redmine_organizations/hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def after_plugins_loaded(_context = {})
require_relative 'patches/group_patch'
require_relative 'patches/issue_patch'
require_relative 'patches/issue_query_patch'
require_relative 'patches/issues_controller_patch'
require_relative 'patches/mailer_patch'
require_relative 'patches/project_patch'
require_relative 'patches/users_helper_patch'
Expand Down
24 changes: 16 additions & 8 deletions lib/redmine_organizations/patches/application_controller_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ module RedmineOrganizations::Patches
module ApplicationControllerPatch

def authorize(ctrl = params[:controller], action = params[:action], global = false)
if @project.present? && User.current.try(:organization).present?
user_organization_and_parents_ids = User.current.organization.self_and_ancestors_ids
project_and_parents_ids = @project.self_and_ancestors.ids
organization_roles = OrganizationNonMemberRole.where(project_id: project_and_parents_ids, organization_id: user_organization_and_parents_ids)
end
if organization_roles.present?
true
if ctrl == "issues" && (%w(show edit update).include?(action))
if @issue.present? && @issue.organizations.include?(User.current.organization)
true
else
super
end
else
super
if @project.present? && User.current.try(:organization).present?
user_organization_and_parents_ids = User.current.organization.self_and_ancestors_ids
project_and_parents_ids = @project.self_and_ancestors.ids
organization_roles = OrganizationNonMemberRole.where(project_id: project_and_parents_ids, organization_id: user_organization_and_parents_ids)
end
if organization_roles.present?
true
else
super
end
end
end

Expand Down
Loading

0 comments on commit 6f841f7

Please sign in to comment.