spina-admin-journal 0.6.1 → 1.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -48
  3. data/app/assets/config/spina_admin_journal_manifest.js +1 -2
  4. data/app/assets/javascripts/spina/admin/journal/application.js +0 -0
  5. data/app/components/spina/admin/journal/affiliations_list_component.rb +32 -0
  6. data/app/components/spina/admin/journal/application_component.rb +11 -0
  7. data/app/components/spina/admin/journal/articles_list_component.rb +54 -0
  8. data/app/components/spina/admin/journal/authors_list_component.rb +37 -0
  9. data/app/components/spina/admin/journal/authorships_list_component.rb +45 -0
  10. data/app/components/spina/admin/journal/empty_list_component.html.haml +1 -0
  11. data/app/components/spina/admin/journal/empty_list_component.rb +14 -0
  12. data/app/components/spina/admin/journal/form_group_component.html.haml +4 -0
  13. data/app/components/spina/admin/journal/form_group_component.rb +17 -0
  14. data/app/components/spina/admin/journal/institutions_list_component.rb +32 -0
  15. data/app/components/spina/admin/journal/issues_list_component.rb +47 -0
  16. data/app/components/spina/admin/journal/licences_list_component.rb +32 -0
  17. data/app/components/spina/admin/journal/list_component.html.haml +11 -0
  18. data/app/components/spina/admin/journal/list_component.rb +22 -0
  19. data/app/components/spina/admin/journal/list_item_component.html.haml +17 -0
  20. data/app/components/spina/admin/journal/list_item_component.rb +23 -0
  21. data/app/components/spina/admin/journal/volumes_list_component.rb +34 -0
  22. data/app/controllers/spina/admin/journal/application_controller.rb +1 -1
  23. data/app/controllers/spina/admin/journal/articles_controller.rb +18 -24
  24. data/app/controllers/spina/admin/journal/authors_controller.rb +18 -26
  25. data/app/controllers/spina/admin/journal/institutions_controller.rb +13 -5
  26. data/app/controllers/spina/admin/journal/issues_controller.rb +20 -27
  27. data/app/controllers/spina/admin/journal/journals_controller.rb +4 -1
  28. data/app/controllers/spina/admin/journal/licences_controller.rb +8 -4
  29. data/app/controllers/spina/admin/journal/volumes_controller.rb +16 -21
  30. data/app/models/spina/admin/journal/author.rb +1 -0
  31. data/app/models/spina/admin/journal/authorship.rb +9 -0
  32. data/app/views/spina/admin/hooks/journal/_primary_navigation.html.haml +35 -26
  33. data/app/views/spina/admin/journal/articles/_form.html.haml +23 -23
  34. data/app/views/spina/admin/journal/articles/_form_authors.html.haml +3 -15
  35. data/app/views/spina/admin/journal/articles/_form_details.html.haml +37 -56
  36. data/app/views/spina/admin/journal/articles/index.html.haml +7 -17
  37. data/app/views/spina/admin/journal/articles/view_authors.html.haml +2 -0
  38. data/app/views/spina/admin/journal/authors/_form.html.haml +24 -24
  39. data/app/views/spina/admin/journal/authors/_form_affiliation.html.haml +12 -20
  40. data/app/views/spina/admin/journal/authors/_form_articles.html.haml +3 -18
  41. data/app/views/spina/admin/journal/authors/_form_details.html.haml +27 -5
  42. data/app/views/spina/admin/journal/authors/index.html.haml +7 -15
  43. data/app/views/spina/admin/journal/authors/view_articles.html.haml +2 -0
  44. data/app/views/spina/admin/journal/institutions/_form.html.haml +24 -24
  45. data/app/views/spina/admin/journal/institutions/_form_details.html.haml +3 -8
  46. data/app/views/spina/admin/journal/institutions/_form_view_affiliations.html.haml +3 -10
  47. data/app/views/spina/admin/journal/institutions/index.html.haml +7 -15
  48. data/app/views/spina/admin/journal/institutions/view_affiliations.html.haml +2 -0
  49. data/app/views/spina/admin/journal/issues/_form.html.haml +23 -23
  50. data/app/views/spina/admin/journal/issues/_form_articles.html.haml +3 -14
  51. data/app/views/spina/admin/journal/issues/_form_details.html.haml +14 -28
  52. data/app/views/spina/admin/journal/issues/index.html.haml +7 -16
  53. data/app/views/spina/admin/journal/issues/view_articles.html.haml +3 -0
  54. data/app/views/spina/admin/journal/journals/_form.html.haml +22 -30
  55. data/app/views/spina/admin/journal/licences/_form.html.haml +24 -37
  56. data/app/views/spina/admin/journal/licences/index.html.haml +7 -16
  57. data/app/views/spina/admin/journal/volumes/_form.html.haml +25 -12
  58. data/app/views/spina/admin/journal/volumes/_form_details.html.haml +5 -10
  59. data/app/views/spina/admin/journal/volumes/_form_issues.html.haml +2 -13
  60. data/app/views/spina/admin/journal/volumes/index.html.haml +7 -16
  61. data/app/views/spina/admin/journal/volumes/view_issues.html.haml +2 -0
  62. data/app/views/spina/admin/parts/admin/journal/page_ranges/_form.html.haml +3 -4
  63. data/config/locales/en.yml +70 -8
  64. data/config/routes.rb +26 -6
  65. data/db/migrate/20220130171603_add_orcid_to_spina_admin_journal_author.rb +7 -0
  66. data/lib/spina/admin/journal/engine.rb +12 -0
  67. data/lib/spina/admin/journal/version.rb +1 -1
  68. data/lib/spina/admin/journal.rb +1 -0
  69. metadata +55 -65
  70. data/app/assets/javascripts/spina/admin/journal/application.es6 +0 -72
  71. data/app/views/layouts/spina/admin/journal/articles.html.haml +0 -10
  72. data/app/views/layouts/spina/admin/journal/authors.html.haml +0 -10
  73. data/app/views/layouts/spina/admin/journal/institutions.html.haml +0 -10
  74. data/app/views/layouts/spina/admin/journal/issues.html.haml +0 -10
  75. data/app/views/layouts/spina/admin/journal/journals.html.haml +0 -10
  76. data/app/views/layouts/spina/admin/journal/licences.html.haml +0 -10
  77. data/app/views/layouts/spina/admin/journal/volumes.html.haml +0 -10
  78. data/app/views/spina/admin/journal/affiliations/_affiliation.html.haml +0 -8
  79. data/app/views/spina/admin/journal/application/_empty_list.html.haml +0 -3
  80. data/app/views/spina/admin/journal/articles/_article.html.haml +0 -10
  81. data/app/views/spina/admin/journal/authors/_author.html.haml +0 -8
  82. data/app/views/spina/admin/journal/authorships/_authorship.html.haml +0 -9
  83. data/app/views/spina/admin/journal/institutions/_institution.html.haml +0 -9
  84. data/app/views/spina/admin/journal/issues/_issue.html.haml +0 -9
  85. data/app/views/spina/admin/journal/journals/index.html.haml +0 -27
  86. data/app/views/spina/admin/journal/licences/_licence.html.haml +0 -11
  87. data/app/views/spina/admin/journal/volumes/_volume.html.haml +0 -7
  88. data/vendor/assets/javascripts/spina/admin/journal/html5sortable.js +0 -1295
