headmin 0.1.1 → 0.2.2
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/Gemfile +0 -1
- data/Gemfile.lock +24 -2
- data/README.md +8 -43
- data/app/controllers/concerns/headmin/authentication.rb +0 -8
- data/app/controllers/concerns/headmin/pagination.rb +1 -1
- data/app/helpers/headmin/admin_helper.rb +4 -4
- data/app/models/concerns/headmin/block.rb +11 -0
- data/app/models/concerns/headmin/blockable.rb +10 -0
- data/app/models/concerns/headmin/field.rb +17 -0
- data/app/models/concerns/headmin/fieldable.rb +44 -0
- data/app/services/block_service.rb +68 -0
- data/app/views/{layouts → examples}/admin.html.erb +0 -0
- data/app/views/{layouts/admin → examples}/auth.html.erb +0 -0
- data/app/views/headmin/_blocks.html.erb +24 -0
- data/app/views/headmin/_breadcrumbs.html.erb +9 -5
- data/app/views/headmin/_card.html.erb +48 -0
- data/app/views/headmin/_dropdown.html.erb +18 -0
- data/app/views/headmin/_filters.html.erb +56 -34
- data/app/views/headmin/_form.html.erb +60 -6
- data/app/views/headmin/_heading.html.erb +8 -4
- data/app/views/headmin/_index.html.erb +9 -8
- data/app/views/headmin/_notifications.html.erb +8 -0
- data/app/views/headmin/_pagination.html.erb +11 -7
- data/app/views/headmin/_popup.html.erb +26 -0
- data/app/views/headmin/_table.html.erb +11 -4
- data/app/views/headmin/dropdown/_button.html.erb +13 -0
- data/app/views/headmin/dropdown/_devise.html.erb +21 -0
- data/app/views/headmin/{layout/dropdown → dropdown}/_divider.html.erb +1 -1
- data/app/views/headmin/dropdown/_item.html.erb +18 -0
- data/app/views/headmin/dropdown/_list.html.erb +11 -0
- data/app/views/headmin/dropdown/_locale.html.erb +17 -0
- data/app/views/headmin/filters/_date.html.erb +21 -16
- data/app/views/headmin/filters/_search.html.erb +18 -18
- data/app/views/headmin/filters/_select.html.erb +28 -23
- data/app/views/headmin/filters/filter/_button.html.erb +15 -6
- data/app/views/headmin/filters/filter/_menu_item.html.erb +2 -2
- data/app/views/headmin/filters/filter/_template.html.erb +2 -2
- data/app/views/headmin/forms/_actions.html.erb +4 -8
- data/app/views/headmin/forms/_base.html.erb +60 -0
- data/app/views/headmin/forms/_blocks.html.erb +32 -0
- data/app/views/headmin/forms/_checkbox.html.erb +39 -0
- data/app/views/headmin/forms/_ckeditor.html.erb +42 -0
- data/app/views/headmin/forms/_date.html.erb +45 -0
- data/app/views/headmin/forms/_email.html.erb +39 -0
- data/app/views/headmin/forms/_file.html.erb +40 -0
- data/app/views/headmin/forms/_image.html.erb +55 -0
- data/app/views/headmin/forms/_label.html.erb +24 -0
- data/app/views/headmin/forms/_number.html.erb +50 -0
- data/app/views/headmin/forms/_password.html.erb +69 -0
- data/app/views/headmin/forms/_redactorx.html.erb +49 -0
- data/app/views/headmin/forms/_repeater.html.erb +133 -0
- data/app/views/headmin/forms/_select.html.erb +70 -0
- data/app/views/headmin/forms/_text.html.erb +62 -0
- data/app/views/headmin/forms/_textarea.html.erb +39 -0
- data/app/views/headmin/forms/_url.html.erb +39 -0
- data/app/views/headmin/forms/_validation.html.erb +21 -0
- data/app/views/headmin/forms/actions/_destroy.html.erb +13 -0
- data/app/views/headmin/forms/actions/_save.html.erb +12 -0
- data/app/views/headmin/forms/actions/_view.html.erb +15 -0
- data/app/views/headmin/forms/fields/_base.html.erb +25 -0
- data/app/views/headmin/forms/fields/_file.html.erb +15 -22
- data/app/views/headmin/forms/fields/_group.html.erb +38 -0
- data/app/views/headmin/forms/fields/_image.html.erb +15 -35
- data/app/views/headmin/forms/fields/_list.html.erb +26 -0
- data/app/views/headmin/forms/fields/_text.html.erb +15 -37
- data/app/views/headmin/forms/repeater/_row.html.erb +51 -0
- data/app/views/headmin/heading/_title.html.erb +1 -1
- data/app/views/headmin/layout/_body.html.erb +1 -1
- data/app/views/headmin/layout/_content.html.erb +1 -1
- data/app/views/headmin/layout/_footer.html.erb +1 -1
- data/app/views/headmin/layout/_header.html.erb +1 -1
- data/app/views/headmin/layout/_main.html.erb +2 -2
- data/app/views/headmin/layout/_sidebar.html.erb +1 -1
- data/app/views/headmin/layout/sidebar/{_menu.html.erb → _nav.html.erb} +1 -1
- data/app/views/headmin/nav/_item.html.erb +21 -0
- data/app/views/headmin/nav/item/_devise.html.erb +21 -0
- data/app/views/headmin/nav/item/_locale.html.erb +17 -0
- data/app/views/headmin/pagination/_per_page.html.erb +18 -0
- data/app/views/headmin/{kaminari → pagination/kaminari}/_first_page.html.erb +0 -0
- data/app/views/headmin/{kaminari → pagination/kaminari}/_gap.html.erb +0 -0
- data/app/views/headmin/{kaminari → pagination/kaminari}/_last_page.html.erb +0 -0
- data/app/views/headmin/{kaminari → pagination/kaminari}/_next_page.html.erb +0 -0
- data/app/views/headmin/{kaminari → pagination/kaminari}/_page.html.erb +1 -1
- data/app/views/headmin/{kaminari → pagination/kaminari}/_paginator.html.erb +0 -0
- data/app/views/headmin/{kaminari → pagination/kaminari}/_prev_page.html.erb +0 -0
- data/app/views/headmin/table/_actions.html.erb +24 -17
- data/app/views/headmin/table/_body.html.erb +12 -10
- data/app/views/headmin/table/_foot.html.erb +8 -4
- data/app/views/headmin/table/_footer.html.erb +3 -7
- data/app/views/headmin/table/_head.html.erb +3 -1
- data/app/views/headmin/table/_header.html.erb +3 -7
- data/app/views/headmin/table/actions/_action.html.erb +26 -9
- data/app/views/headmin/table/actions/_delete.html.erb +11 -7
- data/app/views/headmin/table/actions/_export.html.erb +11 -7
- data/app/views/headmin/table/body/_association.html.erb +1 -1
- data/app/views/headmin/table/body/_boolean.erb +1 -1
- data/app/views/headmin/table/body/_currency.html.erb +1 -1
- data/app/views/headmin/table/body/_date.html.erb +1 -1
- data/app/views/headmin/table/body/_id.html.erb +2 -2
- data/app/views/headmin/table/body/_row.html.erb +1 -1
- data/app/views/headmin/table/body/_string.html.erb +1 -1
- data/app/views/headmin/table/body/_text.html.erb +1 -1
- data/app/views/headmin/table/foot/_cell.html.erb +1 -1
- data/app/views/headmin/table/foot/_id.html.erb +2 -2
- data/app/views/headmin/table/head/_cell.html.erb +1 -1
- data/app/views/headmin/table/head/_id.html.erb +3 -3
- data/app/views/headmin/views/devise/confirmations/_new.html.erb +9 -0
- data/app/views/headmin/views/devise/passwords/_edit.html.erb +12 -0
- data/app/views/headmin/views/devise/passwords/_new.html.erb +9 -0
- data/app/views/{admin/users/registrations/edit.html.erb → headmin/views/devise/registrations/_edit.html.erb} +5 -5
- data/app/views/headmin/views/devise/registrations/_new.html.erb +11 -0
- data/app/views/headmin/views/devise/sessions/_new.html.erb +13 -0
- data/app/views/{admin/users → headmin/views/devise}/shared/_error_messages.html.erb +0 -0
- data/app/views/{admin/users → headmin/views/devise}/shared/_links.html.erb +0 -0
- data/app/views/headmin/views/devise/unlocks/_new.html.erb +10 -0
- data/config/initializers/customize_input_error.rb +9 -0
- data/config/locales/devise/en.yml +65 -0
- data/config/locales/en.yml +2 -134
- data/config/locales/headmin/filters/en.yml +13 -0
- data/config/locales/headmin/filters/nl.yml +13 -0
- data/config/locales/headmin/forms/en.yml +34 -0
- data/config/locales/headmin/forms/nl.yml +33 -0
- data/config/locales/headmin/heading/en.yml +5 -0
- data/config/locales/headmin/heading/nl.yml +5 -0
- data/config/locales/headmin/layout/en.yml +14 -0
- data/config/locales/headmin/layout/nl.yml +14 -0
- data/config/locales/headmin/pagination/en.yml +21 -0
- data/config/locales/headmin/pagination/nl.yml +21 -0
- data/config/locales/headmin/table/en.yml +23 -0
- data/config/locales/headmin/table/nl.yml +23 -0
- data/config/locales/headmin/views/en.yml +58 -0
- data/config/locales/headmin/views/nl.yml +58 -0
- data/config/locales/nl.yml +2 -135
- data/dist/css/headmin.css +3182 -743
- data/dist/js/headmin.js +729 -33
- data/docs/README.md +2 -1
- data/docs/blocks.md +70 -85
- data/docs/devise.md +1 -60
- data/docs/fields.md +57 -0
- data/headmin.gemspec +1 -0
- data/lib/generators/headmin/blocks_generator.rb +19 -0
- data/lib/generators/headmin/fields_generator.rb +19 -0
- data/lib/generators/templates/migrations/create_blocks.rb +10 -0
- data/lib/generators/templates/migrations/create_fields.rb +13 -0
- data/lib/generators/templates/models/block.rb +3 -0
- data/lib/generators/templates/models/field.rb +3 -0
- data/lib/headmin/version.rb +1 -1
- data/package.json +6 -6
- data/src/js/headmin/controllers/blocks_controller.js +103 -0
- data/src/js/headmin/controllers/filters_controller.js +23 -12
- data/src/js/headmin/controllers/popup_controller.js +68 -0
- data/src/js/headmin/controllers/repeater_controller.js +117 -11
- data/src/js/headmin/controllers/table_actions_controller.js +16 -5
- data/src/js/headmin/controllers/table_controller.js +84 -1
- data/src/js/headmin/headmin.js +29 -56
- data/src/scss/headmin/filters.scss +0 -14
- data/src/scss/headmin/form.scss +43 -3
- data/src/scss/headmin/popup.scss +17 -0
- data/src/scss/headmin/table.scss +9 -6
- data/src/scss/headmin.scss +7 -4
- data/src/scss/vendor/redactorx/override.css +3 -0
- data/src/scss/vendor/redactorx/redactorx.css +1460 -0
- data/yarn.lock +105 -2210
- metadata +108 -62
- data/app/controllers/admin/users/confirmations_controller.rb +0 -31
- data/app/controllers/admin/users/omniauth_callbacks_controller.rb +0 -31
- data/app/controllers/admin/users/passwords_controller.rb +0 -35
- data/app/controllers/admin/users/registrations_controller.rb +0 -63
- data/app/controllers/admin/users/sessions_controller.rb +0 -28
- data/app/controllers/admin/users/unlocks_controller.rb +0 -31
- data/app/views/admin/users/confirmations/new.html.erb +0 -9
- data/app/views/admin/users/mailer/confirmation_instructions.html.erb +0 -5
- data/app/views/admin/users/mailer/email_changed.html.erb +0 -7
- data/app/views/admin/users/mailer/password_change.html.erb +0 -3
- data/app/views/admin/users/mailer/reset_password_instructions.html.erb +0 -8
- data/app/views/admin/users/mailer/unlock_instructions.html.erb +0 -7
- data/app/views/admin/users/passwords/edit.html.erb +0 -12
- data/app/views/admin/users/passwords/new.html.erb +0 -9
- data/app/views/admin/users/registrations/new.html.erb +0 -11
- data/app/views/admin/users/sessions/new.html.erb +0 -13
- data/app/views/admin/users/unlocks/new.html.erb +0 -10
- data/app/views/headmin/forms/_group.html.erb +0 -36
- data/app/views/headmin/forms/fields/_checkbox.html.erb +0 -23
- data/app/views/headmin/forms/fields/_ckeditor.html.erb +0 -28
- data/app/views/headmin/forms/fields/_currency.html.erb +0 -24
- data/app/views/headmin/forms/fields/_date.html.erb +0 -36
- data/app/views/headmin/forms/fields/_email.html.erb +0 -39
- data/app/views/headmin/forms/fields/_label.html.erb +0 -9
- data/app/views/headmin/forms/fields/_multiple_select.html.erb +0 -37
- data/app/views/headmin/forms/fields/_password.html.erb +0 -39
- data/app/views/headmin/forms/fields/_repeater.html.erb +0 -48
- data/app/views/headmin/forms/fields/_select.html.erb +0 -36
- data/app/views/headmin/forms/fields/_select_tags.html.erb +0 -32
- data/app/views/headmin/forms/fields/_textarea.html.erb +0 -29
- data/app/views/headmin/forms/fields/_url.html.erb +0 -38
- data/app/views/headmin/forms/fields/_validation.html.erb +0 -12
- data/app/views/headmin/forms/fields/repeater/_row.html.erb +0 -16
- data/app/views/headmin/layout/dropdown/_item.html.erb +0 -17
- data/app/views/headmin/layout/header/_account.html.erb +0 -25
- data/app/views/headmin/layout/header/_locale.html.erb +0 -19
- data/app/views/headmin/layout/sidebar/menu/_account.html.erb +0 -25
- data/app/views/headmin/layout/sidebar/menu/_item.html.erb +0 -16
- data/app/views/headmin/layout/sidebar/menu/_locale.html.erb +0 -18
- data/src/js/headmin/controllers/index_controller.js +0 -79
- data/src/js/headmin/controllers/repeater_row_controller.js +0 -54
- data/src/scss/vendor/choices/cross-inverse.svg +0 -6
- data/src/scss/vendor/choices/cross.svg +0 -6
- data/src/scss/vendor/choices/custom.scss +0 -28
- data/src/scss/vendor/choices/variables.scss +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b4489879289d2643f3045d91f28b3530f3c21e5a888246ceb36029106ea0692
|
4
|
+
data.tar.gz: 0e161c13ca9f3fd26f96401eefea905cd3858d0c3b3dfe86cd8ce4bda718d8f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78d063e6e740edba6d1a849e1bacbff2a8750300848c20134b3e15bc5217b216e53a15be5d923de6671aecf768ce98c41cffa31bbd8939abd42e6a12ee877c7f
|
7
|
+
data.tar.gz: c515db4260d09f9a402d8b46d7d8b36acc10a3dbad433248a19716c5b3b59459ee965dfc8a862d8a35137b58aa4b8af734a6ef73a094b425a9f6ee81140a7261
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,30 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
headmin (0.1
|
4
|
+
headmin (0.2.1)
|
5
|
+
closure_tree (~> 7.3)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
8
9
|
specs:
|
10
|
+
activemodel (6.1.4.1)
|
11
|
+
activesupport (= 6.1.4.1)
|
12
|
+
activerecord (6.1.4.1)
|
13
|
+
activemodel (= 6.1.4.1)
|
14
|
+
activesupport (= 6.1.4.1)
|
15
|
+
activesupport (6.1.4.1)
|
16
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
|
+
i18n (>= 1.6, < 2)
|
18
|
+
minitest (>= 5.1)
|
19
|
+
tzinfo (~> 2.0)
|
20
|
+
zeitwerk (~> 2.3)
|
9
21
|
ast (2.4.2)
|
22
|
+
closure_tree (7.4.0)
|
23
|
+
activerecord (>= 4.2.10)
|
24
|
+
with_advisory_lock (>= 4.0.0)
|
25
|
+
concurrent-ruby (1.1.9)
|
26
|
+
i18n (1.8.10)
|
27
|
+
concurrent-ruby (~> 1.0)
|
10
28
|
minitest (5.14.4)
|
11
29
|
parallel (1.20.1)
|
12
30
|
parser (3.0.0.0)
|
@@ -27,11 +45,15 @@ GEM
|
|
27
45
|
rubocop-ast (1.4.1)
|
28
46
|
parser (>= 2.7.1.5)
|
29
47
|
ruby-progressbar (1.11.0)
|
48
|
+
tzinfo (2.0.4)
|
49
|
+
concurrent-ruby (~> 1.0)
|
30
50
|
unicode-display_width (2.0.0)
|
51
|
+
with_advisory_lock (4.6.0)
|
52
|
+
activerecord (>= 4.2)
|
53
|
+
zeitwerk (2.5.1)
|
31
54
|
|
32
55
|
PLATFORMS
|
33
56
|
x86_64-darwin-19
|
34
|
-
x86_64-darwin-20
|
35
57
|
|
36
58
|
DEPENDENCIES
|
37
59
|
headmin!
|
data/README.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# Headmin
|
2
2
|
A complete library of commonly used components to build an admin interface in your Ruby on Rails project.
|
3
3
|
|
4
|
-
|
4
|
+
## Interesting links
|
5
|
+
- [Full documentation](docs/README.md)
|
6
|
+
- [Rubygems](https://rubygems.org/gems/headmin)
|
7
|
+
- [NPM](https://www.npmjs.com/package/headmin)
|
5
8
|
|
6
9
|
## Installation
|
7
10
|
|
@@ -47,38 +50,6 @@ Finally import Headmin in your stylesheet.
|
|
47
50
|
## Development
|
48
51
|
For development purposes it's helpful to have both the test project and Headmin located in the same directory.
|
49
52
|
|
50
|
-
There are 2 ways of working locally:
|
51
|
-
1. **Configure package managers (preferred)**: setup bundler and yarn to look for local checkouts
|
52
|
-
2. **Use relative paths**: refer to Headmin by it's relative path
|
53
|
-
|
54
|
-
### Solution #1: Configure package managers (preferred)
|
55
|
-
This is the preferred way because you can develop locally, and deploy in a staging environment without changing configurations.
|
56
|
-
|
57
|
-
Force bundler to use the local gem with:
|
58
|
-
```shell
|
59
|
-
bundle config local.headmin /usr/local/var/www/headmin
|
60
|
-
```
|
61
|
-
In your Gemfile you need to refer to the feature branch you're working on
|
62
|
-
```ruby
|
63
|
-
gem 'headmin', git: 'git@github.com:insiting/headmin.git', branch: 'feature/test'
|
64
|
-
```
|
65
|
-
|
66
|
-
Symlink the headmin node module like this.
|
67
|
-
|
68
|
-
In your Headmin directory:
|
69
|
-
```shell
|
70
|
-
yarn link
|
71
|
-
```
|
72
|
-
|
73
|
-
In your project directory
|
74
|
-
```shell
|
75
|
-
yarn link headmin
|
76
|
-
```
|
77
|
-
|
78
|
-
### Solution #2: Use relative paths
|
79
|
-
We don't prefer this solution because you have to switch sources regularly in Gemfile or package.json for each deployment.
|
80
|
-
|
81
|
-
|
82
53
|
In Gemfile
|
83
54
|
```ruby
|
84
55
|
gem "headmin", path: "../headmin"
|
@@ -88,7 +59,7 @@ In package.json
|
|
88
59
|
```json
|
89
60
|
{
|
90
61
|
"dependencies": {
|
91
|
-
"bar": "
|
62
|
+
"bar": "link:../headmin"
|
92
63
|
}
|
93
64
|
}
|
94
65
|
```
|
@@ -128,16 +99,10 @@ $ gem tag -p
|
|
128
99
|
$ gem release
|
129
100
|
```
|
130
101
|
|
131
|
-
|
102
|
+
Update the node module
|
132
103
|
```
|
133
|
-
|
134
|
-
|
135
|
-
{
|
136
|
-
"name": "headmin",
|
137
|
-
"version": "{new version number here}",
|
138
|
-
...
|
139
|
-
}
|
140
|
-
|
104
|
+
# Manually update the version number in package.json
|
105
|
+
$ npm publish
|
141
106
|
```
|
142
107
|
|
143
108
|
## Deployment
|
@@ -13,14 +13,14 @@ module Headmin
|
|
13
13
|
content_tag(:i, class: "bi bi-#{icon} #{klass}", data: data) {}
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
uri = URI(
|
16
|
+
def current_url?(url)
|
17
|
+
uri = URI(url)
|
18
18
|
path = uri.path
|
19
19
|
query_string = uri.query
|
20
20
|
matches_path = request.path.include?(path)
|
21
21
|
matches_query = uri.query ? request.query_string.include?(query_string) : true
|
22
|
-
is_root = request.fullpath ==
|
23
|
-
if
|
22
|
+
is_root = request.fullpath == url
|
23
|
+
if url == admin_root_path
|
24
24
|
is_root
|
25
25
|
else
|
26
26
|
matches_path && matches_query
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Field
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
# Configuration
|
7
|
+
has_closure_tree
|
8
|
+
|
9
|
+
# Associations
|
10
|
+
belongs_to :fieldable, polymorphic: true, optional: true, touch: true
|
11
|
+
belongs_to :field, optional: true, touch: true
|
12
|
+
has_many :fields, foreign_key: "parent_id"
|
13
|
+
accepts_nested_attributes_for :fields, allow_destroy: true
|
14
|
+
has_one_attached :file
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Fieldable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :fields, as: :fieldable, dependent: :destroy
|
7
|
+
accepts_nested_attributes_for :fields, allow_destroy: true
|
8
|
+
|
9
|
+
def fields_hash
|
10
|
+
save_pair(fields.hash_tree)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def save_pair(my_hash, array = false)
|
16
|
+
if array
|
17
|
+
my_hash.map { |key, value|
|
18
|
+
save_pair(value)
|
19
|
+
}
|
20
|
+
else
|
21
|
+
Hash[my_hash.map { |key, value|
|
22
|
+
if value.empty?
|
23
|
+
case key.field_type
|
24
|
+
when 'group'
|
25
|
+
[key.name, save_pair(key.hash_tree[key])]
|
26
|
+
when 'list'
|
27
|
+
[key.name, save_pair(key.hash_tree[key], true)]
|
28
|
+
else
|
29
|
+
[key.name, return_field_output(key)]
|
30
|
+
end
|
31
|
+
else
|
32
|
+
key.field_type == 'list' ? [key.name, save_pair(value, true)] : [key.name, save_pair(value)]
|
33
|
+
end
|
34
|
+
}]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# returns what a field_type should return, e.g. its value, the file, the object ...
|
39
|
+
def return_field_output(key)
|
40
|
+
key.field_type == 'image' ? key.file : key.value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class BlockService
|
2
|
+
def self.block_names(path:)
|
3
|
+
form_views(path: path).map do |view|
|
4
|
+
filename = File.basename(view, '.html.erb')
|
5
|
+
|
6
|
+
# Removes leading _ if exists
|
7
|
+
filename.sub!(/^_/, '')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.form_view(name, path:)
|
12
|
+
view_by_name(name, form_view_paths(path))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.frontend_view(name, path:)
|
16
|
+
view_by_name(name, frontend_view_paths(path))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.frontend_views(path:)
|
20
|
+
views(frontend_view_paths(path))
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.form_views(path:)
|
24
|
+
views(form_view_paths(path))
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Looks for a block view by its name.
|
30
|
+
#
|
31
|
+
# It will first search in a specified path and will fallback to the default path
|
32
|
+
# An exception will be raised if the view is nowhere to be found
|
33
|
+
def self.view_by_name(name, paths)
|
34
|
+
views = views(paths)
|
35
|
+
view = views.find { |view| view.include?("/_#{name}.html.erb") }
|
36
|
+
|
37
|
+
unless view
|
38
|
+
prefixes = paths.map { |path| path.split('app/views/').last }
|
39
|
+
raise ActionView::MissingTemplate.new(paths, name, prefixes, true, "headmin") unless view
|
40
|
+
end
|
41
|
+
|
42
|
+
view
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.form_view_paths(path)
|
46
|
+
[app_view_path(path), app_view_path('admin/blocks')].uniq
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.frontend_view_paths(path)
|
50
|
+
[app_view_path(path), app_view_path('website/blocks')].uniq
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.app_view_path(path)
|
54
|
+
base_path = 'app/views'
|
55
|
+
[base_path, path].join('/')
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.views(paths)
|
59
|
+
paths.map { |path| views_in_path(path) }.flatten
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.views_in_path(path)
|
63
|
+
files = Dir.glob("#{path}/*")
|
64
|
+
files.map do |file|
|
65
|
+
file.split('app/views/').last
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%
|
2
|
+
# headmin/blocks
|
3
|
+
#
|
4
|
+
# ==== Options
|
5
|
+
# * <tt>blockable</tt> - Object with blocks association
|
6
|
+
# * <tt>path</tt> - Directory where to look for block templates
|
7
|
+
#
|
8
|
+
# ==== Examples
|
9
|
+
# Basic version. This will only look for blocks in 'website/blocks'
|
10
|
+
# <%= render "headmin/blocks", blockable: @page %#>
|
11
|
+
#
|
12
|
+
# Define the path to look for block templates like this:
|
13
|
+
# <%= render "headmin/blocks", blockable: @page, path: 'website/pages/blocks' %#>
|
14
|
+
|
15
|
+
blockable = local_assigns.has_key?(:blockable) ? blockable : nil
|
16
|
+
path = local_assigns.has_key?(:path) ? path : nil
|
17
|
+
%>
|
18
|
+
|
19
|
+
<% if blockable && blockable.respond_to?(:blocks) %>
|
20
|
+
<% blockable.blocks.order(:position).each do |block| %>
|
21
|
+
<% view_path = BlockService.frontend_view(block.name, path: path).gsub('/_', '/') %>
|
22
|
+
<%= render view_path, block: block %>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
@@ -1,8 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
<%
|
2
|
+
# headmin/breadcrumbs
|
3
|
+
#
|
4
|
+
# ==== Options
|
5
|
+
# * <tt>breadcrumbs</tt> - Object with blocks association
|
6
|
+
#
|
7
|
+
# ==== Examples
|
8
|
+
# Basic version. This will use the publicly available `breadcrumbs` variable
|
9
|
+
# <%= render "headmin/breadcrumbs" %#>
|
6
10
|
%>
|
7
11
|
|
8
12
|
<nav aria-label="breadcrumb">
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<%
|
2
|
+
# headmin/card
|
3
|
+
#
|
4
|
+
# ==== Options
|
5
|
+
# * <tt>title</tt> - Title for card
|
6
|
+
# * <tt>description</tt> - Description for card
|
7
|
+
# * <tt>padded</tt> - Set to true if you want to render the block content inside the card-body element
|
8
|
+
#
|
9
|
+
# ==== Examples
|
10
|
+
# Basic version.
|
11
|
+
# <%= render 'headmin/card' do %#>
|
12
|
+
# Your content
|
13
|
+
# <% end %#>
|
14
|
+
#
|
15
|
+
# Title and description
|
16
|
+
# <%= render 'headmin/card', title: 'Title', description: 'Description' do %#>
|
17
|
+
# Your content
|
18
|
+
# <% end %#>
|
19
|
+
|
20
|
+
title = local_assigns.has_key?(:title) ? title : nil
|
21
|
+
description = local_assigns.has_key?(:description) ? description : nil
|
22
|
+
padded = local_assigns.has_key?(:padded) ? padded : true
|
23
|
+
%>
|
24
|
+
|
25
|
+
<div class="card mb-3 shadow-sm">
|
26
|
+
|
27
|
+
<% if padded || title || description %>
|
28
|
+
<div class="card-body">
|
29
|
+
<% if title.present? %>
|
30
|
+
<h5 class="card-title"><%= title %></h5>
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<% if description.present? %>
|
34
|
+
<p class="card-text text-secondary"><%= description %></p>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<!-- Render inside body-->
|
38
|
+
<% if padded %>
|
39
|
+
<%= yield if block_given? %>
|
40
|
+
<% end %>
|
41
|
+
</div>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<!-- Render outside body-->
|
45
|
+
<% unless padded %>
|
46
|
+
<%= yield if block_given? %>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%
|
2
|
+
# headmin/dropdown
|
3
|
+
#
|
4
|
+
# ==== Options
|
5
|
+
# * <tt>class</tt> - Custom class names to put on the dropdown
|
6
|
+
#
|
7
|
+
# ==== Examples
|
8
|
+
# Basic version
|
9
|
+
# <%= render "headmin/dropdown" do %#>
|
10
|
+
# Your content
|
11
|
+
# <% end %#>
|
12
|
+
|
13
|
+
class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : 'btn-group'
|
14
|
+
%>
|
15
|
+
|
16
|
+
<div class="dropdown <%= class_names %>">
|
17
|
+
<%= yield %>
|
18
|
+
</div>
|
@@ -1,47 +1,69 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
<%
|
2
|
+
# headmin/filters
|
3
|
+
#
|
4
|
+
# ==== Options
|
5
|
+
# * <tt>url</tt> - Base url to send filter query to. Defaults to current URL
|
6
|
+
#
|
7
|
+
# ==== Examples
|
8
|
+
# Basic version
|
9
|
+
# <%= render "headmin/filters" %#>
|
10
|
+
#
|
11
|
+
# With custom URL
|
12
|
+
# <%= render "headmin/filters", url: admin_polls_path %#>
|
13
|
+
|
14
|
+
action = local_assigns.has_key?(:url) ? url : request.url
|
6
15
|
%>
|
7
|
-
<% action = local_assigns.has_key?(:url) ? url : request.url %>
|
8
16
|
|
9
|
-
<form
|
10
|
-
<%= yield if block_given? %>
|
17
|
+
<form action="<%= action %>" data-controller="filters" data-filters-target="form">
|
11
18
|
|
12
19
|
<!-- Default parameters (e.g. sorting, pagination) -->
|
13
|
-
<% default_params.each do |name, value| %>
|
20
|
+
<% default_params.except('page').each do |name, value| %>
|
14
21
|
<%= hidden_field_tag(name.to_sym, value) %>
|
15
22
|
<% end %>
|
16
23
|
|
17
|
-
|
18
|
-
<div class="h-filter-list d-flex" data-filters-target="list">
|
19
|
-
<%= content_for :filters_buttons %>
|
20
|
-
</div>
|
24
|
+
<%= yield if block_given? %>
|
21
25
|
|
22
|
-
|
23
|
-
|
26
|
+
<div class="d-flex flex-column flex-md-row align-content-start align-items-md-center">
|
27
|
+
<div class="d-flex align-items-center">
|
28
|
+
|
29
|
+
<!-- Search -->
|
30
|
+
<div class="h-filters-search d-flex my-1 w-100">
|
31
|
+
<%= content_for :filters_search %>
|
24
32
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
<
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
<!-- Separator -->
|
34
|
+
<% if content_for(:filters_menu) && content_for(:filters_search) %>
|
35
|
+
<div class="vr mx-2"></div>
|
36
|
+
<% end %>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
<!-- Menu -->
|
40
|
+
<div class="h-filters-menu d-flex align-items-center w-auto my-1">
|
41
|
+
<% if content_for :filters_menu %>
|
42
|
+
<div class="btn-group">
|
43
|
+
<button type="button" class="btn h-btn-outline-light dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
44
|
+
<%= bootstrap_icon('funnel') %>
|
45
|
+
<%= t('.button') %>
|
46
|
+
</button>
|
47
|
+
<ul class="dropdown-menu">
|
48
|
+
<%= content_for :filters_menu %>
|
49
|
+
<li>
|
50
|
+
<hr class="dropdown-divider">
|
51
|
+
</li>
|
52
|
+
<li>
|
53
|
+
<a class="dropdown-item text-danger" href="#" data-action="click->filters#removeAll"><%= t('.remove_all') %></a>
|
54
|
+
</li>
|
55
|
+
</ul>
|
56
|
+
</div>
|
57
|
+
<% end %>
|
58
|
+
</div>
|
37
59
|
</div>
|
38
|
-
<% end %>
|
39
60
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
61
|
+
<!-- Filter list -->
|
62
|
+
<div class="h-filter-list d-flex ms-md-1 flex-wrap" data-filters-target="list">
|
63
|
+
<%= content_for :filters_buttons %>
|
64
|
+
</div>
|
65
|
+
</div>
|
44
66
|
|
45
|
-
<!--
|
46
|
-
<%= content_for :
|
67
|
+
<!-- Filter templates -->
|
68
|
+
<%= content_for :filters_templates %>
|
47
69
|
</form>
|
@@ -1,11 +1,65 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
<%
|
2
|
+
# headmin/form
|
3
|
+
#
|
4
|
+
# ==== Options
|
5
|
+
# * <tt>model<tt> - A model to infer :url and :scope
|
6
|
+
# * <tt>scope<tt> - The scope to prefix input field names with
|
7
|
+
# * <tt>url<tt> - The URL the form submits to
|
8
|
+
# * <tt>format<tt> - The format of the route the form submits to
|
9
|
+
# * <tt>namespace<tt> - A namespace for your form to ensure uniqueness of id attributes on form elements
|
10
|
+
# * <tt>method<tt> - The method to use when submitting the form
|
11
|
+
# * <tt>authenticity_token<tt> - Authenticity token to use in the form
|
12
|
+
# * <tt>local<tt> - By default form submits are remote and unobtrusive XHRs
|
13
|
+
# * <tt>skip_enforcing_utf8<tt> - If set to true, a hidden input with name utf8 is not output
|
14
|
+
# * <tt>builder<tt> - Override the object used to build the form
|
15
|
+
# * <tt>html<tt> - Other optional HTML attributes for the form tag
|
16
|
+
# * <tt>id<tt> - Optional HTML id attribute
|
17
|
+
# * <tt>class<tt> - Optional HTML class attribute
|
18
|
+
# * <tt>data<tt> - Optional HTML data attributes
|
19
|
+
#
|
20
|
+
# === Examples
|
21
|
+
# Basic version
|
22
|
+
# <%= render 'headmin/form', model: @product do |form| %#>
|
23
|
+
# Form content
|
24
|
+
# <% end %#>
|
25
|
+
#
|
26
|
+
# Specify URL to post to
|
27
|
+
# <%= render 'headmin/form', model: @product, url: admin_products_path do |form| %#>
|
28
|
+
# Form content
|
29
|
+
# <% end %#>
|
30
|
+
|
31
|
+
model = local_assigns.has_key?(:model) ? local_assigns[:model] : nil
|
32
|
+
scope = local_assigns.has_key?(:scope) ? local_assigns[:scope] : nil
|
33
|
+
url = local_assigns.has_key?(:url) ? local_assigns[:url] : nil
|
34
|
+
format = local_assigns.has_key?(:format) ? local_assigns[:format] : nil
|
35
|
+
|
36
|
+
namespace = local_assigns.has_key?(:namespace) ? namespace : nil
|
37
|
+
method = local_assigns.has_key?(:method) ? method : nil
|
38
|
+
authenticity_token = local_assigns.has_key?(:authenticity_token) ? authenticity_token : nil
|
39
|
+
local = local_assigns.has_key?(:local) ? local : true
|
40
|
+
skip_enforcing_utf8 = local_assigns.has_key?(:skip_enforcing_utf8) ? skip_enforcing_utf8 : nil
|
41
|
+
builder = local_assigns.has_key?(:builder) ? builder : nil
|
42
|
+
html = local_assigns.has_key?(:html) ? html : {}
|
43
|
+
id = local_assigns.has_key?(:id) ? id : nil
|
44
|
+
option_class = local_assigns.has_key?(:class) ? local_assigns[:class] : nil
|
45
|
+
data = local_assigns.has_key?(:data) ? data : nil
|
46
|
+
|
47
|
+
options = {
|
48
|
+
namespace: namespace,
|
49
|
+
method: method,
|
50
|
+
authenticity_token: authenticity_token,
|
51
|
+
local: local,
|
52
|
+
skip_enforcing_utf8: skip_enforcing_utf8,
|
53
|
+
builder: builder,
|
54
|
+
html: html,
|
55
|
+
id: id,
|
56
|
+
class: option_class,
|
57
|
+
data: data
|
58
|
+
}
|
5
59
|
%>
|
6
60
|
|
7
|
-
<div class="
|
8
|
-
<%= form_with model: model do |form| %>
|
61
|
+
<div class="container">
|
62
|
+
<%= form_with model: model, scope: scope, url: url, format: format, **options do |form| %>
|
9
63
|
<%= yield(form) %>
|
10
64
|
<% end %>
|
11
65
|
</div>
|
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
<%
|
2
|
+
# headmin/heading
|
3
|
+
#
|
4
|
+
# ==== Examples
|
5
|
+
# Basic version
|
6
|
+
# <%= render "headmin/heading" do %#>
|
7
|
+
# Your content
|
8
|
+
# <% end %#>
|
5
9
|
%>
|
6
10
|
|
7
11
|
<div class="h-heading d-flex flex-column flex-md-row align-items-start align-items-md-end justify-content-between">
|