Add private to assigned inventories to tasks [SCI-12081]

This commit is contained in:
Andrej 2025-07-10 09:56:25 +02:00
parent b18ceeb31e
commit a6ff106640
11 changed files with 52 additions and 19 deletions

View file

@ -6,7 +6,7 @@ class MyModuleRepositoriesController < ApplicationController
before_action :load_my_module, except: :assign_my_modules
before_action :load_repository, except: %i(repositories_dropdown_list repositories_list_html repositories_list create)
before_action :check_my_module_view_permissions, except: %i(update consume_modal update_consumption assign_my_modules)
before_action :check_repository_view_permissions, except: %i(repositories_dropdown_list repositories_list_html repositories_list create)
before_action :check_repository_view_permissions, except: %i(index_dt repositories_dropdown_list repositories_list_html repositories_list create)
before_action :check_repository_row_consumption_permissions, only: %i(consume_modal update_consumption)
before_action :check_assign_repository_records_permissions, only: %i(update create)
before_action :load_my_modules, only: :assign_my_modules
@ -19,6 +19,8 @@ class MyModuleRepositoriesController < ApplicationController
rows_view = 'repository_rows/simple_view_index'
preload_cells = false
else
return render_403 unless can_read_repository?(@repository)
rows_view = 'repository_rows/index'
preload_cells = true
end
@ -150,8 +152,8 @@ class MyModuleRepositoriesController < ApplicationController
end
def repositories_list
@assigned_repositories = @my_module.readable_live_and_snapshot_repositories_list(current_user)
render json: @assigned_repositories, each_serializer: AssignedRepositorySerializer, scope: {user: current_user, my_module: @my_module }
@assigned_repositories = @my_module.live_and_snapshot_repositories_list
render json: @assigned_repositories, each_serializer: AssignedRepositorySerializer, scope: { user: current_user, my_module: @my_module }
end
def full_view_table

View file

@ -71,7 +71,8 @@ class MyModuleShareableLinksController < ApplicationController
my_module: @my_module,
include_stock_consumption: @repository.has_stock_management? && params[:assigned].present?,
disable_reminders: true, # reminders are always disabled for shareable links
disable_stock_management: true # stock management is always disabled in MyModule context
disable_stock_management: true, # stock management is always disabled in MyModule context
shareable_link_view: true
}
@all_rows_count = datatable_service.all_count

View file

@ -63,6 +63,8 @@ module GlobalActivitiesHelper
when Team
path = projects_path(team: obj.id)
when Repository
return I18n.t('repositories.private') unless can_read_repository?(obj)
path = repository_path(obj, team: obj.team.id)
when RepositoryRow
# Handle private repository rows
@ -72,6 +74,8 @@ module GlobalActivitiesHelper
path = repository_path(obj.repository, team: obj.repository.team.id)
when RepositoryColumn
return I18n.t('repositories.repository_column.private') unless can_read_repository?(obj.repository)
return current_value unless obj.repository
path = repository_path(obj.repository, team: obj.repository.team.id)

View file

