works_cited 0.1.11 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +8 -8
- data/Gemfile.lock +9 -10
- data/README.md +27 -2
- data/VERSION +1 -1
- data/app/assets/javascripts/works_cited/addFields.js +44 -0
- data/app/assets/javascripts/works_cited/application.js +6 -1
- data/app/assets/javascripts/works_cited/loadPreview.js +45 -0
- data/app/assets/javascripts/works_cited/removeFields.js +37 -0
- data/app/assets/javascripts/works_cited/shared.js +59 -0
- data/app/assets/javascripts/works_cited/showFields.js +9 -0
- data/app/assets/javascripts/works_cited/submitForm.js +33 -0
- data/app/controllers/concerns/works_cited/params.rb +24 -0
- data/app/controllers/works_cited/citations_controller.rb +26 -13
- data/app/helpers/works_cited/application_helper.rb +46 -1
- data/app/models/works_cited/citation.rb +31 -31
- data/app/models/works_cited/contributor.rb +11 -28
- data/app/views/works_cited/citation_types/fields/_book.html.haml +1 -1
- data/app/views/works_cited/citation_types/fields/_electronic.html.haml +1 -1
- data/app/views/works_cited/citation_types/fields/_email.html.haml +1 -1
- data/app/views/works_cited/citation_types/fields/_interview.html.haml +1 -1
- data/app/views/works_cited/citation_types/fields/_periodical.html.haml +1 -1
- data/app/views/works_cited/citation_types/fields/_tweet.html.haml +1 -1
- data/app/views/works_cited/citations/_citation_fields.html.haml +28 -0
- data/app/views/works_cited/citations/_fields.html.haml +14 -0
- data/app/views/works_cited/citations/_form.html.haml +16 -53
- data/app/views/works_cited/citations/preview.html.haml +1 -1
- data/app/views/works_cited/contributors/_contributor_fields.html.haml +11 -0
- data/config/routes.rb +8 -2
- data/db/migrate/20210915160902_add_index_to_works_cited_contributors.rb +9 -0
- data/lib/works_cited/mixins/has_works_cited.rb +14 -1
- data/spec/dummy/app/controllers/doodads_controller.rb +2 -1
- data/spec/dummy/app/controllers/things_controller.rb +1 -1
- data/spec/dummy/app/views/doodads/_form.html.haml +2 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/{20210902202653_create_works_cited_citations.works_cited.rb → 20210915161011_create_works_cited_citations.works_cited.rb} +0 -0
- data/spec/dummy/db/migrate/{20210902202654_create_works_cited_contributors.works_cited.rb → 20210915161012_create_works_cited_contributors.works_cited.rb} +0 -0
- data/spec/dummy/db/migrate/20210915161013_add_index_to_works_cited_contributors.works_cited.rb +9 -0
- data/spec/dummy/db/schema.rb +2 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +27312 -15
- data/spec/dummy/log/test.log +29188 -0
- data/spec/factories/things.rb +8 -0
- data/spec/models/doodad_spec.rb +13 -1
- data/spec/models/thing_spec.rb +13 -1
- data/spec/models/works_cited/citation_spec.rb +12 -0
- data/spec/requests/works_cited/citations_spec.rb +10 -8
- data/spec/routing/works_cited/citations_routing_spec.rb +5 -1
- data/works_cited.gemspec +28 -16
- metadata +51 -15
- data/app/views/works_cited/contributors/_fields.html.haml +0 -9
@@ -57,28 +57,25 @@ module WorksCited
|
|
57
57
|
|
58
58
|
def name_parts
|
59
59
|
parts = []
|
60
|
-
parts << first_name_or_initial
|
61
|
-
parts << middle_initial
|
62
|
-
parts <<
|
63
|
-
"#{last}, #{suffix}"
|
64
|
-
else
|
65
|
-
suffix.presence || last.presence
|
66
|
-
end
|
60
|
+
parts << first_name_or_initial.presence
|
61
|
+
parts << middle_initial.presence
|
62
|
+
parts << [last.presence, suffix.presence].compact.join(', ').presence
|
67
63
|
parts
|
68
64
|
end
|
69
65
|
|
70
66
|
def name_parts_reversed
|
71
67
|
parts = []
|
72
|
-
parts <<
|
73
|
-
parts << first_name_or_initial
|
74
|
-
parts << if suffix.present? && middle_initial.present?
|
75
|
-
"#{middle_initial}, #{suffix}"
|
76
|
-
else
|
77
|
-
suffix.presence || middle_initial
|
78
|
-
end
|
68
|
+
parts << [last.presence, name_other_parts.presence].compact.join(', ').presence
|
79
69
|
parts
|
80
70
|
end
|
81
71
|
|
72
|
+
def name_other_parts
|
73
|
+
other_parts = []
|
74
|
+
other_parts << first_name_or_initial.presence
|
75
|
+
other_parts << [middle_initial.presence, suffix.presence].compact.join(', ').presence
|
76
|
+
other_parts.compact.join(' ').presence
|
77
|
+
end
|
78
|
+
|
82
79
|
def first_name_or_initial
|
83
80
|
return nil unless first.present?
|
84
81
|
|
@@ -90,19 +87,5 @@ module WorksCited
|
|
90
87
|
|
91
88
|
middle[0, 1]&.upcase
|
92
89
|
end
|
93
|
-
|
94
|
-
if defined?(RailsAdmin)
|
95
|
-
rails_admin do
|
96
|
-
visible false
|
97
|
-
edit do
|
98
|
-
field :contributor_role, :enum do
|
99
|
-
enum do
|
100
|
-
WorksCited.configuration.valid_contributor_roles
|
101
|
-
end
|
102
|
-
end
|
103
|
-
include_all_fields
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
90
|
end
|
108
91
|
end
|
@@ -10,5 +10,5 @@
|
|
10
10
|
= f.input :pages, hint: 'like "pp. 150-53"'
|
11
11
|
= f.input :online_database
|
12
12
|
= f.input :doi, label: 'Digital Object Identifier'
|
13
|
-
= f.input :url
|
13
|
+
= f.input :url, as: :string
|
14
14
|
= f.input :accessed_at, as: :string, hint: 'Will be parsed and formatted', input_html: { value: f.object.accessed_at&.mla_date }
|
@@ -1,4 +1,4 @@
|
|
1
1
|
= f.input :title, label: 'Tweet text'
|
2
2
|
= f.input :publisher, default: 'Twitter'
|
3
3
|
= f.input :published_at, label: 'Time posted', as: :string, hint: 'Will be parsed and formatted', input_html: { value: f.object.published_at&.mla_datetime }
|
4
|
-
= f.input :url
|
4
|
+
= f.input :url, as: :string
|
@@ -0,0 +1,28 @@
|
|
1
|
+
:ruby
|
2
|
+
preview_path = f.object.new_record? ? works_cited.preview_citation_url : works_cited.preview_citation_url(f.object.id)
|
3
|
+
%fieldset.nested-fields{id: "citation-#{f.index}"}
|
4
|
+
%legend
|
5
|
+
%h4 Citation
|
6
|
+
= f.hidden_field :_destroy
|
7
|
+
= f.hidden_field :record, value: "#{f.object.record_type}:#{f.object.record_id}"
|
8
|
+
= f.input :citation_type, as: :select, collection: WorksCited.configuration.valid_citation_types, :input_html => {:onchange => "showFields('#{citation_id}', this.options[this.selectedIndex].value);"}
|
9
|
+
- WorksCited.configuration.valid_citation_types.each do |citation_type|
|
10
|
+
.fields{ class: "fields-#{citation_type}", style: 'display: none;' }
|
11
|
+
= works_cited_type_fields f, citation_type
|
12
|
+
%fieldset.works_cited_contributors
|
13
|
+
%legend
|
14
|
+
%h3 Contributors
|
15
|
+
%div#works_cited_contributors
|
16
|
+
= f.simple_fields_for :works_cited_contributors do |g|
|
17
|
+
= render 'works_cited/contributors/contributor_fields', f: g
|
18
|
+
= works_cited_link_to_add_fields 'Add Contributor', f, :works_cited_contributors, 'works_cited/contributors/contributor_fields'
|
19
|
+
%fieldset#preview{ style: 'display: none;' }
|
20
|
+
%legend
|
21
|
+
%h2
|
22
|
+
Preview
|
23
|
+
%small (Real-time)
|
24
|
+
.preview-html#preview-html
|
25
|
+
= link_to "Remove", '#', class: 'remove_fields button button-danger'
|
26
|
+
:javascript
|
27
|
+
showFields('#{f.index}', '#{f.object.citation_type || 'book'}')
|
28
|
+
startPreview('#{preview_path}', 'citation-#{f.index}', '#{record.class.table_name.singularize}[works_cited_citations_attributes][#{f.index}]')
|
@@ -0,0 +1,14 @@
|
|
1
|
+
- if cannot?(:manage, WorksCited::Citation)
|
2
|
+
Not authorized for citations.
|
3
|
+
- else
|
4
|
+
= stylesheet_link_tag 'works_cited/application'
|
5
|
+
= javascript_include_tag 'works_cited/application'
|
6
|
+
%fieldset.citations
|
7
|
+
%legend
|
8
|
+
%h3 Works Cited
|
9
|
+
%div#citations
|
10
|
+
= form.simple_fields_for :works_cited_citations do |g|
|
11
|
+
= render 'works_cited/citations/citation_fields', f: g, record: form.object
|
12
|
+
= works_cited_link_to_add_fields "Add Citation", form, :works_cited_citations, 'works_cited/citations/citation_fields'
|
13
|
+
:javascript
|
14
|
+
addFilterToSubmit()
|
@@ -1,6 +1,9 @@
|
|
1
|
+
:ruby
|
2
|
+
preview_path = @citation.new_record? ? works_cited.preview_citations_url : works_cited.preview_citation_url(@citation.id)
|
3
|
+
citation_id = @citation.new_record? ? 'new' : @citation.id
|
1
4
|
= stylesheet_link_tag 'works_cited/application'
|
2
5
|
= javascript_include_tag 'works_cited/application'
|
3
|
-
= simple_form_for @citation, html: { id:
|
6
|
+
= simple_form_for @citation, html: { id: "citation-#{citation_id}"} do |f|
|
4
7
|
- if @citation.errors.any?
|
5
8
|
#error_explanation
|
6
9
|
%h2= "#{pluralize(@citation.errors.count, "error")} prohibited this citation from being saved:"
|
@@ -10,17 +13,17 @@
|
|
10
13
|
.shared-field
|
11
14
|
= f.hidden_field :id
|
12
15
|
= f.input :record, collection: @records, as: :grouped_select, group_method: :records, group_label_method: :record_type, label_method: :name, value_method: :id, selected: "#{@citation.record_type}:#{@citation.record_id}", include_blank: 'Select a Record'
|
13
|
-
= f.input :citation_type, as: :select, collection: WorksCited.configuration.valid_citation_types, :input_html => {:onchange => "showFields(this.options[this.selectedIndex].value);"}
|
16
|
+
= f.input :citation_type, as: :select, collection: WorksCited.configuration.valid_citation_types, :input_html => {:onchange => "showFields('#{citation_id}', this.options[this.selectedIndex].value);"}
|
14
17
|
- WorksCited.configuration.valid_citation_types.each do |citation_type|
|
15
|
-
.fields{
|
16
|
-
=
|
17
|
-
%fieldset
|
18
|
+
.fields{ class: "fields-#{citation_type}", style: 'display: none;' }
|
19
|
+
= works_cited_type_fields f, citation_type
|
20
|
+
%fieldset.works_cited_contributors
|
18
21
|
%legend
|
19
|
-
%
|
20
|
-
|
21
|
-
=
|
22
|
-
|
23
|
-
|
22
|
+
%h3 Contributors
|
23
|
+
%div#works_cited_contributors
|
24
|
+
= f.simple_fields_for :works_cited_contributors do |g|
|
25
|
+
= render 'works_cited/contributors/contributor_fields', f: g
|
26
|
+
= works_cited_link_to_add_fields 'Add Contributor', f, :works_cited_contributors, 'works_cited/contributors/contributor_fields'
|
24
27
|
%fieldset#preview{ style: 'display: none;' }
|
25
28
|
%legend
|
26
29
|
%h2
|
@@ -30,46 +33,6 @@
|
|
30
33
|
.actions
|
31
34
|
.button-wrapper= f.submit 'Save', class: 'button-large button-action'
|
32
35
|
:javascript
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
for (index = 0; index < fields.length; ++index) {
|
37
|
-
var textField = fields[index];
|
38
|
-
textField.addEventListener('change', loadPreview)
|
39
|
-
}
|
40
|
-
|
41
|
-
function loadPreview() {
|
42
|
-
// Build formData object.
|
43
|
-
var formData = new FormData(document.querySelector('form'))
|
44
|
-
var authenticity_token = document.head.querySelector('meta[name="csrf-token"]').content
|
45
|
-
var preview = document.getElementById('preview')
|
46
|
-
var container = document.getElementById('preview-html')
|
47
|
-
|
48
|
-
fetch('#{preview_citation_url}',
|
49
|
-
{
|
50
|
-
method: 'post',
|
51
|
-
headers: {
|
52
|
-
'X-Requested-With': 'XMLHttpRequest',
|
53
|
-
'X-CSRF-Token': authenticity_token
|
54
|
-
},
|
55
|
-
body: formData,
|
56
|
-
credentials: 'same-origin'
|
57
|
-
})
|
58
|
-
.then(function(response) {
|
59
|
-
// When the page is loaded convert it to text
|
60
|
-
return response.text()
|
61
|
-
})
|
62
|
-
.then((html) => {
|
63
|
-
preview.style.display = 'block'
|
64
|
-
container.innerHTML = html
|
65
|
-
})
|
66
|
-
}
|
67
|
-
function showFields(citation_type) {
|
68
|
-
for (let element of document.getElementsByClassName('fields')){
|
69
|
-
element.style.display='none'
|
70
|
-
}
|
71
|
-
document.getElementById(`fields-${citation_type}`).style.display = 'block'
|
72
|
-
}
|
73
|
-
|
74
|
-
showFields('#{@citation.citation_type || 'book'}')
|
75
|
-
loadPreview()
|
36
|
+
showFields('#{citation_id}', '#{@citation.citation_type || 'book'}')
|
37
|
+
startPreview('#{preview_path}', 'citation-#{citation_id}', 'citation')
|
38
|
+
addFilterToSubmit()
|
@@ -1 +1 @@
|
|
1
|
-
= works_cited_preview
|
1
|
+
= works_cited_preview citation, contributors
|
@@ -0,0 +1,11 @@
|
|
1
|
+
%fieldset.nested-fields
|
2
|
+
%legend
|
3
|
+
%h4 Contributor
|
4
|
+
= f.hidden_field :_destroy
|
5
|
+
= f.input :contributor_role, collection: WorksCited.configuration.valid_contributor_roles.map { |x| [x, x] }
|
6
|
+
= f.input :first
|
7
|
+
= f.input :middle, hint: 'Only the initial is used'
|
8
|
+
= f.input :last
|
9
|
+
= f.input :suffix
|
10
|
+
= f.input :handle
|
11
|
+
= link_to "Remove", '#', class: 'remove_fields button button-danger'
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
WorksCited::Engine.routes.draw do
|
4
|
-
|
5
|
-
|
4
|
+
resources :citations do
|
5
|
+
member do
|
6
|
+
post 'preview', defaults: { format: :json }
|
7
|
+
end
|
8
|
+
collection do
|
9
|
+
post 'preview', defaults: { format: :json }
|
10
|
+
end
|
11
|
+
end
|
6
12
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Contributors need to be indexed on their name
|
4
|
+
class AddIndexToWorksCitedContributors < ActiveRecord::Migration[6.1]
|
5
|
+
def change
|
6
|
+
add_index :works_cited_contributors, %i[last first middle suffix handle], name: :index_citation_name,
|
7
|
+
length: 100
|
8
|
+
end
|
9
|
+
end
|
@@ -12,7 +12,7 @@ module WorksCited
|
|
12
12
|
include InstanceMethods
|
13
13
|
|
14
14
|
has_many :works_cited_citations, as: :record, class_name: 'WorksCited::Citation'
|
15
|
-
accepts_nested_attributes_for :works_cited_citations, allow_destroy: true
|
15
|
+
accepts_nested_attributes_for :works_cited_citations, reject_if: :all_blank, allow_destroy: true
|
16
16
|
end
|
17
17
|
# rubocop:enable Naming/PredicateName
|
18
18
|
|
@@ -22,6 +22,19 @@ module WorksCited
|
|
22
22
|
|
23
23
|
# Included by has_works_cited mixin
|
24
24
|
module InstanceMethods
|
25
|
+
def works_cited_citations_attributes=(raw_citations)
|
26
|
+
array = []
|
27
|
+
raw_citations&.each do |_index, citation|
|
28
|
+
destroy = citation.delete(:_destroy)
|
29
|
+
if destroy == '1'
|
30
|
+
Citation.find(citation[:id]).destroy if citation[:id]
|
31
|
+
next
|
32
|
+
end
|
33
|
+
|
34
|
+
array << citation
|
35
|
+
end
|
36
|
+
super array
|
37
|
+
end
|
25
38
|
end
|
26
39
|
end
|
27
40
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# :nocov:
|
4
4
|
# Super basic controller for Doodads
|
5
5
|
class DoodadsController < ApplicationController
|
6
|
+
include WorksCited::Params
|
6
7
|
before_action :set_doodad, only: %i[show edit update destroy]
|
7
8
|
|
8
9
|
# GET /doodads
|
@@ -56,7 +57,7 @@ class DoodadsController < ApplicationController
|
|
56
57
|
|
57
58
|
# Only allow a list of trusted parameters through.
|
58
59
|
def doodad_params
|
59
|
-
params.require(:doodad).permit(:name, :description)
|
60
|
+
params.require(:doodad).permit(:name, :description, works_cited_params)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
# :nocov:
|
@@ -56,7 +56,7 @@ class ThingsController < ApplicationController
|
|
56
56
|
|
57
57
|
# Only allow a list of trusted parameters through.
|
58
58
|
def thing_params
|
59
|
-
params.require(:thing).permit(:name, :description)
|
59
|
+
params.require(:thing).permit(:name, :description, works_cited_params)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
# :nocov:
|
Binary file
|
File without changes
|
File without changes
|
data/spec/dummy/db/migrate/20210915161013_add_index_to_works_cited_contributors.works_cited.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This migration comes from works_cited (originally 20210915160902)
|
4
|
+
class AddIndexToWorksCitedContributors < ActiveRecord::Migration[6.1]
|
5
|
+
def change
|
6
|
+
add_index :works_cited_contributors, %i[last first middle suffix handle], name: :index_citation_name,
|
7
|
+
length: 100
|
8
|
+
end
|
9
|
+
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
#
|
13
13
|
# It's strongly recommended that you check this file into your version control system.
|
14
14
|
|
15
|
-
ActiveRecord::Schema.define(version:
|
15
|
+
ActiveRecord::Schema.define(version: 20_210_915_161_013) do
|
16
16
|
create_table 'doodads', force: :cascade do |t|
|
17
17
|
t.string 'name'
|
18
18
|
t.text 'description'
|
@@ -75,6 +75,7 @@ ActiveRecord::Schema.define(version: 20_210_907_170_207) do
|
|
75
75
|
t.string 'handle'
|
76
76
|
t.datetime 'created_at', precision: 6, null: false
|
77
77
|
t.datetime 'updated_at', precision: 6, null: false
|
78
|
+
t.index %w[last first middle suffix handle], name: 'index_citation_name'
|
78
79
|
t.index ['works_cited_citation_id'], name: 'index_works_cited_contributors_on_works_cited_citation_id'
|
79
80
|
end
|
80
81
|
|
data/spec/dummy/db/test.sqlite3
CHANGED
Binary file
|