iron-cms 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/iron.css +668 -388
  3. data/app/assets/tailwind/iron/application.css +1 -0
  4. data/app/assets/tailwind/iron/components/button.css +0 -7
  5. data/app/assets/tailwind/iron/components/checkbox.css +21 -0
  6. data/app/assets/tailwind/iron/components/form.css +1 -1
  7. data/app/assets/tailwind/iron/lexxy.css +165 -51
  8. data/app/controllers/iron/account/exports_controller.rb +26 -0
  9. data/app/controllers/iron/account/imports_controller.rb +27 -0
  10. data/app/helpers/iron/form_builder.rb +7 -0
  11. data/app/jobs/iron/export_job.rb +9 -0
  12. data/app/jobs/iron/import_job.rb +9 -0
  13. data/app/models/concerns/iron/broadcastable.rb +9 -0
  14. data/app/models/concerns/iron/processable.rb +34 -0
  15. data/app/models/iron/account/export.rb +86 -0
  16. data/app/models/iron/account/import.rb +208 -0
  17. data/app/models/iron/block_definition/exportable.rb +14 -0
  18. data/app/models/iron/block_definition/importable.rb +27 -0
  19. data/app/models/iron/block_definition.rb +1 -1
  20. data/app/models/iron/content_type/exportable.rb +20 -0
  21. data/app/models/iron/content_type/importable.rb +32 -0
  22. data/app/models/iron/content_type.rb +1 -1
  23. data/app/models/iron/current.rb +6 -3
  24. data/app/models/iron/entry/exportable.rb +49 -0
  25. data/app/models/iron/entry/importable.rb +181 -0
  26. data/app/models/iron/entry.rb +1 -1
  27. data/app/models/iron/field.rb +9 -1
  28. data/app/models/iron/field_definition/exportable.rb +23 -0
  29. data/app/models/iron/field_definition/importable.rb +39 -0
  30. data/app/models/iron/field_definition.rb +1 -1
  31. data/app/models/iron/fields/block.rb +18 -0
  32. data/app/models/iron/fields/block_list.rb +8 -0
  33. data/app/models/iron/fields/boolean.rb +4 -0
  34. data/app/models/iron/fields/date.rb +4 -0
  35. data/app/models/iron/fields/file.rb +16 -0
  36. data/app/models/iron/fields/number.rb +4 -0
  37. data/app/models/iron/fields/reference.rb +4 -0
  38. data/app/models/iron/fields/reference_list.rb +4 -0
  39. data/app/models/iron/fields/rich_text_area.rb +32 -0
  40. data/app/models/iron/fields/text_area.rb +4 -0
  41. data/app/models/iron/fields/text_field.rb +4 -0
  42. data/app/models/iron/user.rb +2 -0
  43. data/app/views/iron/account/exports/index.html.erb +43 -0
  44. data/app/views/iron/account/exports/new.html.erb +39 -0
  45. data/app/views/iron/account/exports/show.html.erb +40 -0
  46. data/app/views/iron/account/imports/index.html.erb +43 -0
  47. data/app/views/iron/account/imports/new.html.erb +52 -0
  48. data/app/views/iron/account/imports/show.html.erb +37 -0
  49. data/app/views/iron/content_types/index.html.erb +1 -8
  50. data/app/views/iron/entries/fields/_file.html.erb +3 -3
  51. data/app/views/iron/settings/show.html.erb +4 -11
  52. data/config/routes.rb +3 -9
  53. data/db/migrate/20251209103109_create_iron_account_exports.rb +13 -0
  54. data/db/migrate/20251209103110_create_iron_account_imports.rb +13 -0
  55. data/lib/iron/version.rb +1 -1
  56. data/lib/iron.rb +1 -1
  57. metadata +40 -28
  58. data/app/controllers/iron/contents_controller.rb +0 -33
  59. data/app/controllers/iron/schemas_controller.rb +0 -32
  60. data/app/models/concerns/iron/csv_serializable.rb +0 -28
  61. data/app/models/iron/archive.rb +0 -69
  62. data/app/models/iron/block_definition/portable.rb +0 -20
  63. data/app/models/iron/content_export.rb +0 -73
  64. data/app/models/iron/content_import/entry_builder.rb +0 -80
  65. data/app/models/iron/content_import/entry_snapshot.rb +0 -23
  66. data/app/models/iron/content_import/field_reconstructor.rb +0 -276
  67. data/app/models/iron/content_import/field_snapshot.rb +0 -33
  68. data/app/models/iron/content_import/registry.rb +0 -32
  69. data/app/models/iron/content_import/session.rb +0 -89
  70. data/app/models/iron/content_import.rb +0 -15
  71. data/app/models/iron/content_type/portable.rb +0 -30
  72. data/app/models/iron/entry/portable.rb +0 -35
  73. data/app/models/iron/field/portable.rb +0 -33
  74. data/app/models/iron/field_definition/portable.rb +0 -42
  75. data/app/models/iron/schema_archive.rb +0 -71
  76. data/app/models/iron/schema_exporter.rb +0 -15
  77. data/app/models/iron/schema_importer/import_strategy.rb +0 -59
  78. data/app/models/iron/schema_importer/merge_strategy.rb +0 -52
  79. data/app/models/iron/schema_importer/replace_strategy.rb +0 -51
  80. data/app/models/iron/schema_importer/safe_strategy.rb +0 -55
  81. data/app/models/iron/schema_importer.rb +0 -108
  82. data/app/views/iron/contents/new.html.erb +0 -34
  83. data/app/views/iron/schemas/new.html.erb +0 -57
  84. data/lib/iron/test_fixtures.rb +0 -50