@@ -1,62 +1,43 @@
1
- .page-form
2
- .page-form-group
3
- .page-form-label
4
- = ::Spina::Admin::Journal::Issue.model_name.human count: :one
5
- .page-form-content
6
- = f.collection_select :issue_id, ::Spina::Admin::Journal::Issue.sorted_desc, :id, ->(issue) { t '.volume_issue', volume_number: issue.volume.number, issue_number: issue.number }
7
- .page-form-group
8
- .page-form-label
9
- = ::Spina::Admin::Journal::Article.human_attribute_name :number
10
- %small= t '.unchangeable'
11
- .page-form-content
12
- = f.number_field :number, disabled: true
13
- .page-form-group
14
- .page-form-label
15
- = ::Spina::Admin::Journal::Article.human_attribute_name :title
16
- .page-form-content
17
- = f.text_field :title
18
- .page-form-group
19
- .page-form-label
20
- = Spina::Admin::Journal::Article.human_attribute_name :status
21
- .page-form-content
22
- = f.select :status, Spina::Admin::Journal::Article.statuses.keys.map { |key| [key.humanize, key] }
23
- .page-form-group
24
- .page-form-label
25
- = Spina::Admin::Journal::Article.human_attribute_name :licence
26
- .page-form-content
27
- = f.collection_select :licence_id, Spina::Admin::Journal::Licence.sorted, :id, :name, prompt: true
28
- .page-form-group
29
- .page-form-label
30
- = ::Spina::Admin::Journal::Author.model_name.human count: :many
31
- .page-form-content
32
- .well{ style: 'margin: 0' }
33
- .table-container
34
- %table.table{ style: 'margin: 0' }
35
- %tbody.collection-check-boxes
36
- = f.collection_check_boxes :affiliation_ids, Spina::Admin::Journal::Affiliation.sorted, :id, :name do |builder|
37
- %tr
38
- %td{ style: "padding-left: 16px" }
39
- .form-checkbox
40
- = builder.check_box
41
- = builder.label
42
- .page-form-group
43
- .page-form-label
44
- = ::Spina::Admin::Journal::Article.human_attribute_name :url
45
- .page-form-content
46
- = f.text_field :url
47
- .page-form-group
48
- .page-form-label
49
- = ::Spina::Admin::Journal::Article.human_attribute_name :doi
50
- .page-form-content
51
- = f.text_field :doi
1
+ = form_with model: [spina, :admin_journal, @article], id: dom_id(@article), html: { autocomplete: 'off' } do |f|
2
+ .-mt-6
3
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Issue.model_name.human(count: :one)) do
4
+ = f.collection_select(:issue_id,
5
+ ::Spina::Admin::Journal::Issue.sorted_desc,
6
+ :id,
7
+ ->(issue) { t '.volume_issue', volume_number: issue.volume.number, issue_number: issue.number },
8
+ {},
9
+ class: 'form-select')
10
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Article.human_attribute_name(:number),
11
+ description: t('.unchangeable')) do
12
+ = f.number_field :number, disabled: true, class: 'form-input'
13
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Article.human_attribute_name(:title)) do
14
+ = render Spina::Forms::TextFieldComponent.new(f, :title)
15
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Article.human_attribute_name(:status)) do
16
+ = f.select :status, Spina::Admin::Journal::Article.statuses.keys.map { |key| [key.humanize, key] }, {}, class: 'form-select'
17
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Article.human_attribute_name(:licence)) do
18
+ = f.collection_select :licence_id, Spina::Admin::Journal::Licence.sorted, :id, :name, { prompt: true }, { class: 'form-select' }
19
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Author.model_name.human(count: :many),
20
+ description: t('.affiliation_info')) do
21
+ %ul.list-none.ml-4
22
+ = f.collection_check_boxes(:affiliation_ids,
23
+ Spina::Admin::Journal::Affiliation.sorted,
24
+ :id,
25
+ ->(affiliation) { t '.name_institution', name: affiliation.name, institution: affiliation.institution.name },
26
+ {},
27
+ class: 'form-checkbox rounded') do |builder|
28
+ %li
29
+ .form-checkbox
30
+ = builder.check_box
31
+ %span.text-sm.font-medium.text-gray-600= builder.label
32
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Article.human_attribute_name(:url)) do
33
+ = render Spina::Forms::TextFieldComponent.new(f, :url)
34
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Article.human_attribute_name(:doi)) do
35
+ = render Spina::Forms::TextFieldComponent.new(f, :doi)
52
36
 
