geoblacklight_admin 0.6.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/app/assets/stylesheets/geoblacklight_admin/_core.scss +1 -1
- data/app/assets/stylesheets/geoblacklight_admin/modules/_icons.scss +9 -0
- data/app/controllers/admin/document_data_dictionaries_controller.rb +126 -0
- data/app/controllers/admin/document_data_dictionary_entries_controller.rb +124 -0
- data/app/controllers/admin/document_distributions_controller.rb +0 -38
- data/app/controllers/admin/import_distributions_controller.rb +126 -0
- data/app/javascript/index.js +1 -1
- data/app/jobs/import_distributions_run_job.rb +32 -0
- data/app/jobs/import_document_distribution_job.rb +23 -0
- data/app/models/document.rb +5 -0
- data/app/models/document_data_dictionary/csv_header_validator.rb +30 -0
- data/app/models/document_data_dictionary.rb +39 -0
- data/app/models/document_data_dictionary_entry.rb +9 -0
- data/app/models/import_distribution/csv_header_validator.rb +32 -0
- data/app/models/import_distribution.rb +55 -0
- data/app/models/import_distribution_state_machine.rb +14 -0
- data/app/models/import_distribution_transition.rb +26 -0
- data/app/models/import_document_distribution.rb +25 -0
- data/app/models/import_document_distribution_state_machine.rb +13 -0
- data/app/models/import_document_distribution_transition.rb +19 -0
- data/app/views/admin/document_data_dictionaries/_data_dictionaries_table.html.erb +40 -0
- data/app/views/admin/document_data_dictionaries/_document_data_dictionary.html.erb +37 -0
- data/app/views/admin/document_data_dictionaries/_document_data_dictionary.json.jbuilder +2 -0
- data/app/views/admin/document_data_dictionaries/_form.html.erb +17 -0
- data/app/views/admin/document_data_dictionaries/edit.html.erb +12 -0
- data/app/views/admin/document_data_dictionaries/index.html.erb +45 -0
- data/app/views/admin/document_data_dictionaries/index.json.jbuilder +1 -0
- data/app/views/admin/document_data_dictionaries/new.html.erb +78 -0
- data/app/views/admin/document_data_dictionaries/show.html.erb +78 -0
- data/app/views/admin/document_data_dictionaries/show.json.jbuilder +1 -0
- data/app/views/admin/document_data_dictionary_entries/_form.html.erb +19 -0
- data/app/views/admin/document_data_dictionary_entries/edit.html.erb +12 -0
- data/app/views/admin/document_data_dictionary_entries/new.html.erb +16 -0
- data/app/views/admin/document_distributions/index.html.erb +2 -2
- data/app/views/admin/documents/_form_nav.html.erb +4 -0
- data/app/views/admin/import_distributions/_form.html.erb +21 -0
- data/app/views/admin/import_distributions/_import_distribution.json.jbuilder +5 -0
- data/app/views/admin/import_distributions/_show_failed_tab.html.erb +36 -0
- data/app/views/admin/import_distributions/_show_success_tab.html.erb +35 -0
- data/app/views/admin/import_distributions/edit.html.erb +8 -0
- data/app/views/admin/import_distributions/index.html.erb +58 -0
- data/app/views/admin/import_distributions/index.json.jbuilder +3 -0
- data/app/views/admin/import_distributions/new.html.erb +7 -0
- data/app/views/admin/import_distributions/show.html.erb +121 -0
- data/app/views/admin/import_distributions/show.json.jbuilder +3 -0
- data/app/views/admin/imports/index.html.erb +2 -2
- data/app/views/admin/shared/_navbar.html.erb +2 -2
- data/app/views/catalog/_gbl_admin_data_dictionaries.html.erb +3 -0
- data/app/views/catalog/_show_gbl_admin_data_dictionaries.html.erb +44 -0
- data/app/views/catalog/data_dictionaries.html.erb +12 -0
- data/db/migrate/20241204163117_create_document_data_dictionaries.rb +14 -0
- data/db/migrate/20241218174455_create_document_data_dictionary_entries.rb +17 -0
- data/db/migrate/20250113213655_import_distributions.rb +56 -0
- data/lib/generators/geoblacklight_admin/config_generator.rb +61 -4
- data/lib/generators/geoblacklight_admin/templates/btaa_sample_document_data_dictionary_entries.csv +9 -0
- data/lib/generators/geoblacklight_admin/templates/btaa_sample_document_distributions.csv +17 -0
- data/lib/geoblacklight_admin/routes/data_dictionariesable.rb +17 -0
- data/lib/geoblacklight_admin/version.rb +1 -1
- metadata +49 -2
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "csv"
|
4
|
+
|
5
|
+
# ImportDistribution class
|
6
|
+
class ImportDistribution < ApplicationRecord
|
7
|
+
include ActiveModel::Validations
|
8
|
+
|
9
|
+
# Callbacks (keep at top)
|
10
|
+
after_commit :set_csv_file_attributes, if: :persisted?
|
11
|
+
|
12
|
+
# Associations
|
13
|
+
has_one_attached :csv_file
|
14
|
+
has_many :document_distributions, dependent: :destroy
|
15
|
+
has_many :import_document_distributions, dependent: :destroy
|
16
|
+
has_many :import_distribution_transitions, autosave: false, dependent: :destroy
|
17
|
+
|
18
|
+
# Validations
|
19
|
+
validates :csv_file, attached: true, content_type: {in: "text/csv", message: "is not a CSV file"}
|
20
|
+
|
21
|
+
validates_with ImportDistribution::CsvHeaderValidator
|
22
|
+
|
23
|
+
# States
|
24
|
+
include Statesman::Adapters::ActiveRecordQueries[
|
25
|
+
transition_class: ImportDistributionTransition,
|
26
|
+
initial_state: :created
|
27
|
+
]
|
28
|
+
|
29
|
+
def state_machine
|
30
|
+
@state_machine ||= ImportDistributionStateMachine.new(self, transition_class: ImportDistributionTransition)
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_csv_file_attributes
|
34
|
+
parsed = CSV.parse(csv_file.download)
|
35
|
+
|
36
|
+
update_columns(
|
37
|
+
headers: parsed[0],
|
38
|
+
row_count: parsed.size - 1,
|
39
|
+
content_type: csv_file.content_type.to_s,
|
40
|
+
filename: csv_file.filename.to_s,
|
41
|
+
extension: csv_file.filename.extension.to_s
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def run!
|
46
|
+
# @TODO: guard this call, unless mappings_valid?
|
47
|
+
|
48
|
+
# Queue Job
|
49
|
+
ImportDistributionsRunJob.perform_later(self)
|
50
|
+
|
51
|
+
# Capture State
|
52
|
+
state_machine.transition_to!(:imported)
|
53
|
+
save
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Import Distribution Statesman
|
4
|
+
class ImportDistributionStateMachine
|
5
|
+
include Statesman::Machine
|
6
|
+
|
7
|
+
state :created, initial: true
|
8
|
+
state :imported
|
9
|
+
state :success
|
10
|
+
state :failed
|
11
|
+
|
12
|
+
transition from: :created, to: [:imported]
|
13
|
+
transition from: :imported, to: %i[success failed]
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Add Import Distribution Statesman Transitions
|
4
|
+
class ImportDistributionTransition < ApplicationRecord
|
5
|
+
include Statesman::Adapters::ActiveRecordTransition
|
6
|
+
|
7
|
+
# If your transition table doesn't have the default `updated_at` timestamp column,
|
8
|
+
# you'll need to configure the `updated_timestamp_column` option, setting it to
|
9
|
+
# another column name (e.g. `:updated_on`) or `nil`.
|
10
|
+
#
|
11
|
+
# self.updated_timestamp_column = :updated_on
|
12
|
+
# self.updated_timestamp_column = nil
|
13
|
+
|
14
|
+
belongs_to :import_distribution, inverse_of: :import_distribution_transitions
|
15
|
+
|
16
|
+
after_destroy :update_most_recent, if: :most_recent?
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def update_most_recent
|
21
|
+
last_transition = import_distribution.import_distribution_transitions.order(:sort_key).last
|
22
|
+
return if last_transition.blank?
|
23
|
+
|
24
|
+
last_transition.update_column(:most_recent, true)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# ImportDocumentDistribution class
|
4
|
+
class ImportDocumentDistribution < ApplicationRecord
|
5
|
+
has_many :import_document_distribution_transitions, autosave: false, dependent: :destroy
|
6
|
+
|
7
|
+
include Statesman::Adapters::ActiveRecordQueries[
|
8
|
+
transition_class: ImportDocumentDistributionTransition,
|
9
|
+
initial_state: :queued
|
10
|
+
]
|
11
|
+
|
12
|
+
def state_machine
|
13
|
+
@state_machine ||= ImportDocumentDistributionStateMachine.new(self, transition_class: ImportDocumentDistributionTransition)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
{
|
18
|
+
friendlier_id: friendlier_id,
|
19
|
+
reference_type: ReferenceType.find_by(name: reference_type),
|
20
|
+
url: distribution_url,
|
21
|
+
label: label,
|
22
|
+
import_distribution_id: import_distribution_id
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# ImportDocumentDistribution Statesman
|
4
|
+
class ImportDocumentDistributionStateMachine
|
5
|
+
include Statesman::Machine
|
6
|
+
|
7
|
+
state :queued, initial: true
|
8
|
+
state :success
|
9
|
+
state :failed
|
10
|
+
|
11
|
+
transition from: :queued, to: %i[success failed]
|
12
|
+
transition from: :failed, to: :success
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Add ImportDocumentDistribution Statesman Transitions
|
4
|
+
class ImportDocumentDistributionTransition < ApplicationRecord
|
5
|
+
include Statesman::Adapters::ActiveRecordTransition
|
6
|
+
|
7
|
+
belongs_to :import_document_distribution, inverse_of: :import_document_distribution_transitions
|
8
|
+
|
9
|
+
after_destroy :update_most_recent, if: :most_recent?
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def update_most_recent
|
14
|
+
last_transition = import_document_distribution.import_document_distribution_transitions.order(:sort_key).last
|
15
|
+
return if last_transition.blank?
|
16
|
+
|
17
|
+
last_transition.update_column(:most_recent, true)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<div class="table-responsive">
|
2
|
+
<table class="table table-striped table-bordered sortable">
|
3
|
+
<thead class="thead-dark">
|
4
|
+
<tr>
|
5
|
+
<th>Name</th>
|
6
|
+
<th>Description</th>
|
7
|
+
<th>Staff Notes</th>
|
8
|
+
<th>Tags</th>
|
9
|
+
<th>Entries</th>
|
10
|
+
<th colspan="2">Actions</th>
|
11
|
+
</tr>
|
12
|
+
</thead>
|
13
|
+
<tbody>
|
14
|
+
<% document_data_dictionaries.each do |document_data_dictionary| %>
|
15
|
+
<tr>
|
16
|
+
<td><%= link_to(document_data_dictionary.name, admin_document_document_data_dictionary_path(document_data_dictionary.friendlier_id, document_data_dictionary)) %></td>
|
17
|
+
<td>
|
18
|
+
<%= document_data_dictionary.description %>
|
19
|
+
<span class="sr-only"><%= document_data_dictionary.inspect %></span>
|
20
|
+
</td>
|
21
|
+
<td>
|
22
|
+
<%= document_data_dictionary.staff_notes %>
|
23
|
+
</td>
|
24
|
+
<td>
|
25
|
+
<%= document_data_dictionary.tags %>
|
26
|
+
</td>
|
27
|
+
<td>
|
28
|
+
<%= link_to "#{document_data_dictionary.document_data_dictionary_entries.count} entries", admin_document_document_data_dictionary_path(document_data_dictionary.friendlier_id, document_data_dictionary) %>
|
29
|
+
</td>
|
30
|
+
<td>
|
31
|
+
<%= link_to 'Edit', edit_admin_document_document_data_dictionary_path(document_data_dictionary.friendlier_id, document_data_dictionary) %>
|
32
|
+
</td>
|
33
|
+
<td>
|
34
|
+
<%= link_to 'Destroy', admin_document_document_data_dictionary_path(document_data_dictionary.friendlier_id, document_data_dictionary), method: :delete, data: { confirm: 'Are you sure?' } %>
|
35
|
+
</td>
|
36
|
+
</tr>
|
37
|
+
<% end %>
|
38
|
+
</tbody>
|
39
|
+
</table>
|
40
|
+
</div>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<%- @page_title = "GBL♦Admin - Document - Data Dictionaries" %>
|
2
|
+
|
3
|
+
<div id="<%= dom_id document_data_dictionary %>">
|
4
|
+
<h2>
|
5
|
+
<%= document_data_dictionary.name %>
|
6
|
+
<%= link_to '~ Edit Data Dictionary', edit_admin_document_document_data_dictionary_path, { class: 'btn btn-primary float-right' } %>
|
7
|
+
</h2>
|
8
|
+
|
9
|
+
<table class="table table-bordered">
|
10
|
+
<thead class="thead-dark">
|
11
|
+
<tr>
|
12
|
+
<th class="header" style="width:300px;">Attribute</th>
|
13
|
+
<th class="header">Value</th>
|
14
|
+
</tr>
|
15
|
+
</thead>
|
16
|
+
<tr>
|
17
|
+
<th>Friendlier Id</th>
|
18
|
+
<td><%= document_data_dictionary.friendlier_id %></td>
|
19
|
+
</tr>
|
20
|
+
<tr>
|
21
|
+
<th>Name</th>
|
22
|
+
<td><%= document_data_dictionary.name %></td>
|
23
|
+
</tr>
|
24
|
+
<tr>
|
25
|
+
<th>Description</th>
|
26
|
+
<td><%= document_data_dictionary.description %></td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<th>Staff Notes</th>
|
30
|
+
<td><%= document_data_dictionary.staff_notes %></td>
|
31
|
+
</tr>
|
32
|
+
<tr>
|
33
|
+
<th>Tags</th>
|
34
|
+
<td><%= document_data_dictionary.tags %></td>
|
35
|
+
</tr>
|
36
|
+
</table>
|
37
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= simple_form_for([:admin, @document, @document_data_dictionary]) do |f| %>
|
2
|
+
<%= f.error_notification %>
|
3
|
+
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
|
4
|
+
|
5
|
+
<div class="form-inputs">
|
6
|
+
<%= f.input :friendlier_id, input_html: { value: @document.friendlier_id, readonly: true } %>
|
7
|
+
<%= f.input :name, input_html: { class: 'form-control', autofocus: true } %>
|
8
|
+
<%= f.input :description, input_html: { class: 'form-control' } %>
|
9
|
+
<%= f.input :staff_notes, input_html: { class: 'form-control' } %>
|
10
|
+
<%= f.input :tags, input_html: { class: "form-control mb-2", placeholder: "Comma-separated tags (Optional)", data: { controller: "taginput" } } %>
|
11
|
+
<%= f.file_field :csv_file, direct_upload: true %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div class="form-group mt-3">
|
15
|
+
<%= f.submit class: 'btn btn-primary' %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% content_for :title, "Editing document data dictionary" %>
|
2
|
+
|
3
|
+
<h1>Editing document data dictionary</h1>
|
4
|
+
|
5
|
+
<%= render "form", document_data_dictionary: @document_data_dictionary %>
|
6
|
+
|
7
|
+
<br>
|
8
|
+
|
9
|
+
<div>
|
10
|
+
<%= link_to "Show this document data dictionary", admin_document_document_data_dictionary_path(@document, @document_data_dictionary) %> |
|
11
|
+
<%= link_to "Back to document data dictionaries", admin_document_document_data_dictionaries_path(@document) %>
|
12
|
+
</div>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<%- @page_title = "GBL♦Admin - Document - Data Dictionaries" %>
|
2
|
+
|
3
|
+
<div class="row mb-2">
|
4
|
+
<div class="col">
|
5
|
+
<h1 style="width:100%;">
|
6
|
+
Document · Data Dictionaries
|
7
|
+
|
8
|
+
<%= link_to '+ New Data Dictionary', new_admin_document_document_data_dictionary_path, { class: 'btn btn-primary float-right' } %>
|
9
|
+
</h1>
|
10
|
+
<% if params[:document_id] %>
|
11
|
+
<h2 class='h3'>
|
12
|
+
<%= link_to(@document.title, admin_document_path(@document)) %>
|
13
|
+
·
|
14
|
+
<%= @document_data_dictionaries.count %> data dictionaries
|
15
|
+
</h2>
|
16
|
+
<% else %>
|
17
|
+
<h2 class='h3'>Data Dictionaries</h2>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<% if @pagy %>
|
21
|
+
<h6>
|
22
|
+
<span class='float-left mt-3'>
|
23
|
+
<%== pagy_info(@pagy, 'data dictionaries'.pluralize(@pagy.count)) %>
|
24
|
+
</span>
|
25
|
+
<span class='float-right'>
|
26
|
+
<%== pagy_bootstrap_nav(@pagy) %>
|
27
|
+
</span>
|
28
|
+
</h6>
|
29
|
+
<% end %>
|
30
|
+
|
31
|
+
<%= render partial: 'data_dictionaries_table', locals: { document_data_dictionaries: @document_data_dictionaries } %>
|
32
|
+
|
33
|
+
<% if @pagy %>
|
34
|
+
<h6>
|
35
|
+
<span class='float-left mt-3'>
|
36
|
+
<%== pagy_info(@pagy, 'data dictionaries'.pluralize(@pagy.count)) %>
|
37
|
+
</span>
|
38
|
+
<span class='float-right'>
|
39
|
+
<%== pagy_bootstrap_nav(@pagy) %>
|
40
|
+
</span>
|
41
|
+
</h6>
|
42
|
+
<% end %>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
json.array! @document_data_dictionaries, partial: "document_data_dictionaries/document_data_dictionary", as: :document_data_dictionary
|
@@ -0,0 +1,78 @@
|
|
1
|
+
<div class="row mb-2">
|
2
|
+
<div class="col">
|
3
|
+
<%= link_to "Back to document data dictionaries", admin_document_document_data_dictionaries_path(@document) %>
|
4
|
+
|
5
|
+
<h1 style="width:100%;">
|
6
|
+
<%= @document.title %> · New Data Dictionary
|
7
|
+
</h1>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="row">
|
12
|
+
<div class="col-5">
|
13
|
+
<%= render "form", document_data_dictionary: @document_data_dictionary %>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div class="col-6">
|
17
|
+
<h4>Example Data Dictionary CSV File</h4>
|
18
|
+
<table class="table table-bordered">
|
19
|
+
<thead>
|
20
|
+
<tr>
|
21
|
+
<th>friendlier_id*</th>
|
22
|
+
<th>field_name*</th>
|
23
|
+
<th>field_type*</th>
|
24
|
+
<th>values*</th>
|
25
|
+
<th>definition</th>
|
26
|
+
<th>definition_source</th>
|
27
|
+
<th>parent_field_name</th>
|
28
|
+
</tr>
|
29
|
+
</thead>
|
30
|
+
<tbody>
|
31
|
+
<tr>
|
32
|
+
<td>999-0010a</td>
|
33
|
+
<td>Institution</td>
|
34
|
+
<td>string</td>
|
35
|
+
<td>University of Minnesota</td>
|
36
|
+
<td>The name of the institution</td>
|
37
|
+
<td>https://www.umn.edu</td>
|
38
|
+
<td>999-0010UMN</td>
|
39
|
+
</tr>
|
40
|
+
<tr>
|
41
|
+
<td>999-0010a</td>
|
42
|
+
<td>Institution</td>
|
43
|
+
<td>string</td>
|
44
|
+
<td>University of Minnesota Duluth</td>
|
45
|
+
<td>The name of the institution</td>
|
46
|
+
<td>https://www.d.umn.edu</td>
|
47
|
+
<td>999-0010UMN</td>
|
48
|
+
</tr>
|
49
|
+
<tr>
|
50
|
+
<td>...</td>
|
51
|
+
<td>...</td>
|
52
|
+
<td>...</td>
|
53
|
+
<td>...</td>
|
54
|
+
<td>...</td>
|
55
|
+
<td>...</td>
|
56
|
+
</tr>
|
57
|
+
</tbody>
|
58
|
+
</table>
|
59
|
+
|
60
|
+
<h5>CSV File Column Definitions</h5>
|
61
|
+
<dl>
|
62
|
+
<dt>friendlier_id</dt>
|
63
|
+
<dd>The associated document's friendlier id</dd>
|
64
|
+
<dt>field_name</dt>
|
65
|
+
<dd>The name of the field</dd>
|
66
|
+
<dt>field_type</dt>
|
67
|
+
<dd>The type of the field</dd>
|
68
|
+
<dt>values</dt>
|
69
|
+
<dd>The values of the field</dd>
|
70
|
+
<dt>definition</dt>
|
71
|
+
<dd>The definition of the field</dd>
|
72
|
+
<dt>definition_source</dt>
|
73
|
+
<dd>The source of the definition</dd>
|
74
|
+
<dt>parent_field_name</dt>
|
75
|
+
<dd>The parent field's name</dd>
|
76
|
+
</dl>
|
77
|
+
</div>
|
78
|
+
</div>
|
@@ -0,0 +1,78 @@
|
|
1
|
+
<%- @page_title = "GBL♦Admin - Document - Data Dictionaries" %>
|
2
|
+
|
3
|
+
<div class="row mb-2">
|
4
|
+
<div class="col">
|
5
|
+
<%= link_to "Back to document data dictionaries", admin_document_document_data_dictionaries_path(@document) %>
|
6
|
+
|
7
|
+
<h1 style="width:100%;">
|
8
|
+
<%= @document.title %> · Data Dictionaries · <%= @document_data_dictionary.name %>
|
9
|
+
|
10
|
+
<%= link_to '+ New Entry', new_admin_document_document_data_dictionary_document_data_dictionary_entry_path(@document, @document_data_dictionary), { class: 'btn btn-primary float-right' } %>
|
11
|
+
</h1>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div class="row">
|
16
|
+
<div class="col-12">
|
17
|
+
<h6>
|
18
|
+
<span class='float-left mt-3'>
|
19
|
+
<%== pagy_info(@pagy) %>
|
20
|
+
</span>
|
21
|
+
<span class='float-right'>
|
22
|
+
<%== pagy_bootstrap_nav(@pagy) %>
|
23
|
+
</span>
|
24
|
+
</h6>
|
25
|
+
|
26
|
+
<div class="table-responsive">
|
27
|
+
<table class="table table-striped table-bordered sortable">
|
28
|
+
<thead class="thead-dark">
|
29
|
+
<tr>
|
30
|
+
<th class="header">field_name</th>
|
31
|
+
<th class="header">field_type</th>
|
32
|
+
<th class="header">values</th>
|
33
|
+
<th class="header">definition</th>
|
34
|
+
<th class="header">definition_source</th>
|
35
|
+
<th class="header">parent_field_name</th>
|
36
|
+
<th class="header">Reorder</th>
|
37
|
+
<th class="header" colspan="2">Actions</th>
|
38
|
+
</tr>
|
39
|
+
</thead>
|
40
|
+
<tbody>
|
41
|
+
<% @document_data_dictionary.document_data_dictionary_entries.each do |entry| %>
|
42
|
+
<tr data-id="<%=entry.id%>">
|
43
|
+
<td><%= entry.field_name %></td>
|
44
|
+
<td><%= entry.field_type %></td>
|
45
|
+
<td><%= entry.values %></td>
|
46
|
+
<td><%= entry.definition %></td>
|
47
|
+
<td><%= entry.definition_source %></td>
|
48
|
+
<td><%= entry.parent_field_name %></td>
|
49
|
+
<td class="handle" style="text-align:center">↕</td>
|
50
|
+
<td>
|
51
|
+
<%= link_to 'Edit', edit_admin_document_document_data_dictionary_document_data_dictionary_entry_path(@document, @document_data_dictionary, entry.id) %>
|
52
|
+
</td>
|
53
|
+
<td>
|
54
|
+
<%= link_to 'Destroy', admin_document_document_data_dictionary_document_data_dictionary_entry_path(@document, @document_data_dictionary, entry.id), method: :delete, data: { confirm: 'Are you sure?' } %>
|
55
|
+
</td>
|
56
|
+
</tr>
|
57
|
+
<% end %>
|
58
|
+
</tbody>
|
59
|
+
</table>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<h6>
|
63
|
+
<span class='float-left mt-3'>
|
64
|
+
<%== pagy_info(@pagy) %>
|
65
|
+
</span>
|
66
|
+
<span class='float-right'>
|
67
|
+
<%== pagy_bootstrap_nav(@pagy) %>
|
68
|
+
</span>
|
69
|
+
</h6>
|
70
|
+
</div>
|
71
|
+
</div>
|
72
|
+
|
73
|
+
<script>
|
74
|
+
GBLADMIN.SortElements(
|
75
|
+
$("tbody"),
|
76
|
+
"<%= sort_admin_document_document_data_dictionary_document_data_dictionary_entries_path(@document, @document_data_dictionary) %>"
|
77
|
+
);
|
78
|
+
</script>
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! "document_data_dictionaries/document_data_dictionary", document_data_dictionary: @document_data_dictionary
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%= simple_form_for([:admin, @document, @document_data_dictionary, @document_data_dictionary_entry]) do |f| %>
|
2
|
+
<%= f.error_notification %>
|
3
|
+
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
|
4
|
+
|
5
|
+
<div class="form-inputs">
|
6
|
+
<%= f.input :friendlier_id, input_html: { value: @document.friendlier_id, readonly: true } %>
|
7
|
+
<%= f.input :document_data_dictionary_id, as: :hidden, input_html: { value: @document_data_dictionary.id } %>
|
8
|
+
<%= f.input :field_name, input_html: { class: 'form-control', autofocus: true } %>
|
9
|
+
<%= f.input :field_type, input_html: { class: 'form-control' } %>
|
10
|
+
<%= f.input :values, input_html: { class: 'form-control' } %>
|
11
|
+
<%= f.input :definition, input_html: { class: 'form-control' } %>
|
12
|
+
<%= f.input :definition_source, input_html: { class: 'form-control' } %>
|
13
|
+
<%= f.input :parent_field_name, input_html: { class: 'form-control' } %>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div class="form-group">
|
17
|
+
<%= f.submit class: 'btn btn-primary' %>
|
18
|
+
</div>
|
19
|
+
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% content_for :title, "Editing document data dictionary entry" %>
|
2
|
+
|
3
|
+
<h1>Editing document data dictionary entry</h1>
|
4
|
+
|
5
|
+
<%= render "form", document_data_dictionary_entry: @document_data_dictionary_entry %>
|
6
|
+
|
7
|
+
<br>
|
8
|
+
|
9
|
+
<div>
|
10
|
+
<%= link_to "Show this document data dictionary entry", admin_document_document_data_dictionary_document_data_dictionary_entry_path(@document, @document_data_dictionary, @document_data_dictionary_entry) %> |
|
11
|
+
<%= link_to "Back to document data dictionary entries", admin_document_document_data_dictionary_document_data_dictionary_entries_path(@document, @document_data_dictionary) %>
|
12
|
+
</div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="row mb-2">
|
2
|
+
<div class="col">
|
3
|
+
<%= link_to "Back to document data dictionaries", admin_document_document_data_dictionaries_path(@document) %>
|
4
|
+
|
5
|
+
<h1 style="width:100%;">
|
6
|
+
<%= @document.title %> · New Data Dictionary Entry
|
7
|
+
</h1>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="row">
|
12
|
+
<div class="col-5">
|
13
|
+
<%= render "form", document_data_dictionary_entry: @document_data_dictionary_entry %>
|
14
|
+
|
15
|
+
<%= link_to "Back to document data dictionary entries", admin_document_document_data_dictionary_document_data_dictionary_entries_path(@document, @document_data_dictionary) %>
|
16
|
+
</div>
|
@@ -6,12 +6,12 @@
|
|
6
6
|
Document · Distributions
|
7
7
|
|
8
8
|
<% if params[:document_id] %>
|
9
|
-
<%= link_to '+ Import CSV',
|
9
|
+
<%= link_to '+ Import CSV', new_admin_import_distribution_path, { class: 'btn btn-primary float-right' } %>
|
10
10
|
|
11
11
|
<%= link_to '+ New Distribution', new_admin_document_document_distribution_path(@document), { class: 'btn btn-primary float-right mr-2' } %>
|
12
12
|
<% else %>
|
13
13
|
<%= link_to '- Delete CSV', destroy_all_admin_document_distributions_path, { class: 'btn btn-danger float-right' } %>
|
14
|
-
<%= link_to '+ Import CSV',
|
14
|
+
<%= link_to '+ Import CSV', new_admin_import_distribution_path, { class: 'btn btn-primary float-right mr-4' } %>
|
15
15
|
<% end %>
|
16
16
|
</h1>
|
17
17
|
|
@@ -32,6 +32,10 @@
|
|
32
32
|
Additional Assets
|
33
33
|
<span class="badge badge-light"><%= @document.document_assets.count %></span>
|
34
34
|
<% end %>
|
35
|
+
<%= link_to admin_document_document_data_dictionaries_url(@document), class: "ml-2" do %>
|
36
|
+
Data Dictionaries
|
37
|
+
<span class="badge badge-light"><%= @document.document_data_dictionaries.count %></span>
|
38
|
+
<% end %>
|
35
39
|
<%= link_to admin_document_document_distributions_url(@document), class: "ml-2" do %>
|
36
40
|
Distributions
|
37
41
|
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<% if @import_distribution.errors.any? %>
|
2
|
+
<div class="alert alert-danger mb-4" role="alert">
|
3
|
+
<h2 class="h4" class="alert-heading"><%= pluralize(@import_distribution.errors.count, "error") %> prohibited this import distribution from being saved</h2>
|
4
|
+
<ol class="mb-0">
|
5
|
+
<% @import_distribution.errors.full_messages.each do |msg| %>
|
6
|
+
<li><%= msg %></li>
|
7
|
+
<% end %>
|
8
|
+
</ol>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<div class="form-inputs">
|
13
|
+
<%= f.input :name, {autofocus: true} %>
|
14
|
+
<%= f.input :source %>
|
15
|
+
<%= f.input :description %>
|
16
|
+
<%= f.file_field :csv_file, direct_upload: true %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="form-actions">
|
20
|
+
<%= f.button :submit, "+ Create Import Distributions", {class: 'btn btn-primary'} %>
|
21
|
+
</div>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
json.extract! import_distribution, :id, :name, :filename, :source, :description, :row_count, :headers, :encoding, :content_type,
|
4
|
+
:extension, :validity, :validation_result, :created_at, :updated_at
|
5
|
+
json.url import_distribution_url(import_distribution, format: :json)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<h6>
|
2
|
+
<span class='float-left mt-3'>
|
3
|
+
<%== pagy_info(@pagy_failed) %>
|
4
|
+
</span>
|
5
|
+
<span class='float-right'>
|
6
|
+
<%== pagy_bootstrap_nav(@pagy_failed) %>
|
7
|
+
</span>
|
8
|
+
</h6>
|
9
|
+
|
10
|
+
<table class="table table-striped">
|
11
|
+
<thead>
|
12
|
+
<tr>
|
13
|
+
<th>State</th>
|
14
|
+
<th>Title</th>
|
15
|
+
<th>Identifier</th>
|
16
|
+
<th>Reason</th>
|
17
|
+
</tr>
|
18
|
+
</thead>
|
19
|
+
<tbody>
|
20
|
+
<% @import_failed_distributions.each_with_index do |distribution, index| %>
|
21
|
+
<tr>
|
22
|
+
<td>
|
23
|
+
<span class="badge badge-danger">
|
24
|
+
<%= distribution.state_machine.current_state %>
|
25
|
+
</span>
|
26
|
+
</td>
|
27
|
+
<td><%= distribution.friendlier_id %></td>
|
28
|
+
<td>
|
29
|
+
<%= link_to admin_import_distribution_path(@import_distribution, distribution) do %>
|
30
|
+
<%= distribution.state_machine&.last_transition&.metadata %>
|
31
|
+
<% end %>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
<% end %>
|
35
|
+
</tbody>
|
36
|
+
</table>
|