diff --git a/app/models/account/data_transfer/record_set.rb b/app/models/account/data_transfer/record_set.rb index ff7b79b5c..c46c34896 100644 --- a/app/models/account/data_transfer/record_set.rb +++ b/app/models/account/data_transfer/record_set.rb @@ -65,7 +65,7 @@ class Account::DataTransfer::RecordSet end def export_record(record) - zip.add_file "data/#{model_dir}/#{record.id}.json", record.to_json + zip.add_file "data/#{model_dir}/#{record.id}.json", record.attributes.slice(*attributes).to_json end def files diff --git a/app/models/color.rb b/app/models/color.rb index 1817d4f70..b6cc1110c 100644 --- a/app/models/color.rb +++ b/app/models/color.rb @@ -2,9 +2,23 @@ Color = Struct.new(:name, :value) class Color class << self + # Finds a Color by its CSS value (e.g. "var(--color-card-4)"). + # Falls back to extracting the value from legacy export formats where + # the Color struct was serialized instead of the raw CSS string. def for_value(value) - COLORS.find { |it| it.value == value } + COLORS.find { |it| it.value == value } || + extract_from_legacy_export(value) end + + private + # Broken exports serialized Color structs instead of raw CSS values, + # producing JSON like {"name":"Lime","value":"var(--color-card-4)"}. + # Parse it and extract the value. + def extract_from_legacy_export(value) + parsed = value.is_a?(String) && JSON.parse(value) + COLORS.find { |it| it.value == parsed["value"] } if parsed.is_a?(Hash) + rescue JSON::ParserError + end end def to_s diff --git a/test/models/account/import_test.rb b/test/models/account/import_test.rb index de384b385..c1e9c2f7c 100644 --- a/test/models/account/import_test.rb +++ b/test/models/account/import_test.rb @@ -226,6 +226,7 @@ class Account::ImportTest < ActiveSupport::TestCase name: account.name, board_count: Board.where(account: account).count, column_count: Column.where(account: account).count, + column_colors: Column.where(account: account).order(:id).pluck(:color), card_count: Card.where(account: account).count, comment_count: Comment.where(account: account).count, tag_count: Tag.where(account: account).count diff --git a/test/models/column/colored_test.rb b/test/models/column/colored_test.rb index 9d2d469e4..241ddb660 100644 --- a/test/models/column/colored_test.rb +++ b/test/models/column/colored_test.rb @@ -7,6 +7,14 @@ class Column::ColoredTest < ActiveSupport::TestCase assert_equal Column::Colored::DEFAULT_COLOR, column.color end + test "reads color from legacy export format" do + column = columns(:writebook_triage) + # Broken exports serialized Color structs as JSON + column.update_column(:color, { "name" => "Lime", "value" => "var(--color-card-4)" }.to_json) + + assert_equal Color.for_value("var(--color-card-4)"), column.reload.color + end + test "update the column color" do columns(:writebook_triage).update!(color: "var(--color-card-3)")