53
37
  = f.fields_for :"#{@locale}_content", @parts do |ff|
54
- = ff.hidden_field :type, value: ff.object.class.name
38
+ = ff.hidden_field :type, value: ff.object.class
55
39
  = ff.hidden_field :title
56
40
  = ff.hidden_field :name
57
41
 
58
- .page-form-group.page-part{ data: { name: ff.object.name } }
59
- = render "spina/admin/parts/#{parts_partial_namespace(ff.object.class.name)}/form", f: ff
42
+ = render "spina/admin/parts/#{parts_partial_namespace(ff.object.class.to_s)}/form", f: ff
60
43
 
61
- - unless @article.new_record?
62
- .pull-right= link_to t('spina.permanently_delete'), admin_journal_article_path(@article), method: :delete, data: { confirm: t('.delete_confirmation', title: @article.title) }, class: 'button button-link button-danger'
@@ -1,19 +1,9 @@
1
- - content_for(:header_actions) do
2
- = link_to new_admin_journal_article_path, class: 'button button-primary' do
3
- = icon 'plus'
4
- = t '.new'
1
+ = render Spina::UserInterface::HeaderComponent.new do |header|
2
+ - header.actions do
3
+ .ml-3
4
+ = link_to new_admin_journal_article_path, class: 'btn btn-primary w-full' do
5
+ = heroicon 'plus', style: :solid, class: 'w-7 h-7 -m1-2'
6
+ = t '.new'
5
7
 
6
- .well
7
- .table-container
8
- %table.table
9
- %thead
10
- %tr
11
- %th= ::Spina::Admin::Journal::Volume.human_attribute_name :number
12
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :number
13
- %th= ::Spina::Admin::Journal::Article.human_attribute_name :number
14
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :date
15
- %th= ::Spina::Admin::Journal::Article.human_attribute_name :title
16
- %th
8
+ = render Spina::Admin::Journal::ArticlesListComponent.new(articles: @articles)
17
9
 
18
- %tbody
19
- = render @articles.any? ? @articles : 'empty_list', message: t('.empty')
@@ -0,0 +1,2 @@
1
+ %turbo-frame#article_authors
2
+ = render Spina::Admin::Journal::AuthorshipsListComponent.new(authorships: @article.authorships.sorted_within_article, sortable: true)
@@ -1,29 +1,29 @@
1
- - if @author.errors.any?
2
- - content_for :notifications do
3
- .notification.notification-danger.animated.fadeInRight
4
- = icon 'exclamation'
5
- .notification-message
6
- = t 'spina.notifications.alert'
7
- %small= @author.errors.full_messages.join('<br />').html_safe
8
- = link_to '#', data: {close_notification: true} do
9
- = icon 'cross'
1
+ %div{ data: { controller: 'tabs',
2
+ tabs: { active: 'cursor-default text-gray-900 bg-spina-dark bg-opacity-10',
3
+ inactive: 'cursor-pointer bg-transparent text-gray-400 border-transparent' } } }
4
+ = render Spina::UserInterface::HeaderComponent.new do |header|
5
+ - header.actions do
6
+ - if @author.persisted?
7
+ = render Spina::UserInterface::DropdownComponent.new do |dropdown|
8
+ - dropdown.button(classes: "btn btn-default px-3") do
9
+ = heroicon('dots-horizontal', style: :solid, class: "w-5 h-5 text-gray-600")
10
10
 
