spina-admin-journal 0.1.0
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +99 -0
- data/Rakefile +36 -0
- data/app/assets/config/spina_admin_journal_manifest.js +3 -0
- data/app/assets/javascripts/spina/admin/journal/application.es6 +72 -0
- data/app/assets/stylesheets/spina/admin/journal/application.css +27 -0
- data/app/controllers/spina/admin/journal/application_controller.rb +26 -0
- data/app/controllers/spina/admin/journal/articles_controller.rb +125 -0
- data/app/controllers/spina/admin/journal/authors_controller.rb +83 -0
- data/app/controllers/spina/admin/journal/institutions_controller.rb +71 -0
- data/app/controllers/spina/admin/journal/issues_controller.rb +129 -0
- data/app/controllers/spina/admin/journal/journals_controller.rb +73 -0
- data/app/controllers/spina/admin/journal/volumes_controller.rb +79 -0
- data/app/models/spina/admin/journal.rb +11 -0
- data/app/models/spina/admin/journal/affiliation.rb +62 -0
- data/app/models/spina/admin/journal/article.rb +55 -0
- data/app/models/spina/admin/journal/author.rb +47 -0
- data/app/models/spina/admin/journal/authorship.rb +19 -0
- data/app/models/spina/admin/journal/institution.rb +32 -0
- data/app/models/spina/admin/journal/issue.rb +49 -0
- data/app/models/spina/admin/journal/journal.rb +50 -0
- data/app/models/spina/admin/journal/volume.rb +37 -0
- data/app/validators/spina/admin/journal/uri_validator.rb +24 -0
- data/app/views/layouts/spina/admin/journal/articles.html.haml +10 -0
- data/app/views/layouts/spina/admin/journal/authors.html.haml +10 -0
- data/app/views/layouts/spina/admin/journal/institutions.html.haml +10 -0
- data/app/views/layouts/spina/admin/journal/issues.html.haml +10 -0
- data/app/views/layouts/spina/admin/journal/journals.html.haml +10 -0
- data/app/views/layouts/spina/admin/journal/volumes.html.haml +10 -0
- data/app/views/spina/admin/hooks/journal/_head.html.haml +2 -0
- data/app/views/spina/admin/hooks/journal/_primary_navigation.html.haml +27 -0
- data/app/views/spina/admin/hooks/journal/_website_secondary_navigation.html.haml +0 -0
- data/app/views/spina/admin/journal/affiliations/_affiliation.html.haml +8 -0
- data/app/views/spina/admin/journal/application/_empty_list.html.haml +3 -0
- data/app/views/spina/admin/journal/articles/_article.html.haml +10 -0
- data/app/views/spina/admin/journal/articles/_form.html.haml +29 -0
- data/app/views/spina/admin/journal/articles/_form_authors.html.haml +10 -0
- data/app/views/spina/admin/journal/articles/_form_details.html.haml +52 -0
- data/app/views/spina/admin/journal/articles/edit.html.haml +1 -0
- data/app/views/spina/admin/journal/articles/index.html.haml +19 -0
- data/app/views/spina/admin/journal/articles/new.html.haml +1 -0
- data/app/views/spina/admin/journal/authors/_author.html.haml +8 -0
- data/app/views/spina/admin/journal/authors/_form.html.haml +29 -0
- data/app/views/spina/admin/journal/authors/_form_affiliation.html.haml +20 -0
- data/app/views/spina/admin/journal/authors/_form_articles.html.haml +18 -0
- data/app/views/spina/admin/journal/authors/_form_details.html.haml +6 -0
- data/app/views/spina/admin/journal/authors/edit.html.haml +1 -0
- data/app/views/spina/admin/journal/authors/index.html.haml +17 -0
- data/app/views/spina/admin/journal/authors/new.html.haml +1 -0
- data/app/views/spina/admin/journal/institutions/_form.html.haml +29 -0
- data/app/views/spina/admin/journal/institutions/_form_details.html.haml +9 -0
- data/app/views/spina/admin/journal/institutions/_form_view_affiliations.html.haml +10 -0
- data/app/views/spina/admin/journal/institutions/_institution.html.haml +9 -0
- data/app/views/spina/admin/journal/institutions/edit.html.haml +1 -0
- data/app/views/spina/admin/journal/institutions/index.html.haml +16 -0
- data/app/views/spina/admin/journal/institutions/new.html.haml +1 -0
- data/app/views/spina/admin/journal/issues/_form.html.haml +29 -0
- data/app/views/spina/admin/journal/issues/_form_articles.html.haml +14 -0
- data/app/views/spina/admin/journal/issues/_form_details.html.haml +32 -0
- data/app/views/spina/admin/journal/issues/_issue.html.haml +9 -0
- data/app/views/spina/admin/journal/issues/edit.html.haml +1 -0
- data/app/views/spina/admin/journal/issues/index.html.haml +18 -0
- data/app/views/spina/admin/journal/issues/new.html.haml +1 -0
- data/app/views/spina/admin/journal/journals/_form.html.haml +35 -0
- data/app/views/spina/admin/journal/journals/edit.html.haml +1 -0
- data/app/views/spina/admin/journal/journals/index.html.haml +27 -0
- data/app/views/spina/admin/journal/journals/new.html.haml +1 -0
- data/app/views/spina/admin/journal/volumes/_form.html.haml +15 -0
- data/app/views/spina/admin/journal/volumes/_form_details.html.haml +10 -0
- data/app/views/spina/admin/journal/volumes/_form_issues.html.haml +13 -0
- data/app/views/spina/admin/journal/volumes/_volume.html.haml +7 -0
- data/app/views/spina/admin/journal/volumes/edit.html.haml +1 -0
- data/app/views/spina/admin/journal/volumes/index.html.haml +17 -0
- data/app/views/spina/admin/journal/volumes/new.html.haml +1 -0
- data/config/locales/en.yml +184 -0
- data/config/routes.rb +21 -0
- data/db/migrate/20201216152147_create_spina_admin_journal_journals.rb +13 -0
- data/db/migrate/20201216153822_create_spina_admin_journal_volumes.rb +13 -0
- data/db/migrate/20201216155113_create_spina_admin_journal_issues.rb +15 -0
- data/db/migrate/20201216161122_create_spina_admin_journal_articles.rb +16 -0
- data/db/migrate/20201216205633_create_spina_admin_journal_institutions.rb +11 -0
- data/db/migrate/20201216211224_create_spina_admin_journal_authors.rb +7 -0
- data/db/migrate/20201216221146_create_spina_admin_journal_affiliations.rb +15 -0
- data/db/migrate/20201216230816_create_spina_admin_journal_authorships.rb +14 -0
- data/db/migrate/20201231165231_create_spina_admin_journal_parts.rb +12 -0
- data/db/migrate/20210424123450_add_json_attributes_to_spina_admin_journal_journals.rb +7 -0
- data/db/migrate/20210424123521_add_json_attributes_to_spina_admin_journal_issues.rb +7 -0
- data/db/migrate/20210424123555_add_json_attributes_to_spina_admin_journal_articles.rb +7 -0
- data/lib/spina/admin/journal.rb +18 -0
- data/lib/spina/admin/journal/engine.rb +17 -0
- data/lib/spina/admin/journal/version.rb +9 -0
- data/lib/tasks/spina/admin/journal_tasks.rake +5 -0
- data/vendor/assets/javascripts/spina/admin/journal/html5sortable.js +1295 -0
- metadata +388 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Authors are collections of {Affiliation}s.
|
|
7
|
+
#
|
|
8
|
+
# Since people can have multiple names, titles, institutions, etc., these details are all
|
|
9
|
+
# handled by the {Affiliation} record. This record groups said records together, in order
|
|
10
|
+
# that a coherent oeuvre of a single author be identified, which is more user-friendly.
|
|
11
|
+
#
|
|
12
|
+
# @note An author must have at least one Affiliation with +status: primary+, else validation
|
|
13
|
+
# will fail.
|
|
14
|
+
#
|
|
15
|
+
# @see Affiliation
|
|
16
|
+
class Author < ApplicationRecord
|
|
17
|
+
# @!attribute [rw] affiliations
|
|
18
|
+
# @return [ActiveRecord::Relation] Directly associated {Affiliation}s.
|
|
19
|
+
has_many :affiliations, inverse_of: :author, dependent: :destroy
|
|
20
|
+
accepts_nested_attributes_for :affiliations
|
|
21
|
+
# @!attribute [rw] institutions
|
|
22
|
+
# @return [ActiveRecord::Relation] The {Institution}s corresponding to this Author's affiliations.
|
|
23
|
+
has_many :institutions, through: :affiliations
|
|
24
|
+
# @!attribute [rw] articles
|
|
25
|
+
# @return [ActiveRecord::Relation] {Article}s associated through authorships.
|
|
26
|
+
has_many :articles, through: :affiliations
|
|
27
|
+
|
|
28
|
+
validate :must_have_one_primary_affiliation
|
|
29
|
+
|
|
30
|
+
# @!attribute [r] primary_affiliation
|
|
31
|
+
# @return [ActiveRecord::Relation] The author's primary affiliation.
|
|
32
|
+
def primary_affiliation
|
|
33
|
+
affiliations.primary.first || Affiliation.new(status: :primary)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def must_have_one_primary_affiliation
|
|
39
|
+
return if !affiliations.nil? && affiliations.any? \
|
|
40
|
+
&& (affiliations.count { |affiliation| affiliation.status == 'primary' } == 1)
|
|
41
|
+
|
|
42
|
+
errors.add :affiliations, 'must have at least one primary affiliation'
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Joins Articles and Affiliations
|
|
7
|
+
# @see Article
|
|
8
|
+
# @see Affiliation
|
|
9
|
+
class Authorship < ApplicationRecord
|
|
10
|
+
# @!attribute [rw] article
|
|
11
|
+
# @return [ActiveRecord::Relation] the associated article
|
|
12
|
+
belongs_to :article
|
|
13
|
+
# @!attribute [rw] author_name
|
|
14
|
+
# @return [ActiveRecord::Relation] the associated affiliation of an author of the article
|
|
15
|
+
belongs_to :affiliation
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Record for an institution. Associated with {Author}s via {Affiliation}s.
|
|
7
|
+
#
|
|
8
|
+
# === Validators
|
|
9
|
+
# Presence:: {#name}
|
|
10
|
+
# Uniqueness:: {#name}
|
|
11
|
+
#
|
|
12
|
+
# === Scopes
|
|
13
|
+
# sorted:: sort institutions in alphabetical order
|
|
14
|
+
#
|
|
15
|
+
# @see Affiliation
|
|
16
|
+
class Institution < ApplicationRecord
|
|
17
|
+
# @!attribute [rw] name
|
|
18
|
+
# @return [String]
|
|
19
|
+
# @!attribute [rw] affiliations
|
|
20
|
+
# @return [ActiveRecord::Relation] the affiliations held at the institution
|
|
21
|
+
has_many :affiliations, dependent: :destroy
|
|
22
|
+
# @!attribute [rw] authors
|
|
23
|
+
# @return [ActiveRecord::Relation] associated authors
|
|
24
|
+
has_many :authors, through: :affiliations
|
|
25
|
+
|
|
26
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false }
|
|
27
|
+
|
|
28
|
+
scope :sorted, -> { order(name: :asc) }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Record for an issue of a journal.
|
|
7
|
+
# Belongs to a particular volume of a journal. Has many articles.
|
|
8
|
+
#
|
|
9
|
+
# === Validators
|
|
10
|
+
# Presence:: {#number}, {#date}
|
|
11
|
+
# Uniqueness:: {#number} (scope: volume)
|
|
12
|
+
#
|
|
13
|
+
# === Scopes
|
|
14
|
+
# sorted_asc:: sorted in order of increasing number
|
|
15
|
+
# sorted_desc:: sorted highest number first
|
|
16
|
+
#
|
|
17
|
+
# @see Article
|
|
18
|
+
# @see Volume
|
|
19
|
+
class Issue < ApplicationRecord
|
|
20
|
+
include AttrJson::Record
|
|
21
|
+
include AttrJson::NestedAttributes
|
|
22
|
+
include Spina::Partable
|
|
23
|
+
include Spina::TranslatedContent
|
|
24
|
+
# @!attribute [rw] number
|
|
25
|
+
# @return [Integer] The number
|
|
26
|
+
# @!attribute [rw] title
|
|
27
|
+
# @return [String] The title of the issue (optional)
|
|
28
|
+
# @!attribute [rw] date
|
|
29
|
+
# @return [Date] The (planned) publication date of the issue.
|
|
30
|
+
# @!attribute [rw] volume
|
|
31
|
+
# @return [ActiveRecord::Relation] the volume that contains this issue
|
|
32
|
+
belongs_to :volume
|
|
33
|
+
# @!attribute [rw] cover_img
|
|
34
|
+
# @return [Spina::Image, nil] the issue's cover image
|
|
35
|
+
belongs_to :cover_img, class_name: 'Spina::Image', optional: true
|
|
36
|
+
|
|
37
|
+
# @!attribute [rw] issue
|
|
38
|
+
# @return [ActiveRecord::Relation] the articles within this issue
|
|
39
|
+
has_many :articles, dependent: :destroy
|
|
40
|
+
|
|
41
|
+
validates :number, presence: true, uniqueness: { scope: :volume_id }
|
|
42
|
+
validates :date, presence: true
|
|
43
|
+
|
|
44
|
+
scope :sorted_asc, -> { includes(:volume).order('spina_admin_journal_volumes.number ASC', number: :asc) }
|
|
45
|
+
scope :sorted_desc, -> { includes(:volume).order('spina_admin_journal_volumes.number DESC', number: :desc) }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Journal records. The top level of the database hierarchy.
|
|
7
|
+
#
|
|
8
|
+
# There should only ever be a single Journal record, which must always be accessed
|
|
9
|
+
# using {Journal.instance}
|
|
10
|
+
#
|
|
11
|
+
# === Validatorss
|
|
12
|
+
# Presence:: {#name}, {#singleton_guard}
|
|
13
|
+
# Uniqueness:: {#name}, {#singleton_guard}
|
|
14
|
+
class Journal < ApplicationRecord
|
|
15
|
+
include AttrJson::Record
|
|
16
|
+
include AttrJson::NestedAttributes
|
|
17
|
+
include Spina::Partable
|
|
18
|
+
include Spina::TranslatedContent
|
|
19
|
+
# @!attribute [rw] name
|
|
20
|
+
# @return [String] The name of the journal.
|
|
21
|
+
# @!attribute [rw] singleton_guard
|
|
22
|
+
# @return [Integer] Used to guarantee that a record is unique.
|
|
23
|
+
# @!attribute [rw] logo
|
|
24
|
+
# @return [Spina::Image, nil] The Spina::Image representing the logo of the journal.
|
|
25
|
+
belongs_to :logo, class_name: 'Spina::Image', optional: true
|
|
26
|
+
|
|
27
|
+
# @!attribute [rw] volumes
|
|
28
|
+
# @return [ActiveRecord::Relation] directly associated volumes
|
|
29
|
+
has_many :volumes, dependent: :destroy
|
|
30
|
+
|
|
31
|
+
validates :name, presence: true, uniqueness: true
|
|
32
|
+
validates :singleton_guard, presence: true, uniqueness: true
|
|
33
|
+
|
|
34
|
+
# Access the journal record.
|
|
35
|
+
#
|
|
36
|
+
# It is possible that Journal.instance gets called from two threads simultaneously.
|
|
37
|
+
# If this occurs, +Journal.create!+ will throw a validation error, since both records will
|
|
38
|
+
# be assigned the same value for +singleton_guard+. This is handled automatically, guaranteeing
|
|
39
|
+
# that there only ever be a single record.
|
|
40
|
+
def self.instance
|
|
41
|
+
Journal.first || Journal.create!(name: I18n.t('spina.admin.journal.unnamed_journal'), singleton_guard: 0)
|
|
42
|
+
rescue ActiveRecord::RecordNotUnique
|
|
43
|
+
# prevent race conditions leading to multiple records being created
|
|
44
|
+
logger.error 'Error when retrieving Journal instance. Retrying...'
|
|
45
|
+
retry
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Volumes of a journal.
|
|
7
|
+
# A journal has multiple volumes, a volume can have multiple issues.
|
|
8
|
+
#
|
|
9
|
+
# === Validators
|
|
10
|
+
# Presence:: {#number}
|
|
11
|
+
# Uniqueness:: {#number} (scope: journal)
|
|
12
|
+
#
|
|
13
|
+
# === Scopes
|
|
14
|
+
# sorted_asc:: sorted in order of increasing number
|
|
15
|
+
# sorted_desc:: sorted highest number first
|
|
16
|
+
#
|
|
17
|
+
# @see Issue
|
|
18
|
+
# @see Journal
|
|
19
|
+
class Volume < ApplicationRecord
|
|
20
|
+
# @!attribute [rw] number
|
|
21
|
+
# @return [Integer]
|
|
22
|
+
# @!attribute [rw] journal
|
|
23
|
+
# @return [ActiveRecord::Relation] the journal that contains this volume
|
|
24
|
+
belongs_to :journal
|
|
25
|
+
|
|
26
|
+
# @!attribute [rw] journal
|
|
27
|
+
# @return [ActiveRecord::Relation] the issues that comprise this volume
|
|
28
|
+
has_many :issues, dependent: :destroy
|
|
29
|
+
|
|
30
|
+
validates :number, presence: true, uniqueness: { scope: :journal_id }
|
|
31
|
+
|
|
32
|
+
scope :sorted_asc, -> { order(number: :asc) }
|
|
33
|
+
scope :sorted_desc, -> { order(number: :desc) }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
module Spina
|
|
6
|
+
module Admin
|
|
7
|
+
module Journal
|
|
8
|
+
# A simple validator for URIs.
|
|
9
|
+
class UriValidator < ActiveModel::EachValidator
|
|
10
|
+
def validate_each(record, attribute, value)
|
|
11
|
+
return if value == '' || value.nil?
|
|
12
|
+
|
|
13
|
+
uri = URI.parse(value)
|
|
14
|
+
|
|
15
|
+
return if uri.is_a?(URI::HTTP) && !uri.host.nil?
|
|
16
|
+
|
|
17
|
+
record.errors.add attribute, :invalid_uri
|
|
18
|
+
rescue URI::InvalidURIError
|
|
19
|
+
record.errors.add attribute, :invalid_uri
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
%li{ class: ('active' if %w[articles issues volumes].include? controller_name) }
|
|
2
|
+
= link_to admin_journal_volumes_path do
|
|
3
|
+
= icon 'pages'
|
|
4
|
+
= ::Spina::Admin::Journal::Journal.instance.name
|
|
5
|
+
= icon 'caret-right'
|
|
6
|
+
|
|
7
|
+
%ul
|
|
8
|
+
%li{ class: ('active' if %w[volumes].include? controller_name) }
|
|
9
|
+
= link_to ::Spina::Admin::Journal::Volume.model_name.human(count: :many), admin_journal_volumes_path
|
|
10
|
+
%li{ class: ('active' if %w[issues].include? controller_name) }
|
|
11
|
+
= link_to ::Spina::Admin::Journal::Issue.model_name.human(count: :many), admin_journal_issues_path
|
|
12
|
+
%li{ class: ('active' if %w[articles].include? controller_name) }
|
|
13
|
+
= link_to ::Spina::Admin::Journal::Article.model_name.human(count: :many), admin_journal_articles_path
|
|
14
|
+
|
|
15
|
+
%li{ class: ('active' if %w[journals authors institutions].include? controller_name) }
|
|
16
|
+
= link_to edit_admin_journal_journal_path(::Spina::Admin::Journal::Journal.instance.id) do
|
|
17
|
+
= icon 'dots'
|
|
18
|
+
= t 'spina.admin.journal.navigation_title'
|
|
19
|
+
= icon 'caret-right'
|
|
20
|
+
|
|
21
|
+
%ul
|
|
22
|
+
%li{ class: ('active' if %w[journals].include? controller_name) }
|
|
23
|
+
= link_to ::Spina::Admin::Journal::Journal.model_name.human(count: :one), edit_admin_journal_journal_path(::Spina::Admin::Journal::Journal.instance.id)
|
|
24
|
+
%li{ class: ('active' if %w[authors].include? controller_name) }
|
|
25
|
+
= link_to ::Spina::Admin::Journal::Author.model_name.human(count: :many), admin_journal_authors_path
|
|
26
|
+
%li{ class: ('active' if %w[institutions].include? controller_name) }
|
|
27
|
+
= link_to ::Spina::Admin::Journal::Institution.model_name.human(count: :many), admin_journal_institutions_path
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
%tr{ data: { id: article.id } }
|
|
2
|
+
%td= article.issue.volume.number
|
|
3
|
+
%td= article.issue.number
|
|
4
|
+
%td.position-display= article.number
|
|
5
|
+
%td= time_tag article.issue.date, format: :iso8601
|
|
6
|
+
%td= article.title
|
|
7
|
+
%td.nowrap.align-right
|
|
8
|
+
= link_to edit_admin_journal_article_path(article.id), class: 'button button-link' do
|
|
9
|
+
= icon 'pencil-outline'
|
|
10
|
+
= t '.view'
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
- if @article.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= @article.errors.full_messages.join('<br />').html_safe
|
|
8
|
+
= link_to '#', data: { close_notification: true } do
|
|
9
|
+
= icon 'cross'
|
|
10
|
+
|
|
11
|
+
= form_for @article, html: { autocomplete: "off" } do |f|
|
|
12
|
+
%header#header
|
|
13
|
+
= render partial: 'spina/admin/shared/breadcrumbs'
|
|
14
|
+
|
|
15
|
+
#header_actions
|
|
16
|
+
%button.button.button-primary{ type: 'submit', style: 'margin-right: 0', data: { disable_with: t('spina.pages.saving') } }
|
|
17
|
+
= icon 'check'
|
|
18
|
+
= t '.save'
|
|
19
|
+
|
|
20
|
+
= link_to t('spina.cancel'), admin_journal_articles_path, class: 'button', style: 'margin-right: 0;'
|
|
21
|
+
|
|
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
|
+
#authors.tab-content= render 'form_authors', f: f
|
|
@@ -0,0 +1,10 @@
|
|
|
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 @article.affiliations.any? ? @article.affiliations : 'empty_list', message: t('.no_authors')
|