headmin 0.1.1
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/.gitignore +13 -0
- data/.nvmrc +1 -0
- data/.rubocop.yml +13 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +43 -0
- data/LICENSE.txt +21 -0
- data/README.md +166 -0
- data/Rakefile +16 -0
- data/app/assets/images/avatar.jpg +0 -0
- data/app/controllers/admin/users/confirmations_controller.rb +31 -0
- data/app/controllers/admin/users/omniauth_callbacks_controller.rb +31 -0
- data/app/controllers/admin/users/passwords_controller.rb +35 -0
- data/app/controllers/admin/users/registrations_controller.rb +63 -0
- data/app/controllers/admin/users/sessions_controller.rb +28 -0
- data/app/controllers/admin/users/unlocks_controller.rb +31 -0
- data/app/controllers/concerns/headmin/acts_as_list.rb +16 -0
- data/app/controllers/concerns/headmin/authentication.rb +17 -0
- data/app/controllers/concerns/headmin/ckeditor.rb +27 -0
- data/app/controllers/concerns/headmin/filter.rb +5 -0
- data/app/controllers/concerns/headmin/pagination.rb +23 -0
- data/app/controllers/concerns/headmin/searchable.rb +15 -0
- data/app/controllers/concerns/headmin/sortable.rb +44 -0
- data/app/helpers/headmin/admin_helper.rb +65 -0
- data/app/helpers/headmin/filter_helper.rb +12 -0
- data/app/helpers/headmin/notification_helper.rb +31 -0
- data/app/views/admin/users/confirmations/new.html.erb +9 -0
- data/app/views/admin/users/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/admin/users/mailer/email_changed.html.erb +7 -0
- data/app/views/admin/users/mailer/password_change.html.erb +3 -0
- data/app/views/admin/users/mailer/reset_password_instructions.html.erb +8 -0
- data/app/views/admin/users/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/admin/users/passwords/edit.html.erb +12 -0
- data/app/views/admin/users/passwords/new.html.erb +9 -0
- data/app/views/admin/users/registrations/edit.html.erb +24 -0
- data/app/views/admin/users/registrations/new.html.erb +11 -0
- data/app/views/admin/users/sessions/new.html.erb +13 -0
- data/app/views/admin/users/shared/_error_messages.html.erb +7 -0
- data/app/views/admin/users/shared/_links.html.erb +27 -0
- data/app/views/admin/users/unlocks/new.html.erb +10 -0
- data/app/views/headmin/_breadcrumbs.html.erb +23 -0
- data/app/views/headmin/_filters.html.erb +47 -0
- data/app/views/headmin/_form.html.erb +11 -0
- data/app/views/headmin/_heading.html.erb +9 -0
- data/app/views/headmin/_index.html.erb +12 -0
- data/app/views/headmin/_notifications.html.erb +12 -0
- data/app/views/headmin/_pagination.html.erb +13 -0
- data/app/views/headmin/_table.html.erb +13 -0
- data/app/views/headmin/filters/_date.html.erb +46 -0
- data/app/views/headmin/filters/_search.html.erb +22 -0
- data/app/views/headmin/filters/_select.html.erb +39 -0
- data/app/views/headmin/filters/filter/_button.html.erb +22 -0
- data/app/views/headmin/filters/filter/_menu_item.html.erb +12 -0
- data/app/views/headmin/filters/filter/_template.html.erb +13 -0
- data/app/views/headmin/forms/_actions.html.erb +32 -0
- data/app/views/headmin/forms/_errors.html.erb +20 -0
- data/app/views/headmin/forms/_group.html.erb +36 -0
- data/app/views/headmin/forms/fields/_checkbox.html.erb +23 -0
- data/app/views/headmin/forms/fields/_ckeditor.html.erb +28 -0
- data/app/views/headmin/forms/fields/_currency.html.erb +24 -0
- data/app/views/headmin/forms/fields/_date.html.erb +36 -0
- data/app/views/headmin/forms/fields/_email.html.erb +39 -0
- data/app/views/headmin/forms/fields/_file.html.erb +24 -0
- data/app/views/headmin/forms/fields/_image.html.erb +37 -0
- data/app/views/headmin/forms/fields/_label.html.erb +9 -0
- data/app/views/headmin/forms/fields/_multiple_select.html.erb +37 -0
- data/app/views/headmin/forms/fields/_password.html.erb +39 -0
- data/app/views/headmin/forms/fields/_repeater.html.erb +48 -0
- data/app/views/headmin/forms/fields/_select.html.erb +36 -0
- data/app/views/headmin/forms/fields/_select_tags.html.erb +32 -0
- data/app/views/headmin/forms/fields/_text.html.erb +39 -0
- data/app/views/headmin/forms/fields/_textarea.html.erb +29 -0
- data/app/views/headmin/forms/fields/_url.html.erb +38 -0
- data/app/views/headmin/forms/fields/_validation.html.erb +12 -0
- data/app/views/headmin/forms/fields/repeater/_row.html.erb +16 -0
- data/app/views/headmin/heading/_title.html.erb +24 -0
- data/app/views/headmin/kaminari/_first_page.html.erb +11 -0
- data/app/views/headmin/kaminari/_gap.html.erb +12 -0
- data/app/views/headmin/kaminari/_last_page.html.erb +12 -0
- data/app/views/headmin/kaminari/_next_page.html.erb +13 -0
- data/app/views/headmin/kaminari/_page.html.erb +12 -0
- data/app/views/headmin/kaminari/_paginator.html.erb +25 -0
- data/app/views/headmin/kaminari/_prev_page.html.erb +11 -0
- data/app/views/headmin/layout/_body.html.erb +9 -0
- data/app/views/headmin/layout/_content.html.erb +9 -0
- data/app/views/headmin/layout/_footer.html.erb +17 -0
- data/app/views/headmin/layout/_header.html.erb +13 -0
- data/app/views/headmin/layout/_main.html.erb +13 -0
- data/app/views/headmin/layout/_sidebar.html.erb +20 -0
- data/app/views/headmin/layout/dropdown/_divider.html.erb +9 -0
- data/app/views/headmin/layout/dropdown/_item.html.erb +17 -0
- data/app/views/headmin/layout/header/_account.html.erb +25 -0
- data/app/views/headmin/layout/header/_locale.html.erb +19 -0
- data/app/views/headmin/layout/sidebar/_bottom.html.erb +4 -0
- data/app/views/headmin/layout/sidebar/_menu.html.erb +9 -0
- data/app/views/headmin/layout/sidebar/menu/_account.html.erb +25 -0
- data/app/views/headmin/layout/sidebar/menu/_item.html.erb +16 -0
- data/app/views/headmin/layout/sidebar/menu/_locale.html.erb +18 -0
- data/app/views/headmin/table/_actions.html.erb +19 -0
- data/app/views/headmin/table/_body.html.erb +19 -0
- data/app/views/headmin/table/_foot.html.erb +15 -0
- data/app/views/headmin/table/_footer.html.erb +13 -0
- data/app/views/headmin/table/_head.html.erb +15 -0
- data/app/views/headmin/table/_header.html.erb +13 -0
- data/app/views/headmin/table/actions/_action.html.erb +10 -0
- data/app/views/headmin/table/actions/_delete.html.erb +8 -0
- data/app/views/headmin/table/actions/_export.html.erb +8 -0
- data/app/views/headmin/table/body/_association.html.erb +11 -0
- data/app/views/headmin/table/body/_boolean.erb +16 -0
- data/app/views/headmin/table/body/_currency.html.erb +10 -0
- data/app/views/headmin/table/body/_date.html.erb +11 -0
- data/app/views/headmin/table/body/_id.html.erb +3 -0
- data/app/views/headmin/table/body/_row.html.erb +9 -0
- data/app/views/headmin/table/body/_sort.html.erb +3 -0
- data/app/views/headmin/table/body/_string.html.erb +16 -0
- data/app/views/headmin/table/body/_text.html.erb +10 -0
- data/app/views/headmin/table/foot/_cell.html.erb +10 -0
- data/app/views/headmin/table/foot/_id.html.erb +9 -0
- data/app/views/headmin/table/head/_cell.html.erb +13 -0
- data/app/views/headmin/table/head/_empty.html.erb +1 -0
- data/app/views/headmin/table/head/_id.html.erb +9 -0
- data/app/views/headmin/table/head/_sort.html.erb +3 -0
- data/app/views/headmin/table/head/cell/_asc.html.erb +4 -0
- data/app/views/headmin/table/head/cell/_default.html.erb +7 -0
- data/app/views/headmin/table/head/cell/_desc.html.erb +4 -0
- data/app/views/layouts/admin/auth.html.erb +20 -0
- data/app/views/layouts/admin.html.erb +42 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/config/locales/defaults/en.yml +215 -0
- data/config/locales/defaults/nl.yml +213 -0
- data/config/locales/devise/nl.yml +85 -0
- data/config/locales/en.yml +137 -0
- data/config/locales/nl.yml +138 -0
- data/dist/css/headmin.css +9874 -0
- data/dist/js/headmin.js +852 -0
- data/docs/README.md +4 -0
- data/docs/blocks.md +116 -0
- data/docs/devise.md +62 -0
- data/headmin.gemspec +35 -0
- data/lib/headmin/engine.rb +10 -0
- data/lib/headmin/version.rb +5 -0
- data/lib/headmin.rb +4 -0
- data/package.json +62 -0
- data/src/js/headmin/controllers/filter_controller.js +47 -0
- data/src/js/headmin/controllers/filters_controller.js +53 -0
- data/src/js/headmin/controllers/index_controller.js +79 -0
- data/src/js/headmin/controllers/repeater_controller.js +35 -0
- data/src/js/headmin/controllers/repeater_row_controller.js +54 -0
- data/src/js/headmin/controllers/table_actions_controller.js +22 -0
- data/src/js/headmin/controllers/table_controller.js +36 -0
- data/src/js/headmin/headmin.js +168 -0
- data/src/js/headmin.js +1 -0
- data/src/scss/headmin/filter.scss +33 -0
- data/src/scss/headmin/filters.scss +14 -0
- data/src/scss/headmin/form.scss +39 -0
- data/src/scss/headmin/general.scss +3 -0
- data/src/scss/headmin/layout/body.scss +6 -0
- data/src/scss/headmin/layout/sidebar.scss +22 -0
- data/src/scss/headmin/layout.scss +2 -0
- data/src/scss/headmin/login.scss +35 -0
- data/src/scss/headmin/table.scss +32 -0
- data/src/scss/headmin/utilities.scss +19 -0
- data/src/scss/headmin.scss +58 -0
- data/src/scss/vendor/bootstrap/variables.scss +71 -0
- data/src/scss/vendor/choices/cross-inverse.svg +6 -0
- data/src/scss/vendor/choices/cross.svg +6 -0
- data/src/scss/vendor/choices/custom.scss +28 -0
- data/src/scss/vendor/choices/variables.scss +16 -0
- data/webpack.config.js +30 -0
- data/yarn.lock +7512 -0
- metadata +220 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Pagination
|
3
|
+
def paginate(collection)
|
4
|
+
@records_filtered = collection.count
|
5
|
+
collection.page(page).per(per_page)
|
6
|
+
end
|
7
|
+
|
8
|
+
def page
|
9
|
+
if params[:page]
|
10
|
+
params[:page]
|
11
|
+
elsif params[:start]
|
12
|
+
(params[:start].to_i / per_page) + 1
|
13
|
+
else
|
14
|
+
1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def per_page
|
19
|
+
length = (params[:per_page] || params[:length]).to_i
|
20
|
+
length > 0 ? length : 24
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Searchable
|
3
|
+
def search(collection)
|
4
|
+
if search_params&.present?
|
5
|
+
collection.search(search_params)
|
6
|
+
else
|
7
|
+
collection
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def search_params
|
12
|
+
@search_params ||= params[:search] && params[:search].to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Headmin
|
2
|
+
module Sortable
|
3
|
+
def sort(collection)
|
4
|
+
if sort_params.to_h.any?
|
5
|
+
sort_by_params(collection)
|
6
|
+
elsif collection.attribute_names.include?(:created_at.to_s)
|
7
|
+
collection.order(created_at: :desc)
|
8
|
+
else
|
9
|
+
collection
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def sort_by_params(collection)
|
14
|
+
sort_params.each do |key, value|
|
15
|
+
next unless %w(asc desc).include?(value)
|
16
|
+
attribute = key.gsub('sort_', '')
|
17
|
+
|
18
|
+
# Sort on model columns first, then check for translation columns
|
19
|
+
if collection.attribute_names.include?(attribute.to_s)
|
20
|
+
column = collection.arel_table[attribute]
|
21
|
+
elsif collection.respond_to?(:translation_class) && collection.translation_class.attribute_names.include?(attribute.to_s)
|
22
|
+
column = collection.translation_class.arel_table[attribute]
|
23
|
+
else
|
24
|
+
next
|
25
|
+
end
|
26
|
+
|
27
|
+
order_scope = "order_by_#{attribute}".to_sym
|
28
|
+
sort_scope = "sort_by_#{attribute}".to_sym
|
29
|
+
if collection.respond_to?(order_scope)
|
30
|
+
collection = collection.send(order_scope, value)
|
31
|
+
elsif collection.respond_to?(sort_scope)
|
32
|
+
collection = collection.send(sort_scope, value)
|
33
|
+
else
|
34
|
+
collection = collection.order(column.send(value))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
collection
|
38
|
+
end
|
39
|
+
|
40
|
+
def sort_params
|
41
|
+
params.permit!.select { |p| p.to_s.include?('sort_') }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Headmin
|
2
|
+
module AdminHelper
|
3
|
+
include Headmin::FilterHelper
|
4
|
+
include Headmin::NotificationHelper
|
5
|
+
|
6
|
+
def current_model
|
7
|
+
controller_name.classify.constantize
|
8
|
+
end
|
9
|
+
|
10
|
+
def bootstrap_icon(icon, options = {})
|
11
|
+
data = options.has_key?(:data) ? options[:data] : nil
|
12
|
+
klass = options.has_key?(:class) ? options[:class] : nil
|
13
|
+
content_tag(:i, class: "bi bi-#{icon} #{klass}", data: data) {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def menu_item_active?(link)
|
17
|
+
uri = URI(link)
|
18
|
+
path = uri.path
|
19
|
+
query_string = uri.query
|
20
|
+
matches_path = request.path.include?(path)
|
21
|
+
matches_query = uri.query ? request.query_string.include?(query_string) : true
|
22
|
+
is_root = request.fullpath == link
|
23
|
+
if link == admin_root_path
|
24
|
+
is_root
|
25
|
+
else
|
26
|
+
matches_path && matches_query
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def form_field_valid?(form, name)
|
31
|
+
!form.object.errors.has_key?(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def form_field_validation_id(form, name)
|
35
|
+
[form.object_name, name.to_s, 'validation'].join('_').parameterize.underscore
|
36
|
+
end
|
37
|
+
|
38
|
+
def form_field_validation_class(form, name)
|
39
|
+
return nil if request.get?
|
40
|
+
form.object.errors.has_key?(name) ? 'is-invalid' : 'is-valid'
|
41
|
+
end
|
42
|
+
|
43
|
+
def default_params
|
44
|
+
params.select { |key, value| is_default_param?(key) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_default_param_key(key)
|
48
|
+
keys = default_param_keys || []
|
49
|
+
keys.push(key)
|
50
|
+
@default_param_keys = keys
|
51
|
+
end
|
52
|
+
|
53
|
+
def default_param_keys
|
54
|
+
@default_param_keys ||= [:page, :start, :length, :per_page]
|
55
|
+
end
|
56
|
+
|
57
|
+
def is_default_param?(key)
|
58
|
+
default_param_keys.include?(key.to_sym) || is_sort_param_key?(key)
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_sort_param_key?(key)
|
62
|
+
key.to_s.include?('sort_')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Headmin
|
2
|
+
module NotificationHelper
|
3
|
+
def notification_color(name)
|
4
|
+
color = {
|
5
|
+
notice: {
|
6
|
+
background: 'bg-success',
|
7
|
+
text: 'text-white'
|
8
|
+
},
|
9
|
+
error: {
|
10
|
+
text: 'text-dark',
|
11
|
+
background: 'bg-danger'
|
12
|
+
},
|
13
|
+
alert: {
|
14
|
+
text: 'text-dark',
|
15
|
+
background: 'bg-warning'
|
16
|
+
},
|
17
|
+
timedout: {
|
18
|
+
text: 'text-dark',
|
19
|
+
background: 'bg-warning'
|
20
|
+
},
|
21
|
+
fallback: {
|
22
|
+
text: 'text-light',
|
23
|
+
background: 'bg-info',
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
name = name.to_sym
|
28
|
+
color.key?(name) ? color[name] : color[:fallback]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: {method: :post}) do |f| %>
|
2
|
+
<%= render "admin/users/shared/error_messages", resource: resource %>
|
3
|
+
|
4
|
+
<%= render 'headmin/forms/fields/email', form: f, attribute: :email, required: true, label: :float %>
|
5
|
+
|
6
|
+
<%= f.submit t('.resend'), class: 'btn btn-lg btn-primary w-100' %>
|
7
|
+
|
8
|
+
<%= render "admin/users/shared/links" %>
|
9
|
+
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<p><%= t('.greeting', email: @resource.email) %></p>
|
2
|
+
|
3
|
+
<p><%= t('.someone_requested') %></p>
|
4
|
+
|
5
|
+
<p><%= link_to t('.change'), edit_password_url(@resource, reset_password_token: @token) %></p>
|
6
|
+
|
7
|
+
<p><%= t('.not_requested')%></p>
|
8
|
+
<p><%= t('.password_not_changed_until') %></p>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: {method: :put}) do |f| %>
|
2
|
+
<%= render "admin/users/shared/error_messages", resource: resource %>
|
3
|
+
|
4
|
+
<%= f.hidden_field :reset_password_token %>
|
5
|
+
|
6
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :password, required: true, label: :float %>
|
7
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :password_confirmation, required: true, label: :float %>
|
8
|
+
|
9
|
+
<%= f.submit t('.change_password'), class: 'btn btn-lg btn-primary w-100' %>
|
10
|
+
|
11
|
+
<%= render "admin/users/shared/links" %>
|
12
|
+
<% end %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: {method: :post}) do |f| %>
|
2
|
+
<%= render "admin/users/shared/error_messages", resource: resource %>
|
3
|
+
|
4
|
+
<%= render 'headmin/forms/fields/email', form: f, attribute: :email, required: true, label: :float %>
|
5
|
+
|
6
|
+
<%= f.submit t('.send_instructions'), class: 'btn btn-lg btn-primary w-100' %>
|
7
|
+
|
8
|
+
<%= render "admin/users/shared/links" %>
|
9
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<div>
|
2
|
+
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {method: :put}) do |f| %>
|
3
|
+
<%= render "admin/users/shared/error_messages", resource: resource %>
|
4
|
+
|
5
|
+
<%= render 'headmin/forms/fields/email', form: f, attribute: :email, required: true, label: :float %>
|
6
|
+
|
7
|
+
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
|
8
|
+
<div><%= t('.waiting_confirmation', email: resource.unconfirmed_email) %></div>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :password, required: true, label: :float %>
|
12
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :password_confirmation, required: true, label: :float %>
|
13
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :current_password, required: true, label: :float %>
|
14
|
+
|
15
|
+
<%= f.submit t('.change'), class: 'btn btn-lg btn-primary w-100' %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<div class="mt-5">
|
19
|
+
<h4><%= t('.cancel') %></h4>
|
20
|
+
|
21
|
+
<p><%= t('.unhappy') %></p>
|
22
|
+
<%= button_to t('.cancel'), registration_path(resource_name), class: 'btn btn-lg btn-danger w-100', data: {confirm: "Are you sure?"}, method: :delete %>
|
23
|
+
</div>
|
24
|
+
</div>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
2
|
+
<%= render "admin/users/shared/error_messages", resource: resource %>
|
3
|
+
|
4
|
+
<%= render 'headmin/forms/fields/email', form: f, attribute: :email, required: true, label: :float %>
|
5
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :password, required: true, label: :float %>
|
6
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :password_confirmation, required: true, label: :float %>
|
7
|
+
|
8
|
+
<%= f.submit t('.sign_up'), class: 'btn btn-lg btn-primary w-100' %>
|
9
|
+
|
10
|
+
<%= render "admin/users/shared/links" %>
|
11
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
|
2
|
+
|
3
|
+
<%= render 'headmin/forms/fields/email', form: f, attribute: :email, required: true, label: :float %>
|
4
|
+
<%= render 'headmin/forms/fields/password', form: f, attribute: :password, required: true, label: :float %>
|
5
|
+
|
6
|
+
<% if devise_mapping.rememberable? %>
|
7
|
+
<%= render 'headmin/forms/fields/checkbox', form: f, attribute: :remember_me, label: true %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= f.submit t('.login'), class: 'btn btn-lg btn-primary w-100' %>
|
11
|
+
|
12
|
+
<%= render "admin/users/shared/links" %>
|
13
|
+
<% end %>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<div class="bg-light mt-5 text-end">
|
2
|
+
<%- if controller_name != 'sessions' %>
|
3
|
+
<%= link_to "Log in", new_session_path(resource_name) %><br />
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
7
|
+
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
11
|
+
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
15
|
+
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
19
|
+
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<%- if devise_mapping.omniauthable? %>
|
23
|
+
<%- resource_class.omniauth_providers.each do |provider| %>
|
24
|
+
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
|
25
|
+
<% end %>
|
26
|
+
<% end %>
|
27
|
+
</div>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: {method: :post}) do |f| %>
|
2
|
+
<%= render "admin/users/shared/error_messages", resource: resource %>
|
3
|
+
|
4
|
+
<%= render 'headmin/forms/fields/email', form: f, attribute: :email, required: true, label: :float %>
|
5
|
+
|
6
|
+
<%= f.submit t('.resend'), class: 'btn btn-lg btn-primary w-100' %>
|
7
|
+
|
8
|
+
<%= render "admin/users/shared/links" %>
|
9
|
+
|
10
|
+
<% end %>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/heading/breadcrumbs
|
3
|
+
accepts block: no
|
4
|
+
parameters:
|
5
|
+
breadcrumbs: Breadcrumbs collection
|
6
|
+
%>
|
7
|
+
|
8
|
+
<nav aria-label="breadcrumb">
|
9
|
+
<ol class="breadcrumb">
|
10
|
+
<% breadcrumb_count = breadcrumbs.count %>
|
11
|
+
<% breadcrumbs.each_with_index do |breadcrumb, index| %>
|
12
|
+
<% last = (index == breadcrumb_count - 1) %>
|
13
|
+
<li class="breadcrumb-item text-muted" aria-current="<%= last ? 'page' : nil %>">
|
14
|
+
<% if last %>
|
15
|
+
<%= breadcrumb.name %>
|
16
|
+
<% else %>
|
17
|
+
<%= link_to_unless_current(breadcrumb.name, breadcrumb.path, class: 'text-muted text-decoration-none') %>
|
18
|
+
<% end %>
|
19
|
+
</li>
|
20
|
+
<% end %>
|
21
|
+
<li> </li>
|
22
|
+
</ol>
|
23
|
+
</nav>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/filters
|
3
|
+
accepts block: yes
|
4
|
+
parameters:
|
5
|
+
url: base url to send filter query to
|
6
|
+
%>
|
7
|
+
<% action = local_assigns.has_key?(:url) ? url : request.url %>
|
8
|
+
|
9
|
+
<form class="h-filters d-flex align-items-center mb-2" action="<%= action %>" data-controller="filters" data-filters-target="form">
|
10
|
+
<%= yield if block_given? %>
|
11
|
+
|
12
|
+
<!-- Default parameters (e.g. sorting, pagination) -->
|
13
|
+
<% default_params.each do |name, value| %>
|
14
|
+
<%= hidden_field_tag(name.to_sym, value) %>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<!-- Filter buttons -->
|
18
|
+
<div class="h-filter-list d-flex" data-filters-target="list">
|
19
|
+
<%= content_for :filters_buttons %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<!-- Filter templates -->
|
23
|
+
<%= content_for :filters_templates %>
|
24
|
+
|
25
|
+
<!-- Menu -->
|
26
|
+
<% if content_for :filters_menu %>
|
27
|
+
<div class="btn-group">
|
28
|
+
<button type="button" class="btn btn-link dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
29
|
+
<%= bootstrap_icon('funnel-fill') %>
|
30
|
+
<%= t('.button') %>
|
31
|
+
</button>
|
32
|
+
<ul class="dropdown-menu">
|
33
|
+
<%= content_for :filters_menu %>
|
34
|
+
<li><hr class="dropdown-divider"></li>
|
35
|
+
<li><a class="dropdown-item text-danger" href="#" data-action="click->filters#removeAll"><%= t('.remove_all') %></a></li>
|
36
|
+
</ul>
|
37
|
+
</div>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<!-- Separator -->
|
41
|
+
<% if content_for(:filters_menu) && content_for(:filters_search) %>
|
42
|
+
<span class="separator"></span>
|
43
|
+
<% end %>
|
44
|
+
|
45
|
+
<!-- Search -->
|
46
|
+
<%= content_for :filters_search %>
|
47
|
+
</form>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/index
|
3
|
+
accepts block: yes (required)
|
4
|
+
parameters:
|
5
|
+
search:
|
6
|
+
url: base url to send search query to
|
7
|
+
placeholder: placeholder for search field
|
8
|
+
%>
|
9
|
+
|
10
|
+
<div class="headmin-index container-fluid" data-controller="index">
|
11
|
+
<%= yield %>
|
12
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="toast-container position-absolute top-0 end-0 p-3">
|
2
|
+
<% flash.each do |name, message| %>
|
3
|
+
<div class="toast align-items-center text-white show <%= notification_color(name.to_sym)[:background] %>" role="alert" aria-live="assertive" aria-atomic="true">
|
4
|
+
<div class="d-flex">
|
5
|
+
<div class="toast-body <%= notification_color(name.to_sym)[:text] %>">
|
6
|
+
<%= message %>
|
7
|
+
</div>
|
8
|
+
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/pagination
|
3
|
+
accepts block: no
|
4
|
+
parameters:
|
5
|
+
collection: Kaminari collection that accepts a method .total_count
|
6
|
+
%>
|
7
|
+
|
8
|
+
<div class="d-flex flex-row-reverse flex-md-row align-items-center w-100 justify-content-between justify-content-md-end">
|
9
|
+
<div class="ms-2 me-md-2 text-secondary">
|
10
|
+
<%= t('.items', count: collection.total_count) %>
|
11
|
+
</div>
|
12
|
+
<%= paginate collection, views_prefix: 'headmin' %>
|
13
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/table
|
3
|
+
accepts block: yes
|
4
|
+
parameters: none
|
5
|
+
%>
|
6
|
+
<% sort_url = local_assigns.has_key?(:sort_url) ? sort_url : nil %>
|
7
|
+
<div class="h-table card my-2 shadow-sm <%= 'table-drag-sort' if sort_url %>" data-sort-url="<%= sort_url %>">
|
8
|
+
<div class="table-responsive">
|
9
|
+
<table class="table table-hover m-0" data-controller="table" data-table-target="table" data-table-url-value="<%= sort_url %>">
|
10
|
+
<%= yield if block_given? %>
|
11
|
+
</table>
|
12
|
+
</div>
|
13
|
+
</div>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/filters/date_range
|
3
|
+
accepts block: no
|
4
|
+
parameters:
|
5
|
+
name: (string) Name of the parameter
|
6
|
+
label: (string) Display name
|
7
|
+
%>
|
8
|
+
<% label = local_assigns.has_key?(:label) ? label : nil %>
|
9
|
+
<% name = local_assigns.has_key?(:name) ? name : nil %>
|
10
|
+
|
11
|
+
<% input_options = {
|
12
|
+
placeholder: 'dd/mm/yyyy',
|
13
|
+
class: "form-control flatpickr",
|
14
|
+
required: true,
|
15
|
+
'data-filters-target': 'input',
|
16
|
+
'data-action': "change->filters#update"
|
17
|
+
} %>
|
18
|
+
|
19
|
+
<%= content_for :filters_menu do %>
|
20
|
+
<%= render 'headmin/filters/filter/menu_item', name: name, label: label %>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<%= content_for :filters_templates do %>
|
24
|
+
<%= render 'headmin/filters/filter/template', name: name, label: label do %>
|
25
|
+
<div class="input-group">
|
26
|
+
<span class="input-group-text">
|
27
|
+
<%= bootstrap_icon('calendar') %>
|
28
|
+
</span>
|
29
|
+
<%= date_field_tag(name, nil, input_options) %>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
<%= content_for :filters_buttons do %>
|
35
|
+
<% if filter_param_exists?(name) %>
|
36
|
+
<% value_formatted = Date.parse(params[name]).strftime('%d/%m/%Y') %>
|
37
|
+
<%= render 'headmin/filters/filter/button', name: name, label: label, value: value_formatted do %>
|
38
|
+
<div class="input-group">
|
39
|
+
<span class="input-group-text">
|
40
|
+
<%= bootstrap_icon('calendar') %>
|
41
|
+
</span>
|
42
|
+
<%= date_field_tag(name, params[name], input_options) %>
|
43
|
+
</div>
|
44
|
+
<% end %>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/filters/search
|
3
|
+
accepts block: no
|
4
|
+
parameters:
|
5
|
+
name: (string) Name of the parameter
|
6
|
+
model: (Object) model to create a placeholder for
|
7
|
+
placeholder: (string) placeholder for search field. Defaults to model name
|
8
|
+
%>
|
9
|
+
<% name = local_assigns.has_key?(:name) ? name : :search %>
|
10
|
+
<% label = local_assigns.has_key?(:label) ? label : nil %>
|
11
|
+
<% placeholder = local_assigns.has_key?(:placeholder) ? placeholder : t('.placeholder', resource: label) %>
|
12
|
+
|
13
|
+
<% value = filter_param_exists?(name) ? params[name] : nil %>
|
14
|
+
|
15
|
+
<% content_for :filters_search do %>
|
16
|
+
<div class="h-filters-search d-flex">
|
17
|
+
<input class="form-control me-1" type="search" placeholder="<%= raw placeholder.capitalize %>" aria-label="Search" name="<%= name %>" value="<%= value %>">
|
18
|
+
<button class="btn h-btn-outline-light d-none d-md-block" type="submit">
|
19
|
+
<%= t('.button') %>
|
20
|
+
</button>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<%#
|
2
|
+
name: headmin/filters/select
|
3
|
+
accepts block: no
|
4
|
+
parameters:
|
5
|
+
name: (string) Name of the parameter
|
6
|
+
label: (string) Display name
|
7
|
+
options: (array) List of options to select from
|
8
|
+
%>
|
9
|
+
<% label = local_assigns.has_key?(:label) ? label : nil %>
|
10
|
+
<% name = local_assigns.has_key?(:name) ? name : nil %>
|
11
|
+
<% options = local_assigns.has_key?(:options) ? options : [] %>
|
12
|
+
|
13
|
+
<% select_options = {
|
14
|
+
class: "form-select",
|
15
|
+
prompt: t('.blank'),
|
16
|
+
include_blank: false,
|
17
|
+
required: true,
|
18
|
+
'data-filters-target': 'input',
|
19
|
+
'data-action': "change->filters#update"
|
20
|
+
} %>
|
21
|
+
|
22
|
+
<%= content_for :filters_menu do %>
|
23
|
+
<%= render 'headmin/filters/filter/menu_item', name: name, label: label %>
|
24
|
+
<% end %>
|
25
|
+
|
26
|
+
<%= content_for :filters_templates do %>
|
27
|
+
<%= render 'headmin/filters/filter/template', name: name, label: label do %>
|
28
|
+
<%= select_tag("#{name}[]", options_for_select(options), select_options) %>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<%= content_for :filters_buttons do %>
|
33
|
+
<% if filter_param_exists?(name) %>
|
34
|
+
<% option_name = options.select { |value, key| params[name].include?(key.to_s)}.map{|value, key| value}.join(', ') %>
|
35
|
+
<%= render 'headmin/filters/filter/button', name: name, label: label, value: option_name do %>
|
36
|
+
<%= select_tag("#{name}[]", options_for_select(options, params[name]), select_options) %>
|
37
|
+
<% end %>
|
38
|
+
<% end %>
|
39
|
+
<% end %>
|