11
- = form_for [:admin_journal, @author], html: {autocomplete: "off"} do |f|
12
- %header#header
13
- = render partial: 'spina/admin/shared/breadcrumbs'
11
+ - dropdown.menu do
12
+ = button_to t('spina.permanently_delete'), admin_journal_author_path(@author), method: :delete, class: "block w-full text-left px-4 py-2 text-sm leading-5 font-medium text-red-500 cursor-pointer bg-white hover:bg-red-100 hover:bg-opacity-50 hover:text-red-500 focus:outline-none focus:bg-gray-100 focus:text-gray-900", form: {data: { controller: 'confirm', confirm_message: t('.delete_confirmation', name: @author.primary_affiliation.name) } }
14
13
 
15
- #header_actions
16
- %button.button.button-primary{type: 'submit', style: 'margin-right: 0', data: {disable_with: t('spina.pages.saving')}}
17
- = icon 'check'
14
+ = button_tag type: :submit, form: dom_id(@author), class: 'btn btn-primary', data: { controller: 'button', action: 'button#loading', loading_message: t('spina.ui.saving')} do
15
+ = heroicon('check', style: :solid, class: 'w-5 h-5 mr-1 -ml-2')
18
16
  = t '.save'
19
17
 
20
- .button{style: 'margin-right: 0'}= link_to t('spina.cancel'), admin_journal_authors_path
18
+ - header.navigation do
19
+ %nav.-mb-3.mt-4
20
+ %ul.inline-flex.w-auto.rounded-md.bg-white
21
+ - @tabs.each do |tab|
22
+ %button.block.px-3.leading-relaxed.py-1.hover:text-gray-800.rounded-md.text-gray-400.font-medium.text-sm.flex.items-center.whitespace-nowrap{ type: 'button', data: { action: 'tabs#show', 'tabs-target': 'button', 'pane-id': "#{tab}" } }
23
+ = t ".#{tab}"
21
24
 
22
- %nav#secondary.tabs
23
- %ul
24
- - @tabs.each_with_index do |tab, i|
25
- %li{ class: ('active' if i == 0) }
26
- = link_to t(".#{tab}"), "##{tab}"
27
-
28
- #details.tab-content.active= render 'form_details', f: f
29
- #articles.tab-content= render 'form_articles', f: f
25
+ .p-4.md:p-8
26
+ = form_with model: [spina, :admin_journal, @author], id: dom_id(@author), html: { autocomplete: 'off' } do |f|
27
+ - @tabs.each_with_index do |tab, i|
28
+ %div{ 'data-tabs-target': 'pane', id: tab, hidden: i != 0 }
29
+ .max-w-5xl= render "form_#{tab}", f: f
@@ -1,20 +1,12 @@
1
- .page-form-group
2
- .page-form-label
3
- = ::Spina::Admin::Journal::Affiliation.human_attribute_name :first_name
4
- .page-form-content
5
- = ff.text_field :first_name
6
- .page-form-group
7
- .page-form-label
8
- = ::Spina::Admin::Journal::Affiliation.human_attribute_name :surname
9
- .page-form-content
10
- = ff.text_field :surname
11
- .page-form-group
12
- .page-form-label
13
- = ::Spina::Admin::Journal::Affiliation.human_attribute_name :institution
14
- .page-form-content
15
- = ff.collection_select :institution_id, ::Spina::Admin::Journal::Institution.sorted, :id, :name
16
- .page-form-group
17
- .page-form-label
18
- = t '.primary'
19
- .page-form-content
20
- = radio_button_tag 'author[primary_affiliation_index]', ff.index, ff.object.status == 'primary'
1
+ %div{ data: { 'part-id': "#{f.object.object_id}", 'tabs-target': 'pane' }, id: "pane_#{f.object.object_id}" }
2
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Affiliation.human_attribute_name(:first_name)) do
3
+ = render Spina::Forms::TextFieldComponent.new(f, :first_name)
4
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Affiliation.human_attribute_name(:surname)) do
5
+ = render Spina::Forms::TextFieldComponent.new(f, :surname)
6
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Affiliation.human_attribute_name(:institution)) do
7
+ = f.collection_select :institution_id, Spina::Admin::Journal::Institution.sorted, :id, :name, {}, class: 'form-select'
8
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: t('.primary'), description: t('.primary_explanation')) do
9
+ = radio_button_tag 'author[primary_affiliation_index]', f.index, f.object.status == 'primary', class: 'form-radio'
10
+
11
+ .text-right
12
+ = button_tag t('spina.ui.delete'), type: :button, class: 'btn btn-default bg-transparent hover:bg-white hover:text-red-500 h-8 px-3 inline-block mt-3', data: { action: 'repeater#removeFields', id: "pane_#{f.object.object_id}" }
@@ -1,18 +1,3 @@
1
- .table-container
2
- %table.table
3
- %thead
4
- %tr
5
- %th= ::Spina::Admin::Journal::Volume.human_attribute_name :number
6
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :number
7
- %th= ::Spina::Admin::Journal::Article.human_attribute_name :number
8
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :date
9
- %th= ::Spina::Admin::Journal::Article.human_attribute_name :title
10
- %th
11
- %tbody
12
- - if @author.affiliations.any?
13
- -# render empty list if no affiliation has any articles
14
- = render 'empty_list', message: t('.no_articles') if @author.affiliations.reduce(true) do |memo, affiliation|
15
- = render affiliation.articles
16
- - memo && !affiliation.articles.any?
17
- - else
18
- = render 'empty_list', message: t('.no_articles')
1
+ - if @author.persisted?
2
+ .-mt-4.md:-mt-8
3
+ %turbo-frame#author_articles{ src: spina.view_articles_admin_journal_author_path(@author), loading: 'lazy' }
@@ -1,6 +1,28 @@
1
- .page-form
2
- = f.fields_for :affiliations, @author.affiliations do |ff|
3
- .well= render 'form_affiliation', ff: ff
1
+ .text-gray-700.text-sm.font-light= t '.explanation'
2
+ .mt-6{ 'data-controller': 'repeater' }
3
+ %label.block.text-sm.leading-5.font-medium.text-gray-700= Spina::Admin::Journal::Author.human_attribute_name :affiliations
4
+ .-mt-4.flex.flex-col.md:flex-row{ data: { 'controller': 'tabs', 'tabs-active': 'bg-spina-dark bg-opacity-10 text-gray-900', 'tabs-inactive': 'text-gray-500' } }
5
+ .md:w-64.md:pr-6
4
6
 