@ -101,11 +101,14 @@ module RepositoryDatatableHelper
# otherwise it will result in duplicated SQL queries
has_stock_management = repository.has_stock_management?
reminders_enabled = !options[:disable_reminders] && Repository.reminders_enabled?
shareable_link_view = options[:shareable_link_view] && my_module.shared?
# Always disabled in a simple view
stock_managable = false
stock_consumption_permitted = has_stock_management && stock_consumption_permitted?(repository, my_module)
repository_rows.map do |record|
next { code: record.code } unless shareable_link_view || can_read_repository?(record.repository)
row = {
DT_RowId: record.id,
DT_RowAttr: { 'data-state': row_style(record, my_module) },
@ -156,7 +159,7 @@ module RepositoryDatatableHelper
consumed_stock_formatted =
number_with_precision(
record.consumed_stock,
precision: (record.repository.repository_stock_column.metadata['decimals'].to_i || 0),
precision: record.repository.repository_stock_column.metadata['decimals'].to_i || 0,
strip_insignificant_zeros: true
)
row['consumedStock'][:value] = {

View file

@ -10,14 +10,22 @@
<ul ref="reminders" v-html="reminders" class="list-none pl-0"></ul>
</template>
</GeneralDropdown>
<a class="hover:no-underline record-info-link truncate block"
<a v-if="params.data.recordInfoUrl"
class="hover:no-underline record-info-link truncate block"
:title="params.data[0]"
:href="params.data.recordInfoUrl"
>
{{ params.data[0] }}
</a>
<span v-else
:title="i18n.t('my_modules.assigned_items.repository.private_repository_row_name', {repository_row_code: params.data.code })"
class="text-sn-grey truncate"
>
<i class="sn-icon sn-icon-locked-task"></i>
{{ i18n.t('my_modules.assigned_items.repository.private_repository_row_name', {repository_row_code: params.data.code }) }}
</span>
<span v-for="state in params.data.DT_RowAttr['data-state']" class="text-sn-grey bg-sn-light-grey text-xs px-1.5 py-1 ">
<span v-if="params.data.DT_RowAttr" v-for="state in params.data.DT_RowAttr['data-state']" class="text-sn-grey bg-sn-light-grey text-xs px-1.5 py-1 ">
{{ state }}
</span>
</div>

View file

@ -19,6 +19,7 @@
</h3>
</div>
<button
v-if="repository.attributes.urls.full_view"
class="btn btn-light icon-btn ml-auto full-screen"
:data-table-url="fullViewUrl"
:data-e2e="`e2e-BT-task-assignedItems-inventory${ repository.id }-expand`"

View file

@ -4,7 +4,7 @@ Canaid::Permissions.register_for(RepositoryBase) do
# repository: read/export
can :read_repository do |user, repository|
if repository.is_a?(RepositorySnapshot)
can_read_my_module?(user, repository.my_module)
repository.original_repository.permission_granted?(user, RepositoryPermissions::READ) && can_read_my_module?(user, repository.my_module)
else
repository.permission_granted?(user, RepositoryPermissions::READ)
end

View file

@ -5,7 +5,11 @@ class AssignedRepositorySerializer < ActiveModel::Serializer
include Rails.application.routes.url_helpers
include MyModulesHelper
attributes :id, :name
attributes :id
attribute :name do
can_read_repository?(scope[:user], object) ? object.name : I18n.t('my_modules.assigned_items.repository.private_repository_name')
end
attribute :assigned_rows_count do
object['assigned_rows_count']
@ -16,19 +20,19 @@ class AssignedRepositorySerializer < ActiveModel::Serializer
end
attribute :has_stock do
object.has_stock_management?
can_read_repository?(scope[:user], object) && object.has_stock_management?
end
attribute :has_stock_consumption do
object.has_stock_consumption?
can_read_repository?(scope[:user], object) && object.has_stock_consumption?
end
attribute :can_manage_consumption do
can_update_my_module_stock_consumption?(scope[:user], scope[:my_module])
can_read_repository?(scope[:user], object) && can_update_my_module_stock_consumption?(scope[:user], scope[:my_module])
end
attribute :stock_column_name do
object.repository_stock_column.name if object.has_stock_management?
object.repository_stock_column.name if can_read_repository?(scope[:user], object) && object.has_stock_management?
end
attribute :footer_label do
@ -40,9 +44,9 @@ class AssignedRepositorySerializer < ActiveModel::Serializer
end
attribute :urls do
{
full_view: assigned_repository_full_view_table_path(scope[:my_module], object),
assigned_rows: assigned_repository_simple_view_index_path(scope[:my_module], object)
}
list = { assigned_rows: assigned_repository_simple_view_index_path(scope[:my_module], object) }
list[:full_view] = assigned_repository_full_view_table_path(scope[:my_module], object) if can_read_repository?(scope[:user], object)
list
end
end

View file

@ -2,7 +2,9 @@
locals: { team: team, subject: team, breadcrumbs: breadcrumbs, values: values, type_of: type_of } %>
<div class="ga-breadcrumb">
<span class="sn-icon sn-icon-inventory"></span>
<% if subject %>
<%if !can_read_repository?(subject)%>
<%= I18n.t('repositories.private') %>
<% elsif subject %>
<%= route_to_other_team(repository_path(subject.id, team: subject.team.id),
team,
subject.name&.truncate(Constants::NAME_TRUNCATION_LENGTH),

View file

@ -2,7 +2,9 @@
locals: { team: team, subject: team, breadcrumbs: breadcrumbs, values: values, type_of: type_of } %>
<div class="ga-breadcrumb">
<span class="sn-icon sn-icon-inventory"></span>
<% if subject %>
<%if !can_read_repository?(subject.repository)%>
<%= I18n.t('repositories.private') %>
<% elsif subject %>
<%= route_to_other_team(repository_path(subject.repository.id, team: subject.repository.team.id),
team,
subject.repository.name&.truncate(Constants::NAME_TRUNCATION_LENGTH),

View file

@ -1483,6 +1483,9 @@ en:
checkbox_label: 'Mark as output'
direct_assign:
success: "Successfully assigned an item to the task."
repository:
private_repository_name: "Private inventory"
private_repository_row_name: "Private item (%{repository_row_code})"
protocol:
title: "Protocol"
options_dropdown:
@ -2241,8 +2244,11 @@ en:
success_flash: "Table result successfully deleted."
repositories:
private: "Private inventory"
repository: "Inventory: %{name}"
snapshot_failed: "Snapshot failed"
repository_column:
private: "Private column"
icon_title:
i_shared: "Shared inventory (owned by your Team)"
shared_edit: "Shared inventory (owned by %{team_name}). You can edit."