@@ -45,6 +45,18 @@ module Iron
45
45
  result
46
46
  end
47
47
 
48
+ def export_value
49
+ {
50
+ type: "block",
51
+ block_handle: block_definition.handle,
52
+ fields: export_nested_fields
53
+ }
54
+ end
55
+
56
+ def export_attachments
57
+ fields.flat_map(&:export_attachments)
58
+ end
59
+
48
60
  def to_csv_rows
49
61
  rows = []
50
62
 
@@ -72,5 +84,11 @@ module Iron
72
84
 
73
85
  content&.truncate(300)
74
86
  end
87
+
88
+ private
89
+
90
+ def export_nested_fields
91
+ fields.to_h { |f| [ f.definition.handle, f.export_value ] }
92
+ end
75
93
  end
76
94
  end
@@ -13,6 +13,14 @@ module Iron
13
13
  blocks.map(&:value)
14
14
  end
15
15
 
16
+ def export_value
17
+ { type: "block_list", value: blocks.map(&:export_value) }
18
+ end
19
+
20
+ def export_attachments
21
+ blocks.flat_map(&:export_attachments)
22
+ end
23
+
16
24
  def to_csv_rows
17
25
  rows = []
18
26
 
@@ -4,6 +4,10 @@ module Iron
4
4
  value_boolean
5
5
  end
6
6
 
7
+ def export_value
8
+ { type: "boolean", value: value_boolean }
9
+ end
10
+
7
11
  private
8
12
 
9
13
  def csv_type
@@ -4,6 +4,10 @@ module Iron
4
4
  value_datetime
5
5
  end
6
6
 
7
+ def export_value
8
+ { type: "date", value: value_datetime&.iso8601 }
9
+ end
10
+
7
11
  private
8
12
 
9
13
  def csv_type
@@ -8,12 +8,28 @@ module Iron
8
8
  file.attached? ? file : nil
9
9
  end
10
10
 
11
+ def export_value
12
+ return { type: "file", value: nil } unless file.attached?
13
+
14
+ { type: "file", value: export_attachment_path }
15
+ end
16
+
17
+ def export_attachments
18
+ return [] unless file.attached?
19
+
20
+ [ file.blob ]
21
+ end
22
+
11
23
  def image?
12
24
  file.attached? && file.blob.content_type&.start_with?("image/")
13
25
  end
14
26
 
15
27
  private
16
28
 
29
+ def export_attachment_path
30
+ "#{entry.id}/#{file.blob.key}_#{file.blob.filename}"
31
+ end
32
+
17
33
  def definition_restricts_file_type?
18
34
  file.attached? &&
19
35
  definition.file_scope == "specific" &&