5
- - unless @author.new_record?
6
- .pull-right= link_to t('spina.permanently_delete'), admin_journal_author_path(@author), method: :delete, data: { confirm: t('.delete_confirmation', name: @author.primary_affiliation.name) }, class: 'button button-link button-danger'
7
+ -# Fields for new affiliation
8
+ - new_affiliation = Spina::Admin::Journal::Affiliation.new
9
+ - fields = f.fields_for(:affiliations, [new_affiliation], child_index: new_affiliation.object_id) { |ff| render('form_affiliation', f: ff) }.gsub('\n', '')
10
+
11
+ -# Tabs
12
+ .pt-6.-ml-3
13
+ %div{ data: { action: 'exists->tabs#added', 'repeater-target' => 'list', 'tabs-target' => 'list' } }
14
+ - (f.object.affiliations || []).each.with_index do |affiliation, index|
15
+ %button.text-gray-500.hover:text-gray-900.rounded-md.px-3.truncate.text-sm.font-medium.flex.items-center.w-full.h-9{ data: { 'action': 'tabs#show', 'pane-id': "pane_#{affiliation.object_id}", 'repeater-target': 'listItem', 'tabs-target': 'button' }, type: 'button' }
16
+ = affiliation&.name
17
+ %button.text-gray-400.pl-2.hover:text-gray-900.rounded-md.truncate.text-sm.font-medium.flex.items-center.w-full.h-10{ data: { 'action': 'repeater#addFields', 'child-index': "#{new_affiliation.object_id}", 'fields': fields }, type: 'button' }
18
+ = heroicon 'plus', style: :solid, class: 'w-6 h-6 mr-1'
19
+ = t 'spina.ui.new_entry'
20
+
21
+ -# Content
22
+ .flex-1.pl-6.md:pl-0{ 'data-repeater-target': 'content' }
23
+ = f.fields_for :affiliations do |affiliation_fields|
24
+ = render 'form_affiliation', f: affiliation_fields
25
+
26
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Author.human_attribute_name(:orcid),
27
+ description: t('.orcid_info')) do
28
+ = render Spina::Forms::TextFieldComponent.new(f, :orcid)
@@ -1,17 +1,9 @@
1
- - content_for(:header_actions) do
2
- = link_to new_admin_journal_author_path, class: 'button button-primary' do
3
- = icon 'plus'
4
- = t '.new'
1
+ = render Spina::UserInterface::HeaderComponent.new do |header|
2
+ - header.actions do
3
+ .ml-3
4
+ = link_to new_admin_journal_author_path, class: 'btn btn-primary w-full' do
5
+ = heroicon 'plus', style: :solid, class: 'w-7 h-7 -m1-2'
6
+ = t '.new'
5
7
 
6
- .well
7
- .table-container
8
- %table.table
9
- %thead
10
- %tr
11
- %th= ::Spina::Admin::Journal::Affiliation.human_attribute_name :name
12
- %th= ::Spina::Admin::Journal::Institution.model_name.human count: :one
13
- %th= t '.number_of_articles'
14
- %th
8
+ = render Spina::Admin::Journal::AuthorsListComponent.new(authors: @authors)
15
9
 
