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.
- 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 +55 -65
- 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: f786acd82a7df514c811bd3fd8fd06220b030d58858b1897bde326f62ee03d3c
|
4
|
+
data.tar.gz: 8b02e8903963f11402ce612ac7a53c77c851dc17ba5425edf333eab8c875ab07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50c4507b1747a4a17db2b16836626f72cc8d149676af9ef9e442daa81e192af21bce6c913168e8f570474d2f0052b5cc5df1fde1c8e4c3d963fc85f07ac66eb0
|
7
|
+
data.tar.gz: 4f8a96788318d91f69911489a979a258c87020690e3a6e6f5ec006911a140388a77056e9e2ff83434eedbfc8944437bbf4c445b9b4c088c1af8acf60c724c877
|
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
|
![Rails tests](https://github.com/louis-vs/spina-admin-journal/workflows/Verify/badge.svg?branch=master&event=push)
|
4
8
|
[![codecov](https://codecov.io/gh/louis-vs/spina-admin-journal/branch/master/graph/badge.svg?token=9TZ9QGGLAH)](https://codecov.io/gh/louis-vs/spina-admin-journal)
|
5
9
|
[![CodeFactor](https://www.codefactor.io/repository/github/louis-vs/spina-admin-journal/badge)](https://www.codefactor.io/repository/github/louis-vs/spina-admin-journal)
|
@@ -7,69 +11,48 @@
|
|
7
11
|
[![Code quality: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/louis-vs/spina-admin-journal.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/louis-vs/spina-admin-journal/context:javascript)
|
8
12
|
[![Inline docs](http://inch-ci.org/github/louis-vs/spina-admin-journal.svg?branch=master)](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
|