@@ -4,6 +4,10 @@ module Iron
4
4
  value_float
5
5
  end
6
6
 
7
+ def export_value
8
+ { type: "number", value: value_float }
9
+ end
10
+
7
11
  private
8
12
 
9
13
  def csv_type
@@ -11,6 +11,10 @@ module Iron
11
11
  end
12
12
  end
13
13
 
14
+ def export_value
15
+ { type: "reference", value: referenced_entry_id }
16
+ end
17
+
14
18
  private
15
19
 
16
20
  def csv_type
@@ -14,6 +14,10 @@ module Iron
14
14
  end
15
15
  end
16
16
 
17
+ def export_value
18
+ { type: "reference_list", value: references.map(&:entry_id) }
19
+ end
20
+
17
21
  def to_csv_rows
18
22
  rows = []
19
23
 
@@ -1,11 +1,31 @@
1
1
  module Iron
2
2
  class Fields::RichTextArea < Field
3
+ include ActionView::Helpers::TagHelper
4
+
3
5
  has_rich_text :rich_text
4
6
 
5
7
  def value
6
8
  rich_text&.to_s
7
9
  end
8
10
 
11
+ def export_value
12
+ return { type: "rich_text_area", value: nil } unless rich_text&.body.present?
13
+
14
+ html = rich_text.body.render_attachments do |attachment|
15
+ export_attachment_tag(attachment)
16
+ end.to_html
17
+
18
+ { type: "rich_text_area", value: html }
19
+ end
20
+
21
+ def export_attachments
22
+ return [] unless rich_text&.body.present?
23
+
24
+ rich_text.body.attachables.filter_map do |attachable|
25
+ attachable.blob if attachable.respond_to?(:blob)
26
+ end
27
+ end
28
+
9
29
  def to_csv_rows
10
30
  rows = []
11
31
 
@@ -24,6 +44,18 @@ module Iron
24
44
 
25
45
  private
26
46
 
47
+ def export_attachment_tag(attachment)
48
+ case attachable = attachment.attachable
49
+ when ActiveStorage::Blob
50
+ path = "#{entry.id}/#{attachable.key}_#{attachable.filename}"
51
+ attachable.image? ? tag.img(src: path) : tag.a(attachable.filename, href: path)
52
+ when ActionText::Attachables::RemoteImage
53
+ tag.img(src: attachable.url)
54
+ else
55
+ attachment.to_html
56
+ end
57
+ end
58
+
27
59
  def csv_type
28
60
  "rich_text"
29
61
  end
@@ -4,6 +4,10 @@ module Iron
4
4
  value_text
5
5
  end
6
6
 
7
+ def export_value
8
+ { type: "text_area", value: value_text }
9
+ end
10
+
7
11
  private
8
12
 
9
13
  def csv_type
@@ -6,6 +6,10 @@ module Iron
6
6
  value_string
7
7
  end
8
8
 
9
+ def export_value
10
+ { type: "text_field", value: value_string }
11
+ end
12
+
9
13
  private
10
14
 
11
15
  def validate_required_field
@@ -6,6 +6,8 @@ module Iron
6
6
 
7
7
  has_secure_password
8
8
  has_many :sessions, dependent: :destroy
9
+ has_many :exports, class_name: "Iron::Account::Export", dependent: :destroy
10
+ has_many :imports, class_name: "Iron::Account::Import", dependent: :destroy
9
11
 
10
12
  normalizes :email_address, with: ->(e) { e.strip.downcase }
11
13
 
