scinote-web/app/controllers/repository_row_connections_controller.rb

172 lines
6.8 KiB
Ruby

# frozen_string_literal: true
class RepositoryRowConnectionsController < ApplicationController
before_action :load_repository, except: :repositories
before_action :load_create_vars, only: :create
before_action :check_read_permissions, except: :repositories
before_action :load_repository_row, except: :repositories
before_action :check_manage_permissions, only: %i(create destroy)
def create
RepositoryRowConnection.transaction do
@connection_repository.repository_rows
.where(id: connection_params[:relation_ids])
.where.not(id: @repository_row.id)
.where.not(
id: if @relation_type == 'parent'
@repository_row.parent_connections.select(:parent_id)
else
@repository_row.child_connections.select(:child_id)
end
)
.find_each do |linked_repository_row|
build_connection(linked_repository_row)
log_activity(:inventory_item_relationships_linked,
@repository_row.repository,
{ repository_row: @repository_row.id,
repository_row_linked: linked_repository_row.id,
relationship_type: @relation_type == 'parent' ? 'parent' : 'child' })
end
@repository_row.save!
relation_key = @relation_type == 'parent' ? :parents : :children
render json: { relation_key => connected_rows_by_relation_type }
end
rescue ActiveRecord::RecordInvalid => e
Rails.logger.error e.message
render json: { errors: @repository_row.errors.full_messages }, status: :unprocessable_entity
end
def destroy
RepositoryRowConnection.transaction do
connection = @repository_row.parent_connections.or(@repository_row.child_connections).find(params[:id])
unlinked_repository_row = connection.parent?(@repository_row) ? connection.child : connection.parent
log_activity(:inventory_item_relationships_unlinked,
@repository_row.repository,
{ repository_row: @repository_row.id,
repository_row_unlinked: unlinked_repository_row.id })
connection.destroy!
head :no_content
end
rescue StandardError
head :unprocessable_entity
end
def repositories
repositories = Repository.accessible_by_teams(current_team)
.search_by_name_and_id(current_user, current_user.teams, params[:query])
.order(name: :asc)
.page(params[:page] || 1)
.per(Constants::SEARCH_LIMIT)
render json: {
data: repositories.select(:id, :name, :archived)
.map { |repository| { id: repository.id, name: repository.name_with_label } },
next_page: repositories.next_page
}
end
def repository_rows
selected_repository = Repository.accessible_by_teams(current_team).find(params[:selected_repository_id])
repository_rows = selected_repository.repository_rows
.where.not(id: @repository_row.id)
.where.not(id: @repository_row.parent_connections.select(:parent_id))
.where.not(id: @repository_row.child_connections.select(:child_id))
.search_by_name_and_id(current_user, current_user.teams, params[:query])
.order(name: :asc)
.page(params[:page] || 1)
.per(Constants::SEARCH_LIMIT)
render json: {
data: repository_rows.select(:id, :name, :archived, :repository_id)
.map { |row| { id: row.id, name: row.name_with_label } },
next_page: repository_rows.next_page
}
end
private
def load_create_vars
@relation_type = connection_params[:relation] if connection_params[:relation].in?(%w(parent child))
return render_422(t('.invalid_params')) unless @relation_type
@connection_repository = Repository.accessible_by_teams(current_team)
.find_by(id: connection_params[:connection_repository_id])
return render_404 unless @connection_repository
return render_403 unless can_connect_repository_rows?(@connection_repository)
end
def load_repository
@repository = Repository.accessible_by_teams(current_team).find_by(id: params[:repository_id])
render_404 unless @repository
end
def load_repository_row
@repository_row = @repository.repository_rows.find_by(id: params[:repository_row_id])
render_404 unless @repository_row
end
def check_read_permissions
render_403 unless can_read_repository?(@repository)
end
def check_manage_permissions
render_403 unless can_connect_repository_rows?(@repository)
end
def connection_params
params.require(:repository_row_connection).permit(:connection_repository_id, :relation, relation_ids: [])
end
def build_connection(linked_repository_row)
connection_params = {
created_by: current_user,
last_modified_by: current_user
}
if @relation_type == 'parent'
@repository_row.parent_connections.build(connection_params.merge(parent: linked_repository_row))
else
@repository_row.child_connections.build(connection_params.merge(child: linked_repository_row))
end
end
def connected_rows_by_relation_type
repository_connections = if @relation_type == 'parent'
@repository_row.parent_connections
else
@repository_row.child_connections
end
repository_connections.map do |connection|
repository_row = @relation_type == 'parent' ? connection.parent : connection.child
{
name: repository_row.name_with_label,
code: repository_row.code,
path: repository_repository_row_path(repository_row.repository, repository_row),
repository_name: repository_row.repository.name,
repository_path: repository_path(repository_row.repository),
unlink_path: repository_repository_row_repository_row_connection_path(
repository_row.repository,
repository_row,
connection
)
}
end
end
def log_activity(type_of, repository, message_items = {})
message_items = { repository: repository.id }.merge(message_items)
Activities::CreateActivityService
.call(activity_type: type_of,
owner: current_user,
subject: repository,
team: repository.team,
message_items: message_items)
end
end