16
- %tbody
17
- = render @authors.any? ? @authors : 'empty_list', message: t('.empty')
@@ -0,0 +1,2 @@
1
+ %turbo-frame#author_articles
2
+ = render Spina::Admin::Journal::ArticlesListComponent.new(articles: @author.affiliations.reduce([]) { |memo, affiliation| memo << affiliation.articles.to_a }.flatten )
@@ -1,29 +1,29 @@
1
- - if @institution.errors.any?
2
- - content_for :notifications do
3
- .notification.notification-danger.animated.fadeInRight
4
- = icon 'exclamation'
5
- .notification-message
6
- = t 'spina.notifications.alert'
7
- %small= @institution.errors.full_messages.join('<br />').html_safe
8
- = link_to '#', data: { close_notification: true } do
9
- = icon 'cross'
1
+ %div{ data: { controller: 'tabs',
2
+ tabs: { active: 'cursor-default text-gray-900 bg-spina-dark bg-opacity-10',
3
+ inactive: 'cursor-pointer bg-transparent text-gray-400 border-transparent' } } }
4
+ = render Spina::UserInterface::HeaderComponent.new do |header|
5
+ - header.actions do
6
+ - if @institution.persisted?
7
+ = render Spina::UserInterface::DropdownComponent.new do |dropdown|
8
+ - dropdown.button(classes: "btn btn-default px-3") do
9
+ = heroicon('dots-horizontal', style: :solid, class: "w-5 h-5 text-gray-600")
10
10
 
11
- = form_for [:admin_journal, @institution], html: {autocomplete: "off"} do |f|
12
- %header#header
13
- = render partial: 'spina/admin/shared/breadcrumbs'
11
+ - dropdown.menu do
12
+ = button_to t('spina.permanently_delete'), admin_journal_institution_path(@institution), method: :delete, class: "block w-full text-left px-4 py-2 text-sm leading-5 font-medium text-red-500 cursor-pointer bg-white hover:bg-red-100 hover:bg-opacity-50 hover:text-red-500 focus:outline-none focus:bg-gray-100 focus:text-gray-900", form: {data: { controller: 'confirm', confirm_message: t('.delete_confirmation', name: @institution.name) } }
14
13
 
15
- #header_actions
16
- %button.button.button-primary{ type: 'submit', style: 'margin-right: 0', data: { disable_with: t('spina.pages.saving') } }
17
- = icon 'check'
14
+ = button_tag type: :submit, form: dom_id(@institution), class: 'btn btn-primary', data: { controller: 'button', action: 'button#loading', loading_message: t('spina.ui.saving')} do
15
+ = heroicon('check', style: :solid, class: 'w-5 h-5 mr-1 -ml-2')
18
16
  = t '.save'
19
17
 
20
- .button{ style: 'margin-right: 0' }= link_to t('spina.cancel'), admin_journal_institutions_path
18
+ - header.navigation do
19
+ %nav.-mb-3.mt-4
20
+ %ul.inline-flex.w-auto.rounded-md.bg-white
21
+ - @tabs.each do |tab|
22
+ %button.block.px-3.leading-relaxed.py-1.hover:text-gray-800.rounded-md.text-gray-400.font-medium.text-sm.flex.items-center.whitespace-nowrap{ type: 'button', data: { action: 'tabs#show', 'tabs-target': 'button', 'pane-id': "#{tab}" } }
23
+ = t ".#{tab}"
21
24
 
22
- %nav#secondary.tabs
23
- %ul
24
- - @tabs.each_with_index do |tab, i|
25
- %li{ class: ('active' if i == 0) }
26
- = link_to t(".#{tab}"), "##{tab}"
27
-
28
- #details.tab-content.active= render 'form_details', f: f
29
- #view_affiliations.tab-content= render 'form_view_affiliations', f: f
25
+ .p-4.md:p-8
26
+ = form_with model: [spina, :admin_journal, @institution], id: dom_id(@institution), html: { autocomplete: 'off' } do |f|
27
+ - @tabs.each_with_index do |tab, i|
28
+ %div{ 'data-tabs-target': 'pane', id: tab, hidden: i != 0 }
29
+ .max-w-5xl= render "form_#{tab}", f: f
@@ -1,9 +1,4 @@
1
- .page-form
2
- .page-form-group
3
- .page-form-label
4
- = ::Spina::Admin::Journal::Institution.human_attribute_name :name
5
- .page-form-content
6
- = f.text_field :name
1
+ .-mt-6
2
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Institution.human_attribute_name(:name)) do
3
+ = render Spina::Forms::TextFieldComponent.new(f, :name)
7
4
 
8
- - unless @institution.new_record?
9
- .pull-right= link_to t('spina.permanently_delete'), admin_journal_institution_path(@institution), method: :delete, data: { confirm: t('.delete_confirmation', name: @institution.name) }, class: 'button button-link button-danger'
@@ -1,10 +1,3 @@
1
- .table-container
2
- %table.table
3
- %thead
4
- %tr
5
- %th= ::Spina::Admin::Journal::Affiliation.human_attribute_name :name
6
- %th= ::Spina::Admin::Journal::Affiliation.human_attribute_name :institution
7
- %th= t '.number_of_articles'
8
- %th
9
- %tbody
10
- = render @institution.affiliations.any? ? @institution.affiliations : 'empty_list', message: t('.no_affiliations')
1
+ - if @institution.persisted?
2
+ .-mt-4.md:-mt-8
3
+ %turbo-frame#institution_affiliations{ src: spina.view_affiliations_admin_journal_institution_path(@institution), loading: 'lazy' }
@@ -1,16 +1,8 @@
1
- - content_for(:header_actions) do
2
- = link_to new_admin_journal_institution_path, class: 'button button-primary' do
3
- = icon 'plus'
4
- = t '.new'
1
+ = render Spina::UserInterface::HeaderComponent.new do |header|
2
+ - header.actions do
3
+ .ml-3
4
+ = link_to new_admin_journal_institution_path, class: 'btn btn-primary w-full' do
5
+ = heroicon 'plus', style: :solid, class: 'w-7 h-7 -m1-2'
6
+ = t '.new'
5
7
 