@@ -0,0 +1,43 @@
1
+ <% content_for :title, "Exports" %>
2
+
3
+ <div class="">
4
+ <%= back_button_to "Settings", settings_path %>
5
+ <div class="flex justify-between items-center">
6
+ <h1 class="page-title">Exports</h1>
7
+ <%= link_to "New Export", new_account_export_path, class: "button-primary" %>
8
+ </div>
9
+
10
+ <div class="mt-8">
11
+ <% if @exports.any? %>
12
+ <div class="bg-white dark:bg-stone-800/50 rounded-lg shadow-sm divide-y divide-stone-200 dark:divide-stone-700/20 overflow-hidden">
13
+ <% @exports.each do |export| %>
14
+ <div class="p-4 flex items-center justify-between">
15
+ <div>
16
+ <p class="text-sm font-medium text-stone-900 dark:text-white">
17
+ <%= export.title %>
18
+ </p>
19
+ <p class="text-sm text-stone-500 dark:text-stone-400">
20
+ <%= export.include_schema? ? "Schema" : "" %><%= export.include_schema? && export.include_content? ? " + " : "" %><%= export.include_content? ? "Content" : "" %>
21
+ </p>
22
+ </div>
23
+ <div class="flex items-center gap-3">
24
+ <% if export.pending? || export.processing? %>
25
+ <span class="inline-flex items-center gap-1.5 text-sm text-stone-500">
26
+ <div class="animate-spin h-4 w-4 border-2 border-stone-300 border-t-stone-600 rounded-full"></div>
27
+ Processing
28
+ </span>
29
+ <% elsif export.completed? %>
30
+ <%= link_to "Download", main_app.rails_blob_path(export.file, disposition: "attachment"), class: "button-secondary text-sm" %>
31
+ <% elsif export.failed? %>
32
+ <span class="text-sm text-red-600">Failed</span>
33
+ <% end %>
34
+ <%= link_to "View", account_export_path(export), class: "text-sm text-stone-500 hover:text-stone-700" %>
35
+ </div>
36
+ </div>
37
+ <% end %>
38
+ </div>
39
+ <% else %>
40
+ <p class="text-sm text-stone-500">No exports yet.</p>
41
+ <% end %>
42
+ </div>
43
+ </div>
@@ -0,0 +1,39 @@
1
+ <% content_for :title, "New Export" %>
2
+
3
+ <div class="">
4
+ <%= back_button_to "Exports", account_exports_path %>
5
+ <h1 class="page-title">New Export</h1>
6
+ <p class="mt-2 text-sm text-stone-500">Select what you want to export from your CMS.</p>
7
+
8
+ <%= form_with model: @export, class: "mt-8 max-w-2xl" do |form| %>
9
+ <fieldset class="mb-6">
10
+ <legend class="text-sm font-medium mb-3">Select what to export</legend>
11
+ <div class="space-y-5">
12
+ <div class="flex gap-3">
13
+ <div class="flex h-6 shrink-0 items-center">
14
+ <%= form.check_box :include_schema, aria: { describedby: "include_schema_description" } %>
15
+ </div>
16
+ <div class="text-sm/6">
17
+ <%= form.label :include_schema, "Schema", class: "font-medium text-stone-900 dark:text-white" %>
18
+ <p id="include_schema_description" class="text-stone-500 dark:text-stone-400">Content types, fields, and block definitions</p>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="flex gap-3">
23
+ <div class="flex h-6 shrink-0 items-center">
24
+ <%= form.check_box :include_content, aria: { describedby: "include_content_description" } %>
25
+ </div>
26
+ <div class="text-sm/6">
27
+ <%= form.label :include_content, "Content", class: "font-medium text-stone-900 dark:text-white" %>
28
+ <p id="include_content_description" class="text-stone-500 dark:text-stone-400">Entries and uploaded files</p>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </fieldset>
33
+
34
+ <div class="flex items-center gap-x-3">
35
+ <%= form.submit "Export", class: "button-primary" %>
36
+ <%= link_to "Cancel", account_exports_path, class: "button-secondary" %>
37
+ </div>
38
+ <% end %>
39
+ </div>
@@ -0,0 +1,40 @@
1
+ <% content_for :title, @export.title %>
2
+ <%= turbo_stream_from @export %>
3
+
4
+ <div class="">
5
+ <%= back_button_to "Exports", account_exports_path %>
6
+ <h1 class="page-title"><%= @export.title %></h1>
7
+
8
+ <div class="mt-8 max-w-2xl">
9
+ <div class="bg-white shadow-sm sm:rounded-lg dark:bg-stone-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
10
+ <div class="px-4 py-5 sm:p-6">
11
+ <% if @export.pending? || @export.processing? %>
12
+ <div class="flex items-center gap-3">
13
+ <div class="animate-spin h-5 w-5 border-2 border-stone-300 border-t-stone-600 rounded-full dark:border-stone-600 dark:border-t-stone-300"></div>
14
+ <h3 class="text-base font-semibold text-stone-900 dark:text-white">Generating export...</h3>
15
+ </div>
16
+
17
+ <% elsif @export.completed? %>
18
+ <h3 class="text-base font-semibold text-stone-900 dark:text-white">Export complete</h3>
19
+ <div class="mt-2 text-sm text-stone-500 dark:text-stone-400">
20
+ <p>
21
+ Exported:
22
+ <%= @export.include_schema? ? "Schema" : "" %><%= @export.include_schema? && @export.include_content? ? " and " : "" %><%= @export.include_content? ? "Content" : "" %>
23
+ </p>
24
+ </div>
25
+ <div class="mt-4">
26
+ <%= link_to "Download", main_app.rails_blob_path(@export.file, disposition: "attachment"), class: "button-primary" %>
27
+ </div>
28
+
29
+ <% elsif @export.failed? %>
30
+ <h3 class="text-base font-semibold text-stone-900 dark:text-white">Export failed</h3>
31
+ <% if @export.error_message.present? %>
32
+ <div class="mt-2 text-sm text-stone-500 dark:text-stone-400">
33
+ <p><%= @export.error_message %></p>
34
+ </div>
35
+ <% end %>
36
+ <% end %>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
@@ -0,0 +1,43 @@
1
+ <% content_for :title, "Imports" %>
2
+
3
+ <div class="">
4
+ <%= back_button_to "Settings", settings_path %>
5
+ <div class="flex justify-between items-center">
6
+ <h1 class="page-title">Imports</h1>
7
+ <%= link_to "New Import", new_account_import_path, class: "button-primary" %>
8
+ </div>
9
+
10
+ <div class="mt-8">
11
+ <% if @imports.any? %>
12
+ <div class="bg-white dark:bg-stone-800/50 rounded-lg shadow-sm divide-y divide-stone-200 dark:divide-stone-700/20 overflow-hidden">
13
+ <% @imports.each do |import| %>
14
+ <div class="p-4 flex items-center justify-between">
15
+ <div>
16
+ <p class="text-sm font-medium text-stone-900 dark:text-white">
17
+ <%= import.title %>
18
+ </p>
19
+ <p class="text-sm text-stone-500 dark:text-stone-400">
20
+ <%= import.include_schema? ? "Schema" : "" %><%= import.include_schema? && import.include_content? ? " + " : "" %><%= import.include_content? ? "Content" : "" %>
21
+ </p>
22
+ </div>
23
+ <div class="flex items-center gap-3">
24
+ <% if import.pending? || import.processing? %>
25
+ <span class="inline-flex items-center gap-1.5 text-sm text-stone-500">
26
+ <div class="animate-spin h-4 w-4 border-2 border-stone-300 border-t-stone-600 rounded-full"></div>
27
+ Processing
28
+ </span>
29
+ <% elsif import.completed? %>
30
+ <span class="text-sm text-green-600">Completed</span>
31
+ <% elsif import.failed? %>
32
+ <span class="text-sm text-red-600">Failed</span>
33
+ <% end %>
34
+ <%= link_to "View", account_import_path(import), class: "text-sm text-stone-500 hover:text-stone-700" %>
35
+ </div>
36
+ </div>
37
+ <% end %>
38
+ </div>
39
+ <% else %>
40
+ <p class="text-sm text-stone-500">No imports yet.</p>
41
+ <% end %>
42
+ </div>
43
+ </div>
@@ -0,0 +1,52 @@
1
+ <% content_for :title, "Import Data" %>
2
+
3
+ <div class="">
4
+ <%= back_button_to "Imports", account_imports_path %>
5
+ <h1 class="page-title">Import Data</h1>
6
+ <p class="mt-2 text-sm text-stone-500">Upload a file to import your CMS data.</p>
7
+
8
+ <%= form_with model: @import, multipart: true, class: "mt-8 max-w-2xl" do |form| %>
9
+ <fieldset class="mb-6">
10
+ <legend class="text-sm font-medium mb-3">Select what to import</legend>
11
+ <div class="space-y-5">
12
+ <div class="flex gap-3">
13
+ <div class="flex h-6 shrink-0 items-center">
14
+ <%= form.check_box :include_schema, aria: { describedby: "include_schema_description" } %>
15
+ </div>
16
+ <div class="text-sm/6">
17
+ <%= form.label :include_schema, "Schema", class: "font-medium text-stone-900 dark:text-white" %>
18
+ <p id="include_schema_description" class="text-stone-500 dark:text-stone-400">Content types, fields, and block definitions</p>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="flex gap-3">
23
+ <div class="flex h-6 shrink-0 items-center">
24
+ <%= form.check_box :include_content, aria: { describedby: "include_content_description" } %>
25
+ </div>
26
+ <div class="text-sm/6">
27
+ <%= form.label :include_content, "Content", class: "font-medium text-stone-900 dark:text-white" %>
28
+ <p id="include_content_description" class="text-stone-500 dark:text-stone-400">Entries and uploaded files</p>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </fieldset>
33
+
34
+ <div class="field-group">
35
+ <div class="field">
36
+ <%= form.label :file, "File" %>
37
+ <div>
38
+ <%= form.file_field :file,
39
+ accept: ".zip",
40
+ required: true,
41
+ class: "input" %>
42
+ <p class="mt-2 text-sm text-stone-500">Select a file exported from Iron CMS</p>
43
+ </div>
44
+ </div>
45
+ </div>
46
+
47
+ <div class="mt-6 flex items-center gap-x-3">
48
+ <%= form.submit "Import", class: "button-primary" %>
49
+ <%= link_to "Cancel", account_imports_path, class: "button-secondary" %>
50
+ </div>
51
+ <% end %>
52
+ </div>
@@ -0,0 +1,37 @@
1
+ <% content_for :title, @import.title %>
2
+ <%= turbo_stream_from @import %>
3
+
4
+ <div class="">
5
+ <%= back_button_to "Imports", account_imports_path %>
6
+ <h1 class="page-title"><%= @import.title %></h1>
7
+
8
+ <div class="mt-8 max-w-2xl">
9
+ <div class="bg-white shadow-sm sm:rounded-lg dark:bg-stone-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
10
+ <div class="px-4 py-5 sm:p-6">
11
+ <% if @import.pending? || @import.processing? %>
12
+ <div class="flex items-center gap-3">
13
+ <div class="animate-spin h-5 w-5 border-2 border-stone-300 border-t-stone-600 rounded-full dark:border-stone-600 dark:border-t-stone-300"></div>
14
+ <h3 class="text-base font-semibold text-stone-900 dark:text-white">Importing...</h3>
15
+ </div>
16
+
17
+ <% elsif @import.completed? %>
18
+ <h3 class="text-base font-semibold text-stone-900 dark:text-white">Import complete</h3>
19
+ <div class="mt-2 text-sm text-stone-500 dark:text-stone-400">
20
+ <p>
21
+ Imported:
22
+ <%= @import.include_schema? ? "Schema" : "" %><%= @import.include_schema? && @import.include_content? ? " and " : "" %><%= @import.include_content? ? "Content" : "" %>
23
+ </p>
24
+ </div>
25
+
26
+ <% elsif @import.failed? %>
27
+ <h3 class="text-base font-semibold text-stone-900 dark:text-white">Import failed</h3>
28
+ <% if @import.error_message.present? %>
29
+ <div class="mt-2 text-sm text-stone-500 dark:text-stone-400">
30
+ <p><%= @import.error_message %></p>
31
+ </div>
32
+ <% end %>
33
+ <% end %>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
@@ -3,14 +3,7 @@
3
3
  <div class="space-y-8">
