spina-admin-journal 0.6.2 → 1.0.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 +4 -4
- data/README.md +36 -48
- data/app/assets/config/spina_admin_journal_manifest.js +1 -2
- data/app/assets/javascripts/spina/admin/journal/application.js +0 -0
- data/app/components/spina/admin/journal/affiliations_list_component.rb +32 -0
- data/app/components/spina/admin/journal/application_component.rb +11 -0
- data/app/components/spina/admin/journal/articles_list_component.rb +54 -0
- data/app/components/spina/admin/journal/authors_list_component.rb +37 -0
- data/app/components/spina/admin/journal/authorships_list_component.rb +45 -0
- data/app/components/spina/admin/journal/empty_list_component.html.haml +1 -0
- data/app/components/spina/admin/journal/empty_list_component.rb +14 -0
- data/app/components/spina/admin/journal/form_group_component.html.haml +4 -0
- data/app/components/spina/admin/journal/form_group_component.rb +17 -0
- data/app/components/spina/admin/journal/institutions_list_component.rb +32 -0
- data/app/components/spina/admin/journal/issues_list_component.rb +47 -0
- data/app/components/spina/admin/journal/licences_list_component.rb +32 -0
- data/app/components/spina/admin/journal/list_component.html.haml +11 -0
- data/app/components/spina/admin/journal/list_component.rb +22 -0
- data/app/components/spina/admin/journal/list_item_component.html.haml +17 -0
- data/app/components/spina/admin/journal/list_item_component.rb +23 -0
- data/app/components/spina/admin/journal/volumes_list_component.rb +34 -0
- data/app/controllers/spina/admin/journal/application_controller.rb +1 -1
- data/app/controllers/spina/admin/journal/articles_controller.rb +18 -24
- data/app/controllers/spina/admin/journal/authors_controller.rb +18 -26
- data/app/controllers/spina/admin/journal/institutions_controller.rb +13 -5
- data/app/controllers/spina/admin/journal/issues_controller.rb +20 -27
- data/app/controllers/spina/admin/journal/journals_controller.rb +4 -1
- data/app/controllers/spina/admin/journal/licences_controller.rb +8 -4
- data/app/controllers/spina/admin/journal/volumes_controller.rb +16 -21
- data/app/models/spina/admin/journal/author.rb +1 -0
- data/app/models/spina/admin/journal/authorship.rb +9 -0
- data/app/views/spina/admin/hooks/journal/_primary_navigation.html.haml +35 -26
- data/app/views/spina/admin/journal/articles/_form.html.haml +23 -23
- data/app/views/spina/admin/journal/articles/_form_authors.html.haml +3 -15
- data/app/views/spina/admin/journal/articles/_form_details.html.haml +37 -56
- data/app/views/spina/admin/journal/articles/index.html.haml +7 -17
- data/app/views/spina/admin/journal/articles/view_authors.html.haml +2 -0
- data/app/views/spina/admin/journal/authors/_form.html.haml +24 -24
- data/app/views/spina/admin/journal/authors/_form_affiliation.html.haml +12 -20
- data/app/views/spina/admin/journal/authors/_form_articles.html.haml +3 -18
- data/app/views/spina/admin/journal/authors/_form_details.html.haml +27 -5
- data/app/views/spina/admin/journal/authors/index.html.haml +7 -15
- data/app/views/spina/admin/journal/authors/view_articles.html.haml +2 -0
- data/app/views/spina/admin/journal/institutions/_form.html.haml +24 -24
- data/app/views/spina/admin/journal/institutions/_form_details.html.haml +3 -8
- data/app/views/spina/admin/journal/institutions/_form_view_affiliations.html.haml +3 -10
- data/app/views/spina/admin/journal/institutions/index.html.haml +7 -15
- data/app/views/spina/admin/journal/institutions/view_affiliations.html.haml +2 -0
- data/app/views/spina/admin/journal/issues/_form.html.haml +23 -23
- data/app/views/spina/admin/journal/issues/_form_articles.html.haml +3 -14
- data/app/views/spina/admin/journal/issues/_form_details.html.haml +14 -28
- data/app/views/spina/admin/journal/issues/index.html.haml +7 -16
- data/app/views/spina/admin/journal/issues/view_articles.html.haml +3 -0
- data/app/views/spina/admin/journal/journals/_form.html.haml +22 -30
- data/app/views/spina/admin/journal/licences/_form.html.haml +24 -37
- data/app/views/spina/admin/journal/licences/index.html.haml +7 -16
- data/app/views/spina/admin/journal/volumes/_form.html.haml +25 -12
- data/app/views/spina/admin/journal/volumes/_form_details.html.haml +5 -10
- data/app/views/spina/admin/journal/volumes/_form_issues.html.haml +2 -13
- data/app/views/spina/admin/journal/volumes/index.html.haml +7 -16
- data/app/views/spina/admin/journal/volumes/view_issues.html.haml +2 -0
- data/app/views/spina/admin/parts/admin/journal/page_ranges/_form.html.haml +3 -4
- data/config/locales/en.yml +70 -8
- data/config/routes.rb +26 -6
- data/db/migrate/20220130171603_add_orcid_to_spina_admin_journal_author.rb +7 -0
- data/lib/spina/admin/journal/engine.rb +12 -0
- data/lib/spina/admin/journal/version.rb +1 -1
- data/lib/spina/admin/journal.rb +1 -0
- metadata +53 -63
- data/app/assets/javascripts/spina/admin/journal/application.es6 +0 -72
- data/app/views/layouts/spina/admin/journal/articles.html.haml +0 -10
- data/app/views/layouts/spina/admin/journal/authors.html.haml +0 -10
- data/app/views/layouts/spina/admin/journal/institutions.html.haml +0 -10
- data/app/views/layouts/spina/admin/journal/issues.html.haml +0 -10
- data/app/views/layouts/spina/admin/journal/journals.html.haml +0 -10
- data/app/views/layouts/spina/admin/journal/licences.html.haml +0 -10
- data/app/views/layouts/spina/admin/journal/volumes.html.haml +0 -10
- data/app/views/spina/admin/journal/affiliations/_affiliation.html.haml +0 -8
- data/app/views/spina/admin/journal/application/_empty_list.html.haml +0 -3
- data/app/views/spina/admin/journal/articles/_article.html.haml +0 -10
- data/app/views/spina/admin/journal/authors/_author.html.haml +0 -8
- data/app/views/spina/admin/journal/authorships/_authorship.html.haml +0 -9
- data/app/views/spina/admin/journal/institutions/_institution.html.haml +0 -9
- data/app/views/spina/admin/journal/issues/_issue.html.haml +0 -9
- data/app/views/spina/admin/journal/journals/index.html.haml +0 -27
- data/app/views/spina/admin/journal/licences/_licence.html.haml +0 -11
- data/app/views/spina/admin/journal/volumes/_volume.html.haml +0 -7
- data/vendor/assets/javascripts/spina/admin/journal/html5sortable.js +0 -1295
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a0055e328c3ad9ed3d723edb02c58062caf6621d4dd0a286021930957f42dd1
|
|
4
|
+
data.tar.gz: 303734e1e4dc5d2c90b45e24d2399872ada559e50ed60571316d35a48fbbd363
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8efcbe772ec874d7c1c5359b2ae00b62a9fba78af47a270371d3120f2845e11df8c808c3d7d3928ac97682dabb8d6cd5f365dbac94e4989c5da49f825e0c0a86
|
|
7
|
+
data.tar.gz: 0b2012a0505383c60e5fbd92c1c4718f76258032a7d428c0a6292f75dc9d87710fe43cf54ee1cb68fcf0164a8c1592df511174a2102cfb429ff1251ce6d1334d
|
data/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Spina::Admin::Journal
|
|
2
2
|
|
|
3
|
+
*Journal* is a plugin for [Spina](https://www.spinacms.com/) that provides a fully-fledged journal management package, intended to provide a more streamlined, easy-to-use, modern alternative to [OJS](https://pkp.sfu.ca/ojs/).
|
|
4
|
+
|
|
5
|
+
Spina is a content management system built in [Ruby on Rails](http://rubyonrails.org/). *Journal* augments Spina by providing an admin interface for managing an academic journal.
|
|
6
|
+
|
|
3
7
|

|
|
4
8
|
[](https://codecov.io/gh/louis-vs/spina-admin-journal)
|
|
5
9
|
[](https://www.codefactor.io/repository/github/louis-vs/spina-admin-journal)
|
|
@@ -7,69 +11,48 @@
|
|
|
7
11
|
[](https://lgtm.com/projects/g/louis-vs/spina-admin-journal/context:javascript)
|
|
8
12
|
[](http://inch-ci.org/github/louis-vs/spina-admin-journal)
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## Usage
|
|
13
|
-
|
|
14
|
-
The plugin adds two menus to Spina's primary navigation:
|
|
15
|
-
|
|
16
|
-
* **Journal settings** provides access to global properties of the journal. It is divided into 3 submenus:
|
|
17
|
-
* **Journal** allows you to change the name of the journal.
|
|
18
|
-
* **Institutions** allows you to add institutions, to which authors can be affiliated.
|
|
19
|
-
* **Authors** allows you to add authors, who can then be added to articles.
|
|
20
|
-
* The **journal content** menu will be named after the journal as specified in Journal Settings. It provides a means of editing the content of the journal and is divided into three submenus:
|
|
21
|
-
* **Volumes** allows you to add and remove volumes of the journal, and edit their respective issues.
|
|
22
|
-
* **Issues** allows you to add, edit and remove issues of particular volumes of the journal, and edit their respective articles.
|
|
23
|
-
* **Articles** allows you to add, edit and remove articles belonging to particular issues.
|
|
14
|
+
## Features
|
|
24
15
|
|
|
25
|
-
The plugin
|
|
16
|
+
The journal plugin covers many of the needs of a professional online journal publication, including:
|
|
26
17
|
|
|
27
|
-
|
|
18
|
+
- Simple, responsive, intuitive interface that builds upon Spina's own.
|
|
19
|
+
- Seamlessly integrate published content with other information about the journal.
|
|
20
|
+
- Manage volumes, issues, articles and authors in a highly structured and organised manner.
|
|
21
|
+
- Keep track of individual authors with multiple affiliations, e.g. if they change name or institution, connecting with [ORCID](https://orcid.org/).
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
### From scratch
|
|
32
|
-
|
|
33
|
-
Make sure you have a working installation of Ruby on Rails 6.1. You can find a setup guide [here](https://guides.rubyonrails.org/getting_started.html).
|
|
34
|
-
|
|
35
|
-
Then run:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
$ rails new your-app --database=postgresql
|
|
39
|
-
$ cd your-app
|
|
40
|
-
$ bin/rails db:create
|
|
41
|
-
$ bin/rails active_storage:install
|
|
42
|
-
```
|
|
23
|
+
Currently, a submissions management system is not included, but this is planned for a future release. This will allow you to manage the submissions process for the journal in a streamlined manner in parallel to publication.
|
|
43
24
|
|
|
44
|
-
|
|
25
|
+
## Usage
|
|
45
26
|
|
|
46
|
-
|
|
47
|
-
gem 'spina', '~> 2.0'
|
|
48
|
-
```
|
|
27
|
+
The plugin adds two menus to Spina's primary navigation:
|
|
49
28
|
|
|
50
|
-
|
|
29
|
+
- **Journal settings** provides access to global properties of the journal. It is divided into 3 submenus:
|
|
30
|
+
- **Journal** allows you to change metadata such as the name of the journal, as well as content that will appear on the journal homepage.
|
|
31
|
+
- **Institutions** allows you to add institutions, to which authors can be affiliated.
|
|
32
|
+
- **Authors** allows you to add authors and their affiliations, which can then be added to articles.
|
|
33
|
+
- **Licences** allows you to add licences and association information, which can be associated with individual articles, representing the licence under which the content is released.
|
|
34
|
+
- The **journal content** menu will be named after the journal as specified in Journal Settings. It provides a means of editing the content of the journal and is divided into three submenus:
|
|
35
|
+
- **Volumes** allows you to add and remove volumes of the journal, and edit their respective issues.
|
|
36
|
+
- **Issues** allows you to add, edit and remove issues of particular volumes of the journal, and edit their respective articles.
|
|
37
|
+
- **Articles** allows you to add, edit and remove articles belonging to particular issues.
|
|
51
38
|
|
|
52
|
-
|
|
53
|
-
$ bundle install
|
|
54
|
-
```
|
|
39
|
+
**NB:** This release of the plugin does not provide any public-facing frontend or Spina theme. An example implementation can be found within the [Conferences Primer Theme](https://github.com/louis-vs/spina-conferences-primer_theme-fork). Note that this theme also contains frontends for two other Spina plugins, [Spina Conferences Blog](https://github.com/louis-vs/spina-admin-conferences-blog) and [Spina Admin Conferences](https://github.com/louis-vs/spina-admin-conferences-fork/). You can use the theme in your project as is, or copy whichever parts of the code you need.
|
|
55
40
|
|
|
56
|
-
|
|
41
|
+
A dedicated journal theme, coupled with an automatic installer, is being planned. A system to manage submissions is also on the roadmap.
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
$ bin/rails g spina:install
|
|
60
|
-
```
|
|
43
|
+
## Installation
|
|
61
44
|
|
|
62
|
-
|
|
45
|
+
Make sure you have a working installation of Ruby on Rails 7. You can find a setup guide [here](https://guides.rubyonrails.org/getting_started.html).
|
|
63
46
|
|
|
64
|
-
|
|
47
|
+
You then need to install Spina, following the guide [on the Spina website](https://spinacms.com/docs).
|
|
65
48
|
|
|
66
|
-
|
|
49
|
+
To install the plugin, add this line to your application's Gemfile:
|
|
67
50
|
|
|
68
51
|
```ruby
|
|
69
|
-
gem 'spina-admin-journal', '~> 0
|
|
52
|
+
gem 'spina-admin-journal', '~> 1.0'
|
|
70
53
|
```
|
|
71
54
|
|
|
72
|
-
|
|
55
|
+
Then execute:
|
|
73
56
|
|
|
74
57
|
```bash
|
|
75
58
|
$ bundle install
|
|
@@ -78,7 +61,7 @@ $ bundle install
|
|
|
78
61
|
You'll then need to install and run the migrations for the journal:
|
|
79
62
|
|
|
80
63
|
```bash
|
|
81
|
-
$ bin/rails
|
|
64
|
+
$ bin/rails spina_admin_journal:install:migrations
|
|
82
65
|
$ bin/rails db:migrate
|
|
83
66
|
```
|
|
84
67
|
|
|
@@ -94,6 +77,11 @@ You can manually populate the database from within the app, or alternatively you
|
|
|
94
77
|
|
|
95
78
|
Bug reports and feature requests are welcome in the [Issues](https://github.com/louis-vs/spina-admin-journal/issues) section. Translations are also very welcome!
|
|
96
79
|
|
|
80
|
+
### Planned features
|
|
81
|
+
|
|
82
|
+
- [ ] Submissions management
|
|
83
|
+
- [ ] Translations
|
|
84
|
+
|
|
97
85
|
## License
|
|
98
86
|
|
|
99
87
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A list of licences. Not sortable.
|
|
7
|
+
class AffiliationsListComponent < ListComponent
|
|
8
|
+
def initialize(affiliations:)
|
|
9
|
+
@affiliations = affiliations
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def before_render
|
|
13
|
+
@list_items = generate_list_items(@affiliations)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
render ListComponent.new(list_items: @list_items, sortable: false)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def generate_list_items(affiliations)
|
|
23
|
+
affiliations.map do |affiliation|
|
|
24
|
+
{ id: affiliation.id,
|
|
25
|
+
label: affiliation.reversed_name,
|
|
26
|
+
path: helpers.spina.edit_admin_journal_author_path(affiliation.author) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A list of articles. Articles should only be sortable if presented within the contex of an
|
|
7
|
+
# issue.
|
|
8
|
+
class ArticlesListComponent < ListComponent
|
|
9
|
+
attr_reader :sortable
|
|
10
|
+
|
|
11
|
+
def initialize(articles:, sortable: false)
|
|
12
|
+
@articles = articles
|
|
13
|
+
@sortable = sortable
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def before_render
|
|
17
|
+
@list_items = generate_list_items(@articles)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call
|
|
21
|
+
render ListComponent.new(list_items: @list_items,
|
|
22
|
+
sortable: sortable?,
|
|
23
|
+
sort_path: generate_sort_path)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def sortable?
|
|
27
|
+
sortable
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def generate_list_items(articles)
|
|
33
|
+
articles.map do |article|
|
|
34
|
+
{ id: article.id,
|
|
35
|
+
label: generate_label(article),
|
|
36
|
+
path: helpers.spina.edit_admin_journal_article_path(article.id) }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def generate_label(article) # rubocop:disable Metrics/AbcSize
|
|
41
|
+
t('spina.admin.journal.articles.article_number', volume_number: article.issue.volume.number, # rubocop:disable Style/StringConcatenation
|
|
42
|
+
issue_number: article.issue.number,
|
|
43
|
+
article_number: article.number
|
|
44
|
+
) + ' | ' + t('spina.admin.journal.articles.title_author', title: article.title, # rubocop:disable Layout/MultilineMethodCallBraceLayout Layout/SpaceInsideParens
|
|
45
|
+
author: article.authorships.sorted_within_article.map { |authorship| authorship.affiliation.surname }.join(', ')) # rubocop:disable Layout/LineLength
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def generate_sort_path
|
|
49
|
+
@articles.any? ? helpers.spina.sort_admin_journal_issues_path(@articles.first.issue.id) : ''
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A list of authors. Not sortable.
|
|
7
|
+
class AuthorsListComponent < ListComponent
|
|
8
|
+
def initialize(authors:)
|
|
9
|
+
@authors = authors
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def before_render
|
|
13
|
+
@list_items = generate_list_items(@authors)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
render ListComponent.new(list_items: @list_items, sortable: false)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def generate_list_items(authors)
|
|
23
|
+
authors.map do |author|
|
|
24
|
+
{ id: author.id,
|
|
25
|
+
label: generate_label(author),
|
|
26
|
+
path: helpers.spina.edit_admin_journal_author_path(author) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def generate_label(author)
|
|
31
|
+
t 'spina.admin.journal.authors.name_institution', name: author.primary_affiliation.name,
|
|
32
|
+
institution: author.primary_affiliation.institution.name
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A list of authorships. Sortable when displayed in their corresponding article.
|
|
7
|
+
class AuthorshipsListComponent < ListComponent
|
|
8
|
+
attr_reader :sortable
|
|
9
|
+
|
|
10
|
+
def initialize(authorships:, sortable: false)
|
|
11
|
+
@authorships = authorships
|
|
12
|
+
@sortable = sortable
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def before_render
|
|
16
|
+
@list_items = generate_list_items(@authorships)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def call
|
|
20
|
+
render ListComponent.new(list_items: @list_items,
|
|
21
|
+
sortable: sortable?,
|
|
22
|
+
sort_path: generate_sort_path)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def sortable?
|
|
26
|
+
sortable
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def generate_list_items(authorships)
|
|
32
|
+
authorships.map do |authorship|
|
|
33
|
+
{ id: authorship.id,
|
|
34
|
+
label: authorship.affiliation.reversed_name,
|
|
35
|
+
path: helpers.spina.edit_admin_journal_author_path(authorship.affiliation.author) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def generate_sort_path
|
|
40
|
+
@authorships.any? ? helpers.spina.sort_admin_journal_authors_path(@authorships.first.article.id) : ''
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= @message
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Displays a message indicating that a {ListComponent} has no items.
|
|
7
|
+
class EmptyListComponent < ApplicationComponent
|
|
8
|
+
def initialize(message: t('spina.admin.journal.empty_list'))
|
|
9
|
+
@message = message
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# Correctly styles label, description and content of form fields.
|
|
7
|
+
class FormGroupComponent < ApplicationComponent
|
|
8
|
+
attr_reader :label, :description
|
|
9
|
+
|
|
10
|
+
def initialize(label:, description: '')
|
|
11
|
+
@label = label
|
|
12
|
+
@description = description
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A list of institutions. Not sortable.
|
|
7
|
+
class InstitutionsListComponent < ListComponent
|
|
8
|
+
def initialize(institutions:)
|
|
9
|
+
@institutions = institutions
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def before_render
|
|
13
|
+
@list_items = generate_list_items(@institutions)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
render ListComponent.new(list_items: @list_items, sortable: false)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def generate_list_items(institutions)
|
|
23
|
+
institutions.map do |institution|
|
|
24
|
+
{ id: institution.id,
|
|
25
|
+
label: institution.name,
|
|
26
|
+
path: helpers.spina.edit_admin_journal_institution_path(institution.id) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A list of issues. Issues should only be sortable if presented within the contex of a
|
|
7
|
+
# volume.
|
|
8
|
+
class IssuesListComponent < ListComponent
|
|
9
|
+
attr_reader :sortable
|
|
10
|
+
|
|
11
|
+
def initialize(issues:, sortable: false)
|
|
12
|
+
@issues = issues
|
|
13
|
+
@sortable = sortable
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def before_render
|
|
17
|
+
@list_items = generate_list_items(@issues)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call
|
|
21
|
+
render ListComponent.new(list_items: @list_items,
|
|
22
|
+
sortable: sortable?,
|
|
23
|
+
sort_path: generate_sort_path)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def sortable?
|
|
27
|
+
sortable
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def generate_list_items(issues)
|
|
33
|
+
issues.map do |issue|
|
|
34
|
+
{ id: issue.id,
|
|
35
|
+
label: t('spina.admin.journal.issues.volume_issue', volume_number: issue.volume.number,
|
|
36
|
+
issue_number: issue.number),
|
|
37
|
+
path: helpers.spina.edit_admin_journal_issue_path(issue.id) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def generate_sort_path
|
|
42
|
+
@issues.any? ? helpers.spina.sort_admin_journal_issues_path(@issues.first.volume.id) : ''
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A list of licences. Not sortable.
|
|
7
|
+
class LicencesListComponent < ListComponent
|
|
8
|
+
def initialize(licences:)
|
|
9
|
+
@licences = licences
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def before_render
|
|
13
|
+
@list_items = generate_list_items(@licences)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
render ListComponent.new(list_items: @list_items, sortable: false)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def generate_list_items(licences)
|
|
23
|
+
licences.map do |licence|
|
|
24
|
+
{ id: licence.id,
|
|
25
|
+
label: licence.name,
|
|
26
|
+
path: helpers.spina.edit_admin_journal_licence_path(licence) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
.my-6.md:m-8
|
|
2
|
+
- if sortable?
|
|
3
|
+
.mb-4.text-gray-600.text-sm= t 'spina.admin.journal.sort_info'
|
|
4
|
+
.bg-white.md:rounded-lg.border-l-0.border-r-0.border.md:border-r.md:border-l.border-gray-200.border-b-0.shadow-sm{ data: { controller: 'sortable' } }
|
|
5
|
+
= form_with(url: @sort_path, data: { sortable_target: 'form' }) { |f| }
|
|
6
|
+
%ul{ data: { sortable_target: 'list' } }
|
|
7
|
+
- if @list_items.any?
|
|
8
|
+
- @list_items.each do |item|
|
|
9
|
+
= render Spina::Admin::Journal::ListItemComponent.new(id: item[:id], label: item[:label], path: item[:path], sortable: sortable?)
|
|
10
|
+
- else
|
|
11
|
+
= render Spina::Admin::Journal::EmptyListComponent.new
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A generic implementation of a list, resembling Spina's page list.
|
|
7
|
+
class ListComponent < ApplicationComponent
|
|
8
|
+
attr_reader :sortable
|
|
9
|
+
|
|
10
|
+
def initialize(list_items:, sortable: false, sort_path: '')
|
|
11
|
+
@sortable = sortable
|
|
12
|
+
@list_items = list_items
|
|
13
|
+
@sort_path = sort_path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def sortable?
|
|
17
|
+
sortable
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
%li{data: { id: @id }}
|
|
2
|
+
.flex.items-center.border-gray-200.border-b.bg-opacity-50.w-full
|
|
3
|
+
- if sortable?
|
|
4
|
+
.p-4.text-gray-300.hover:text-gray-600.cursor-move{ data: { 'sortable-handle': true } }
|
|
5
|
+
= helpers.heroicon('menu-alt-4', style: :solid, class: 'w-4 h-4 -mr-4')
|
|
6
|
+
|
|
7
|
+
.flex-auto
|
|
8
|
+
.block.text-spina.font-medium.text-sm.p-4{class: 'hover:text-spina-dark' }
|
|
9
|
+
= link_to @path do
|
|
10
|
+
= @label
|
|
11
|
+
|
|
12
|
+
.flex-1
|
|
13
|
+
|
|
14
|
+
= link_to @path, class: 'btn btn-link mr-4' do
|
|
15
|
+
.flex.flex-nowrap.items-center.px-8.py-1
|
|
16
|
+
= helpers.heroicon 'pencil-alt', style: :outline, class: 'w-4 h-4'
|
|
17
|
+
.ml-2= t 'spina.admin.journal.edit'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A generic list item that is only intended to be called by {ListItemComponent}.
|
|
7
|
+
class ListItemComponent < ApplicationComponent
|
|
8
|
+
attr_reader :sortable
|
|
9
|
+
|
|
10
|
+
def initialize(id:, label:, path:, sortable: false)
|
|
11
|
+
@label = label
|
|
12
|
+
@id = id
|
|
13
|
+
@path = path
|
|
14
|
+
@sortable = sortable
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def sortable?
|
|
18
|
+
sortable
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spina
|
|
4
|
+
module Admin
|
|
5
|
+
module Journal
|
|
6
|
+
# A sortable list of volumes.
|
|
7
|
+
class VolumesListComponent < ListComponent
|
|
8
|
+
def initialize(volumes:)
|
|
9
|
+
@volumes = volumes
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def before_render
|
|
13
|
+
@list_items = generate_list_items(@volumes)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call
|
|
17
|
+
render ListComponent.new(list_items: @list_items,
|
|
18
|
+
sortable: true,
|
|
19
|
+
sort_path: helpers.spina.sort_admin_journal_volumes_path(Journal.instance.id))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def generate_list_items(volumes)
|
|
25
|
+
volumes.map do |volume|
|
|
26
|
+
{ id: volume.id,
|
|
27
|
+
label: t('spina.admin.journal.volumes.volume_number', number: volume.number),
|
|
28
|
+
path: helpers.spina.edit_admin_journal_volume_path(volume.id) }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|