6
- .well
7
- .table-container
8
- %table.table
9
- %thead
10
- %tr
11
- %th= ::Spina::Admin::Journal::Institution.human_attribute_name :name
12
- %th= t '.number_of_affiliations'
13
- %th
14
-
15
- %tbody
16
- = render @institutions.any? ? @institutions : 'empty_list', message: t('.empty')
8
+ = render Spina::Admin::Journal::InstitutionsListComponent.new(institutions: @institutions)
@@ -0,0 +1,2 @@
1
+ %turbo-frame#institution_affiliations
2
+ = render Spina::Admin::Journal::AffiliationsListComponent.new(affiliations: @institution.affiliations.sorted)
@@ -1,29 +1,29 @@
1
- - if @issue.errors.any?
2
- - content_for :notifications do
3
- .notification.notification-danger.animated.fadeInRight
4
- = icon 'exclamation'
5
- .notification-message
6
- = t 'spina.notifications.alert'
7
- %small= @issue.errors.full_messages.join('<br />').html_safe
8
- = link_to '#', data: { close_notification: true } do
9
- = icon 'cross'
1
+ %div{ data: { controller: 'tabs',
2
+ tabs: { active: 'cursor-default text-gray-900 bg-spina-dark bg-opacity-10',
3
+ inactive: 'cursor-pointer bg-transparent text-gray-400 border-transparent' } } }
4
+ = render Spina::UserInterface::HeaderComponent.new do |header|
5
+ - header.actions do
6
+ - if @issue.persisted?
7
+ = render Spina::UserInterface::DropdownComponent.new do |dropdown|
8
+ - dropdown.button(classes: "btn btn-default px-3") do
9
+ = heroicon('dots-horizontal', style: :solid, class: "w-5 h-5 text-gray-600")
10
10
 
11
- = form_for [:admin_journal, @issue], html: { autocomplete: 'off' } do |f|
12
- %header#header
13
- = render partial: 'spina/admin/shared/breadcrumbs'
11
+ - dropdown.menu do
12
+ = button_to t('spina.permanently_delete'), admin_journal_issue_path(@issue), method: :delete, class: "block w-full text-left px-4 py-2 text-sm leading-5 font-medium text-red-500 cursor-pointer bg-white hover:bg-red-100 hover:bg-opacity-50 hover:text-red-500 focus:outline-none focus:bg-gray-100 focus:text-gray-900", form: {data: { controller: 'confirm', confirm_message: t('.delete_confirmation', number: @issue.number) } }
14
13
 
15
- #header_actions
16
- %button.button.button-primary{ type: 'submit', style: 'margin-right: 0', data: { disable_with: t('spina.pages.saving') } }
17
- = icon 'check'
14
+ = button_tag type: :submit, form: dom_id(@issue), class: 'btn btn-primary', data: { controller: 'button', action: 'button#loading', loading_message: t('spina.ui.saving')} do
15
+ = heroicon('check', style: :solid, class: 'w-5 h-5 mr-1 -ml-2')
18
16
  = t '.save'
19
17
 
20
- .button{style: 'margin-right: 0'}= link_to t('spina.cancel'), admin_journal_institutions_path
18
+ - header.navigation do
19
+ %nav.-mb-3.mt-4
20
+ %ul.inline-flex.w-auto.rounded-md.bg-white
21
+ - @tabs.each do |tab|
22
+ %button.block.px-3.leading-relaxed.py-1.hover:text-gray-800.rounded-md.text-gray-400.font-medium.text-sm.flex.items-center.whitespace-nowrap{ type: 'button', data: { action: 'tabs#show', 'tabs-target': 'button', 'pane-id': "#{tab}" } }
23
+ = t ".#{tab}"
21
24
 
22
- %nav#secondary.tabs
23
- %ul
24
- - @tabs.each_with_index do |tab, i|
25
- %li{ class: ('active' if i == 0) }
26
- = link_to t(".#{tab}"), "##{tab}"
25
+ .p-4.md:p-8
26
+ - @tabs.each_with_index do |tab, i|
27
+ %div{ 'data-tabs-target': 'pane', id: tab, hidden: i != 0 }
28
+ .max-w-5xl.max-w-5xl= render "form_#{tab}"
27
29
 
28
- #details.tab-content.active= render 'form_details', f: f
29
- #articles.tab-content= render 'form_articles', f: f
@@ -1,14 +1,3 @@
1
- .sort-message
2
- .well
3
- .table-container
4
- %table.table
5
- %thead
6
- %tr
7
- %th= ::Spina::Admin::Journal::Volume.human_attribute_name :number
8
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :number
9
- %th= ::Spina::Admin::Journal::Article.human_attribute_name :number
10
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :date
11
- %th= ::Spina::Admin::Journal::Article.human_attribute_name :title
12
- %th
13
- %tbody.html5sortable{ data: { id: @issue.id, sorted_collection: 'admin_journal_articles', sort_url: !@issue.id.nil? && sort_admin_journal_articles_url(@issue) } }
14
- = render @articles && @articles.any? ? @articles : 'empty_list', message: t('.no_articles')
1
+ - if @issue.persisted?
2
+ .-mt-4.md:-mt-8
3
+ %turbo-frame#issue_articles{ src: spina.view_articles_admin_journal_issue_path(@issue), loading: 'lazy' }
@@ -1,32 +1,18 @@
1
- .page-form
2
- .page-form-group
3
- .page-form-label
4
- = ::Spina::Admin::Journal::Volume.human_attribute_name :number
5
- .page-form-content
6
- = f.collection_select :volume_id, ::Spina::Admin::Journal::Volume.sorted_desc, :id, :number
7
- .page-form-group
8
- .page-form-label
9
- = ::Spina::Admin::Journal::Issue.human_attribute_name :number
10
- %small= t '.issue_unchangeable'
11
- .page-form-content
12
- = f.number_field :number, disabled: true
13
- .page-form-group
14
- .page-form-label
15
- = ::Spina::Admin::Journal::Issue.human_attribute_name :title
16
- .page-form-content
17
- = f.text_field :title
18
- .page-form-group
19
- .page-form-label
20
- = ::Spina::Admin::Journal::Issue.human_attribute_name :date
21
- .page-form-content
22
- = f.date_field :date
1
+ = form_with model: [spina, :admin_journal, @issue], id: dom_id(@issue), html: { autocomplete: 'off' } do |f|
2
+ .-mt-6
3
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Volume.human_attribute_name(:number)) do
4
+ = f.collection_select :volume_id, ::Spina::Admin::Journal::Volume.sorted_desc, :id, :number, {}, class: 'form-select'
5
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Issue.human_attribute_name(:number),
6
+ description: t('.issue_unchangeable')) do
7
+ = f.number_field :number, disabled: true, class: 'form-input'
8
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Issue.human_attribute_name(:title)) do
9
+ = render Spina::Forms::TextFieldComponent.new(f, :title)
10
+ = render Spina::Admin::Journal::FormGroupComponent.new(label: Spina::Admin::Journal::Issue.human_attribute_name(:date)) do
11
+ = f.date_field :date, class: 'form-input'
12
+
23
13
  = f.fields_for :"#{@locale}_content", @parts do |ff|
24
- = ff.hidden_field :type, value: ff.object.class.name
14
+ = ff.hidden_field :type, value: ff.object.class
25
15
  = ff.hidden_field :title
26
16
  = ff.hidden_field :name
27
17
 
28
- .page-form-group.page-part{ data: { name: ff.object.name } }
29
- = render "spina/admin/parts/#{parts_partial_namespace(ff.object.class.name)}/form", f: ff
30
-
31
- - unless @issue.new_record?
32
- .pull-right= link_to t('spina.permanently_delete'), admin_journal_issue_path(@issue), method: :delete, data: { confirm: t('.delete_confirmation', number: @issue.number) }, class: 'button button-link button-danger'
18
+ = render "spina/admin/parts/#{parts_partial_namespace(ff.object.class.to_s)}/form", f: ff
@@ -1,18 +1,9 @@
1
- - content_for(:header_actions) do
2
- = link_to new_admin_journal_issue_path, class: 'button button-primary' do
3
- = icon 'plus'
4
- = t '.new'
1
+ = render Spina::UserInterface::HeaderComponent.new do |header|
2
+ - header.actions do
3
+ .ml-3
4
+ = link_to new_admin_journal_issue_path, class: 'btn btn-primary w-full' do
5
+ = heroicon 'plus', style: :solid, class: 'w-7 h-7 -m1-2'
6
+ = t '.new'
5
7
 
6
- .well
7
- .table-container
8
- %table.table
9
- %thead
10
- %tr
11
- %th= ::Spina::Admin::Journal::Volume.human_attribute_name :number
12
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :number
13
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :title
14
- %th= ::Spina::Admin::Journal::Issue.human_attribute_name :date
15
- %th
8
+ = render Spina::Admin::Journal::IssuesListComponent.new(issues: @issues, sortable: false)
16
9
 
17
- %tbody
18
- = render @issues.any? ? @issues : 'empty_list', message: t('.empty')
@@ -0,0 +1,3 @@
1
+ %turbo-frame#issue_articles
2
+ = render Spina::Admin::Journal::ArticlesListComponent.new(articles: @issue.articles, sortable: true)
3
+