4
4
  <div class="flex justify-between items-center">
5
5
  <h1 class="page-title">Content Types</h1>
6
- <div class="flex items-center gap-2">
7
- <%= link_to "Export",
8
- export_schema_path,
9
- class: "button-secondary",
10
- data: { turbo: false } %>
11
- <%= link_to "Import", schema_path, class: "button-secondary" %>
12
- <%= link_to "New Content Type", new_content_type_path, class: "button-primary" %>
13
- </div>
6
+ <%= link_to "New Content Type", new_content_type_path, class: "button-primary" %>
14
7
  </div>
15
8
 
16
9
  <div
@@ -20,8 +20,8 @@
20
20
  bg-stone-700
21
21
  "
22
22
  >
23
- <% if field.file.attached? && field.valid? %>
24
- <%= image_tag field.file,
23
+ <% if field.file.attached? && field.file.blob.persisted? && field.valid? %>
24
+ <%= image_tag main_app.url_for(field.file),
25
25
  class: "h-full w-full object-cover object-center",
26
26
  data: {
27
27
  file_upload_target: "preview",
@@ -36,7 +36,7 @@
36
36
  >
37
37
  <% end %>
38
38
  </div>
39
- <%= builder.label :file, "Change", class: "btn mt-2" %>
39
+ <%= builder.label :file, "Change", class: "button-primary mt-2" %>
40
40
  <%= builder.file_field :file,
41
41
  class: "hidden",
42
42
  accept:
@@ -32,20 +32,13 @@
32
32
  </div>
33
33
 
34
34
  <div class="bg-white dark:bg-stone-800/50 rounded-lg shadow-sm p-6 max-w-96">
35
- <h2 class="text-lg font-semibold mb-4">Content Management</h2>
35
+ <h2 class="text-lg font-semibold mb-4">Data Management</h2>
36
36
  <p class="text-sm text-stone-600 dark:text-stone-400 mb-4">
37
- Export content entries and their files or import an archive from another instance.
37
+ Export and import your CMS data.
38
38
  </p>
39
39
  <div class="flex flex-col gap-2">
40
- <%= link_to "Export Content",
41
- export_content_path,
42
- class: "button-primary",
43
- data: {
44
- turbo: false,
45
- } %>
46
- <%= link_to "Import Content",
47
- new_content_path,
48
- class: "button-secondary" %>
40
+ <%= link_to "Export Data", account_exports_path, class: "button-secondary" %>
41
+ <%= link_to "Import Data", account_imports_path, class: "button-secondary" %>
49
42
  </div>
50
43
  </div>
51
44
  </div>
data/config/routes.rb CHANGED
@@ -16,15 +16,9 @@ Iron::Engine.routes.draw do
16
16
  get "entries/search", to: "entries#search"
17
17
  resources :icons, only: [ :index ]
18
18
 
19
- resource :schema, only: [] do
20
- get :export, on: :member
21
- get :new, on: :member
22
- post :import, on: :member
23
- end
24
-
25
- resource :content, only: [ :new ] do
26
- get :export, on: :collection
27
- post :import, on: :collection
19
+ namespace :account do
20
+ resources :exports, only: %i[index new create show]
21
+ resources :imports, only: %i[index new create show]
28
22
  end
29
23
 
30
24
  resources :block_definitions do
@@ -0,0 +1,13 @@
1
+ class CreateIronAccountExports < ActiveRecord::Migration[8.1]
2
+ def change
3
+ create_table :iron_account_exports do |t|
4
+ t.references :user, null: false, foreign_key: { to_table: :iron_users }
5
+ t.string :status, default: "pending", null: false
6
+ t.boolean :include_schema, default: true, null: false
7
+ t.boolean :include_content, default: true, null: false
8
+ t.datetime :completed_at
9
+ t.string :error_message
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class CreateIronAccountImports < ActiveRecord::Migration[8.1]
2
+ def change
3
+ create_table :iron_account_imports do |t|
4
+ t.references :user, null: false, foreign_key: { to_table: :iron_users }
5
+ t.string :status, default: "pending", null: false
6
+ t.boolean :include_schema, default: true, null: false
7
+ t.boolean :include_content, default: true, null: false
8
+ t.datetime :completed_at
9
+ t.string :error_message
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
data/lib/iron/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Iron
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.1"
3
3
  end
data/lib/iron.rb CHANGED
@@ -2,7 +2,7 @@ require "iron/version"
2
2
  require "iron/engine"
3
3
  require "iron/sdk"
4
4
  require "iron/global_id/instance_scoped_locator"
5
- require "iron/test_fixtures"
5
+ require "zip"
6
6
 
7
7
  module Iron
8
8
  # Your code goes here...