diff --git a/app/controllers/repository_rows_controller.rb b/app/controllers/repository_rows_controller.rb
index a08dc7650..458971463 100644
--- a/app/controllers/repository_rows_controller.rb
+++ b/app/controllers/repository_rows_controller.rb
@@ -385,7 +385,15 @@ class RepositoryRowsController < ApplicationController
end
def load_repository_row
- @repository_row = @repository.repository_rows.eager_load(:repository_columns).find_by(id: params[:id])
+ @repository_row =
+ if params[:form_repository_rows_field_value_id]
+ FormRepositoryRowsFieldValue
+ .find_by(id: params[:form_repository_rows_field_value_id])
+ &.reified_repository_row_by_id(params[:id])
+ else
+ @repository.repository_rows.eager_load(:repository_columns).find_by(id: params[:id])
+ end
+
render_404 unless @repository_row
end
diff --git a/app/javascript/vue/forms/fields/repository_rows.vue b/app/javascript/vue/forms/fields/repository_rows.vue
index 542d0cb51..f1aec6fe7 100644
--- a/app/javascript/vue/forms/fields/repository_rows.vue
+++ b/app/javascript/vue/forms/fields/repository_rows.vue
@@ -63,7 +63,7 @@ export default {
},
methods: {
itemCardUrl(row) {
- return repository_repository_row_path(row.repository_id, row.id);
+ return repository_repository_row_path(row.repository_id, row.id, { form_repository_rows_field_value_id: this.field.field_value.id });
},
addValue(rows) {
const rowIds = this.assignedIds;
diff --git a/app/javascript/vue/repository_item_sidebar/RepositoryItemSidebar.vue b/app/javascript/vue/repository_item_sidebar/RepositoryItemSidebar.vue
index 08d95dc2a..ec723f74e 100644
--- a/app/javascript/vue/repository_item_sidebar/RepositoryItemSidebar.vue
+++ b/app/javascript/vue/repository_item_sidebar/RepositoryItemSidebar.vue
@@ -10,7 +10,7 @@
-
-
-
-
-
-
-
- {{ i18n.t("repositories.item_card.repository_text_value.no_text") }}
-
+
diff --git a/app/javascript/vue/shared/content/form_response.vue b/app/javascript/vue/shared/content/form_response.vue
index 8ffc8beca..c06eb5f87 100644
--- a/app/javascript/vue/shared/content/form_response.vue
+++ b/app/javascript/vue/shared/content/form_response.vue
@@ -166,12 +166,12 @@ export default {
if (this.formFieldValues.find((formFieldValue) => formFieldValue.form_field_id === formFieldId)) {
this.formFieldValues = this.formFieldValues.map((formFieldValue) => {
if (formFieldValue.form_field_id === formFieldId) {
- return response.data.data.attributes;
+ return { ...response.data.data.attributes, id: response.data.data.id };
}
return formFieldValue;
});
} else {
- this.formFieldValues.push(response.data.data.attributes);
+ this.formFieldValues.push({ ...response.data.data.attributes, id: response.data.data.id });
}
});
},
diff --git a/app/javascript/vue/shared/legacy/Textarea.vue b/app/javascript/vue/shared/legacy/Textarea.vue
index 3a2e692ce..1a3ee6763 100644
--- a/app/javascript/vue/shared/legacy/Textarea.vue
+++ b/app/javascript/vue/shared/legacy/Textarea.vue
@@ -115,6 +115,8 @@ export default {
});
},
enableEdit(e) {
+ if (!this.canEdit) return;
+
if (e && $(e.target).hasClass('atwho-user-popover')) return;
if (e && $(e.target).hasClass('sa-name')) return;
if (e && $(e.target).hasClass('sa-link')) return;
diff --git a/app/models/form_repository_rows_field_value.rb b/app/models/form_repository_rows_field_value.rb
index 0d4a4ebd0..add6b4818 100644
--- a/app/models/form_repository_rows_field_value.rb
+++ b/app/models/form_repository_rows_field_value.rb
@@ -25,6 +25,35 @@ class FormRepositoryRowsFieldValue < FormFieldValue
data
end
+ def reified_repository_row_by_id(repository_row_id)
+ # build an in-memory, read-only representation of the repository row in the snapshot
+
+ row_attributes = data.find { |r| r['id'] == repository_row_id.to_i }
+ row = RepositoryRow.new(row_attributes.except('repository_cells'))
+
+ row.repository_cells = row_attributes['repository_cells'].map do |cell_attributes|
+ repository_cell = row.repository_cells.build(cell_attributes.except('value', 'repository_column'))
+ repository_column = RepositoryColumn.new(cell_attributes['repository_column'])
+ repository_column.readonly!
+
+ repository_cell.assign_attributes(
+ repository_column_id: cell_attributes['repository_column']['id'],
+ repository_row_id: repository_row_id.to_i,
+ repository_column: repository_column,
+ value:
+ cell_attributes['repository_column']['data_type'].constantize.new(
+ cell_attributes['value'].except('repository_column')
+ )
+ )
+ repository_cell.readonly!
+ repository_cell
+ end
+
+ row.snapshot_by_name = User.find_by(id: row.snapshot_by_id)&.full_name
+ row.readonly!
+ row
+ end
+
def formatted
value&.map { |i| "#{i['name']} (#{RepositoryRow::ID_PREFIX}#{i['id']})" }&.join(' | ')
end
diff --git a/app/models/repository_row.rb b/app/models/repository_row.rb
index ce7988bec..e028210b8 100644
--- a/app/models/repository_row.rb
+++ b/app/models/repository_row.rb
@@ -112,7 +112,7 @@ class RepositoryRow < ApplicationRecord
length: { maximum: Constants::NAME_MAX_LENGTH }
validates :created_by, presence: true
- attr_accessor :import_status, :import_message
+ attr_accessor :import_status, :import_message, :snapshot_at, :snapshot_by_id, :snapshot_by_name
scope :active, -> { where(archived: false) }
scope :archived, -> { where(archived: true) }
diff --git a/app/serializers/form_field_value_serializer.rb b/app/serializers/form_field_value_serializer.rb
index 7b633e83d..ef8b89f8b 100644
--- a/app/serializers/form_field_value_serializer.rb
+++ b/app/serializers/form_field_value_serializer.rb
@@ -3,7 +3,7 @@
class FormFieldValueSerializer < ActiveModel::Serializer
include Canaid::Helpers::PermissionsHelper
- attributes :form_field_id, :type, :value, :submitted_at, :submitted_by_full_name,
+ attributes :id, :form_field_id, :type, :value, :submitted_at, :submitted_by_full_name,
:unit, :not_applicable, :selection, :datetime, :datetime_to
def submitted_by_full_name
diff --git a/app/views/repository_rows/show.json.jbuilder b/app/views/repository_rows/show.json.jbuilder
index 8cb949385..63306b85a 100644
--- a/app/views/repository_rows/show.json.jbuilder
+++ b/app/views/repository_rows/show.json.jbuilder
@@ -1,10 +1,15 @@
# frozen_string_literal: true
json.id @repository_row.id
+if @repository_row.snapshot_at
+ json.snapshot_at DateTime.parse(@repository_row.snapshot_at).strftime("#{I18n.backend.date_format} %H:%M")
+ json.snapshot_by_name @repository_row.snapshot_by_name
+end
+
json.repository do
json.id @repository.id
json.name @repository.name
- json.is_snapshot @repository.is_a?(RepositorySnapshot)
+ json.is_snapshot @repository.is_a?(RepositorySnapshot) || !@repository_row.snapshot_at.nil?
end
json.editable @repository_row.editable?
json.notification @notification
@@ -12,9 +17,9 @@ json.notification @notification
json.update_path update_cell_repository_repository_row_path(@repository, @repository_row)
json.permissions do
- json.can_export_repository_stock can_export_repository_stock?(@repository)
- json.can_manage can_manage_repository_rows?(@repository) if @repository.is_a?(Repository) && !@repository.is_a?(SoftLockedRepository)
- json.can_connect_rows can_connect_repository_rows?(@repository) if @repository.is_a?(Repository) && !@repository.is_a?(SoftLockedRepository)
+ json.can_export_repository_stock @repository_row.snapshot_at.nil? && can_export_repository_stock?(@repository)
+ json.can_manage @repository_row.snapshot_at.nil? && can_manage_repository_rows?(@repository) if @repository.is_a?(Repository) && !@repository.is_a?(SoftLockedRepository)
+ json.can_connect_rows @repository_row.snapshot_at.nil? && can_connect_repository_rows?(@repository) if @repository.is_a?(Repository) && !@repository.is_a?(SoftLockedRepository)
end
json.actions do
@@ -106,7 +111,7 @@ end
json.custom_columns do
json.array! repository_columns_ordered_by_state(@repository_row.repository).each do |repository_column|
- repository_cell = @repository_row.repository_cells.find_by(repository_column: repository_column)
+ repository_cell = @repository_row.repository_cells.find { |c| c.repository_column_id == repository_column.id }
options = case repository_column.data_type
when 'RepositoryListValue'
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 7844878f8..5850af453 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -2714,6 +2714,7 @@ en:
one: "day"
other: "days"
stock_export: "Export"
+ snapshot_label: "Snapshot on %{timestamp} by %{name}"
custom_columns_label: "Custom columns"
no_custom_columns_label: "No custom columns"
repository_time_range_value: