standard_view 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +31 -10
- data/Rakefile +3 -8
- data/app/helpers/standard_view/application_helper.rb +38 -0
- data/app/helpers/standard_view/badge_helper.rb +22 -0
- data/app/helpers/standard_view/flash_helper.rb +16 -0
- data/app/helpers/standard_view/formatting_helper.rb +21 -0
- data/app/helpers/standard_view/masthead_helper.rb +27 -0
- data/app/helpers/standard_view/navigation_helper.rb +51 -0
- data/app/views/application/_attributes_card.html.erb +32 -0
- data/app/views/application/_flash_messages.html.erb +7 -0
- data/app/views/application/_icon.html.erb +5 -0
- data/app/views/application/_javascripts.html.erb +25 -0
- data/app/views/application/_list_item.html.erb +11 -0
- data/app/views/application/_masthead.html.erb +21 -0
- data/app/views/application/_masthead_brand.html.erb +1 -0
- data/app/views/application/_masthead_nav.html.erb +6 -0
- data/app/views/application/_masthead_nav_items.html.erb +8 -0
- data/app/views/application/_masthead_nav_menu.html.erb +8 -0
- data/app/views/application/_masthead_nav_menu_icon.html.erb +1 -0
- data/app/views/application/_masthead_nav_menu_items.html.erb +10 -0
- data/app/views/application/_stylesheet_font_awesome.html.erb +6 -0
- data/app/views/application/_stylesheets.html.erb +12 -0
- data/app/views/application/index.html.erb +1 -0
- data/app/views/application/show.html.erb +1 -0
- data/app/views/layouts/standard_view/application.html.erb +8 -7
- data/app/views/standard_view/_breadcrumbs.html.erb +48 -0
- data/app/views/standard_view/_index.html.erb +83 -0
- data/app/views/standard_view/_list_item.html.erb +29 -0
- data/app/views/standard_view/_navigation_aside.html.erb +5 -0
- data/app/views/standard_view/_navigation_tabs.html.erb +5 -0
- data/app/views/standard_view/_page_content.html.erb +8 -0
- data/app/views/standard_view/_paginated_collection.html.erb +8 -0
- data/app/views/standard_view/_show.html.erb +48 -0
- data/config/initializers/material.rb +9 -0
- data/config/initializers/simple_form.rb +184 -0
- data/config/initializers/simple_form_bootstrap.rb +457 -0
- data/config/initializers/will_paginate.rb +57 -0
- data/config/locales/en.yml +12 -0
- data/lib/standard_view/engine.rb +11 -0
- data/lib/standard_view/version.rb +3 -1
- data/lib/standard_view.rb +7 -3
- metadata +169 -21
- data/app/assets/config/standard_view_manifest.js +0 -2
- data/app/assets/javascripts/standard_view/application.js +0 -14
- data/app/assets/stylesheets/standard_view/application.css +0 -15
- data/app/controllers/standard_view/application_controller.rb +0 -5
- data/app/jobs/standard_view/application_job.rb +0 -4
- data/app/mailers/standard_view/application_mailer.rb +0 -6
- data/app/models/standard_view/application_record.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 824ed5917b07dfd7e64412849c15dad8645763bf244cb7386e0c1d05f52922f5
|
4
|
+
data.tar.gz: e156d437fc328b5365dc16712a19435e0ca4a704a081fa3d1e5a7fd89fd6b00c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01adcd82c9011b0f7251c6cc6063416e71eca9fbbf1ee21dd49aba6efcab0d37d346e78e0455dbd8f781e1c1d8611ffd19df2225bf0d7d6adcb03415a4aa5ee6
|
7
|
+
data.tar.gz: 6503b79daf574e4f03bef75e04873537dad8931a7adf50615cd6325254812e82894fd07304d7e94b90f20ace5de00150a184e647adae0ab2cfdb33f0ee43386f
|
data/README.md
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
# StandardView
|
2
|
-
Short description and motivation.
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
Use Bootstrap to present a nicely standardized view for your models.
|
4
|
+
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/standard_view.svg)](https://badge.fury.io/rb/standard_view)
|
6
|
+
[![Build Status](https://semaphoreci.com/api/v1/freshly/standard_view/branches/develop/badge.svg)](https://semaphoreci.com/freshly/standard_view)
|
7
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/beccb908a058d1c51245/maintainability)](https://codeclimate.com/github/Freshly/standard_view/maintainability)
|
8
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/beccb908a058d1c51245/test_coverage)](https://codeclimate.com/github/Freshly/standard_view/test_coverage)
|
9
|
+
|
10
|
+
* [StandardView](#standardview)
|
11
|
+
* [Installation](#installation)
|
12
|
+
* [Usage](#usage)
|
13
|
+
* [Development](#development)
|
14
|
+
* [Contributing](#contributing)
|
15
|
+
* [License](#license)
|
6
16
|
|
7
17
|
## Installation
|
18
|
+
|
8
19
|
Add this line to your application's Gemfile:
|
9
20
|
|
10
21
|
```ruby
|
@@ -12,17 +23,27 @@ gem 'standard_view'
|
|
12
23
|
```
|
13
24
|
|
14
25
|
And then execute:
|
15
|
-
|
16
|
-
$ bundle
|
17
|
-
```
|
26
|
+
|
27
|
+
$ bundle
|
18
28
|
|
19
29
|
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install standard_view
|
22
|
-
|
30
|
+
|
31
|
+
$ gem install standard_view
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
TODO: Write usage instructions here
|
36
|
+
|
37
|
+
## Development
|
38
|
+
|
39
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
40
|
+
|
41
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
23
42
|
|
24
43
|
## Contributing
|
25
|
-
|
44
|
+
|
45
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Freshly/standard_view.
|
26
46
|
|
27
47
|
## License
|
48
|
+
|
28
49
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
@@ -17,13 +17,8 @@ end
|
|
17
17
|
load 'rails/tasks/statistics.rake'
|
18
18
|
|
19
19
|
require 'bundler/gem_tasks'
|
20
|
+
require "rspec/core/rake_task"
|
20
21
|
|
21
|
-
|
22
|
+
RSpec::Core::RakeTask.new(:spec)
|
22
23
|
|
23
|
-
|
24
|
-
t.libs << 'test'
|
25
|
-
t.pattern = 'test/**/*_test.rb'
|
26
|
-
t.verbose = false
|
27
|
-
end
|
28
|
-
|
29
|
-
task default: :test
|
24
|
+
task default: :spec
|
@@ -1,4 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StandardView
|
2
4
|
module ApplicationHelper
|
5
|
+
def action
|
6
|
+
ActiveSupport::StringInquirer.new action_name
|
7
|
+
end
|
8
|
+
|
9
|
+
def active_for(options = {})
|
10
|
+
"active" if on_page?(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_page?(check_parameters: false, **options)
|
14
|
+
current_page?(options, check_parameters: check_parameters)
|
15
|
+
rescue ActionController::UrlGenerationError
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def icon_for(reference, spin: false)
|
20
|
+
reference = reference.icon if reference.respond_to?(:icon)
|
21
|
+
definition = if reference.nil?
|
22
|
+
{}
|
23
|
+
elsif reference.respond_to?(:to_h)
|
24
|
+
reference.to_h
|
25
|
+
else
|
26
|
+
I18n.t("icons.#{reference}", default: nil) || reference
|
27
|
+
end
|
28
|
+
|
29
|
+
definition = { name: definition } if definition.present? && !definition.respond_to?(:fetch)
|
30
|
+
|
31
|
+
icon_tag(definition[:name], definition[:style], spin: spin)
|
32
|
+
end
|
33
|
+
|
34
|
+
def current_page
|
35
|
+
params[:page]
|
36
|
+
end
|
37
|
+
|
38
|
+
def icon_tag(name = nil, style = nil, spin: false)
|
39
|
+
content_tag(:i, "", class: "fa#{style || "s"} fa-#{name || "question"} #{"fa-spin" if spin}")
|
40
|
+
end
|
3
41
|
end
|
4
42
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module StandardView
|
2
|
+
module BadgeHelper
|
3
|
+
def badge(content, type: "dark", right: false, pill: false, extra_class: nil, **options)
|
4
|
+
extra = "#{"badge-pill" if pill} #{"float-right mt-1 ml-2" if right} #{extra_class}"
|
5
|
+
content_tag :span, content, class: "badge badge-#{type} #{extra}", **options
|
6
|
+
end
|
7
|
+
|
8
|
+
def count_badge(value, type: "dark", extra_class: "ml-1", **options)
|
9
|
+
number = value.respond_to?(:count) ? value.count : value
|
10
|
+
badge_type = block_given? ? yield(number) : type
|
11
|
+
badge number_with_delimiter(number), type: badge_type, extra_class: extra_class, **options
|
12
|
+
end
|
13
|
+
|
14
|
+
def unread_badge(value, **options)
|
15
|
+
count_badge(value, **options) { |number| number.zero? ? "dark" : "danger" }
|
16
|
+
end
|
17
|
+
|
18
|
+
def boolean_badge(is, **options)
|
19
|
+
badge t(is ? "common.on" : "common.off"), type: is ? "success" : "danger", **options
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StandardView
|
4
|
+
module FlashHelper
|
5
|
+
ALERT_CLASSES_BY_FLASH_TYPE = {
|
6
|
+
success: "alert-success",
|
7
|
+
error: "alert-danger",
|
8
|
+
alert: "alert-warning",
|
9
|
+
notice: "alert-info",
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
def alert_class_for_flash(flash_type)
|
13
|
+
ALERT_CLASSES_BY_FLASH_TYPE.fetch(flash_type.to_sym, flash_type.to_s)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StandardView
|
4
|
+
module FormattingHelper
|
5
|
+
def title_for_collection(collection)
|
6
|
+
title_for_model(collection.model)
|
7
|
+
end
|
8
|
+
|
9
|
+
def title_for_model(model)
|
10
|
+
heading_for_model(model).pluralize
|
11
|
+
end
|
12
|
+
|
13
|
+
def heading_for_model(model)
|
14
|
+
model.model_name.human.titleize
|
15
|
+
end
|
16
|
+
|
17
|
+
def color_square(color, size: "24px")
|
18
|
+
content_tag(:div, "", title: color, style: "width: #{size}; height: #{size}; background: #{color}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StandardView
|
4
|
+
module MastheadHelper
|
5
|
+
def masthead_nav_link_for_model(model_class)
|
6
|
+
list = Material::List.for(model_class)
|
7
|
+
masthead_nav_link list.item_class, list.list_title, active_for(controller: list.route_key)
|
8
|
+
end
|
9
|
+
|
10
|
+
def masthead_menu_link_for_model(model_class)
|
11
|
+
list = Material::List.for(model_class)
|
12
|
+
masthead_menu_link list.item_class, list.icon, list.list_title, active_for(controller: list.route_key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def masthead_nav_link(destination, text, class_name = nil, **options)
|
16
|
+
link_to(destination, class: "nav-item nav-link #{class_name}", **options) { text }
|
17
|
+
end
|
18
|
+
|
19
|
+
def masthead_menu_link(destination, icon_type, text, class_name = nil, **options)
|
20
|
+
link_to(destination, class: "dropdown-item #{class_name}", **options) { icon_with_text(icon_type, text) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def icon_with_text(icon_type, text)
|
24
|
+
"#{icon_for(icon_type)} #{text}".html_safe
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StandardView
|
4
|
+
module NavigationHelper
|
5
|
+
def nav_item_overview_for_material(material)
|
6
|
+
active_link_class = active_for(controller: material.route_key, action: :show)
|
7
|
+
content_tag(:li, class: "nav-item") do
|
8
|
+
link_to(t("common.overview"), material, class: "nav-link #{active_link_class}")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def nav_item_nested_model_for_record(record, model, count_method = nil)
|
13
|
+
nav_item_related_model_for_record(record, model, count_method, nested: true)
|
14
|
+
end
|
15
|
+
|
16
|
+
def nav_item_related_model_for_record(record, model, count_method = nil, nested: false)
|
17
|
+
collection = model.model_name.collection
|
18
|
+
count_method ||= begin
|
19
|
+
default_count_method_name = "#{collection}_count".to_sym
|
20
|
+
record.respond_to?(default_count_method_name) ? default_count_method_name : collection
|
21
|
+
end
|
22
|
+
|
23
|
+
link_target = [ collection, record ]
|
24
|
+
link_target.reverse! if nested
|
25
|
+
|
26
|
+
active_link_arguments = { controller: (nested ? model : record).model_name.collection }
|
27
|
+
active_link_arguments[:action] = collection unless nested
|
28
|
+
|
29
|
+
nav_item(
|
30
|
+
link_target: link_target,
|
31
|
+
icon: model.model_name.singular.to_sym,
|
32
|
+
title: title_for_model(model),
|
33
|
+
count: record.public_send(count_method.to_sym),
|
34
|
+
active_class: active_for(**active_link_arguments),
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def nav_item(link_target:, icon:, title:, count:, active_class:)
|
39
|
+
content_tag(:li, class: "nav-item") do
|
40
|
+
link_to(link_target, class: "nav-link #{active_class}") do
|
41
|
+
content_tag(:span) do
|
42
|
+
concat icon_for(icon)
|
43
|
+
concat " ".html_safe
|
44
|
+
concat title
|
45
|
+
concat count_badge(count)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<% cache material do %>
|
2
|
+
<div class="card">
|
3
|
+
<div class="card-header">
|
4
|
+
<%# if content_for?(:attributes_action) %>
|
5
|
+
<%#= content_for(:attributes_action) %>
|
6
|
+
<%# else %>
|
7
|
+
<%# if controller.action_methods.include?("edit") && (!record.respond_to?(:editable?) || record.editable?) %>
|
8
|
+
<%#= link_to t("edit"), { action: :edit }, class: "btn btn-primary btn-sm float-right" %>
|
9
|
+
<%# elsif controller.action_methods.include? "destroy" %>
|
10
|
+
<%# if (!record.respond_to?(:destroyable?) || record.destroyable?) %>
|
11
|
+
<%#= link_to t("destroy"), record, class: "btn btn-danger btn-sm float-right", method: :delete, data: { confirm: t("confirm_destroy") } %>
|
12
|
+
<%# end %>
|
13
|
+
<%# end %>
|
14
|
+
<%#= content_for(:extra_attributes_action) if content_for?(:extra_attributes_action) %>
|
15
|
+
<%# end %>
|
16
|
+
|
17
|
+
<h4 class="mb-0"><%= t(".title") %></h4>
|
18
|
+
</div>
|
19
|
+
<div class="card-body p-0">
|
20
|
+
<table class="table m-0">
|
21
|
+
<tbody>
|
22
|
+
<% material.sorted_attribute_names.each do |attribute_name| %>
|
23
|
+
<tr>
|
24
|
+
<th><%= material.human_attribute_name(attribute_name) %></th>
|
25
|
+
<td><%= material.human_attribute_value(attribute_name) %></td>
|
26
|
+
</tr>
|
27
|
+
<% end %>
|
28
|
+
</tbody>
|
29
|
+
</table>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
<% end %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%= javascript_include_tag "https://www.gstatic.com/charts/loader.js" %>
|
2
|
+
|
3
|
+
<script
|
4
|
+
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
|
5
|
+
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
|
6
|
+
crossorigin="anonymous"
|
7
|
+
></script>
|
8
|
+
<script
|
9
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
|
10
|
+
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
|
11
|
+
crossorigin="anonymous"
|
12
|
+
></script>
|
13
|
+
<script
|
14
|
+
src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
|
15
|
+
integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
|
16
|
+
crossorigin="anonymous"
|
17
|
+
></script>
|
18
|
+
<script
|
19
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-colorpicker/2.5.3/js/bootstrap-colorpicker.min.js"
|
20
|
+
crossorigin="anonymous"
|
21
|
+
></script>
|
22
|
+
|
23
|
+
<%= javascript_include_tag "application" %>
|
24
|
+
|
25
|
+
<%= content_for(:page_scripts) if content_for?(:page_scripts) %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% render_default_partial = true %>
|
2
|
+
<% source_partial_path = list_item.source.try(:to_partial_path) %>
|
3
|
+
<% if source_partial_path.present? %>
|
4
|
+
<% prefix, path = source_partial_path.split("/") %>
|
5
|
+
<% if lookup_context.template_exists?(path, prefix, true) %>
|
6
|
+
<% render_default_partial = false %>
|
7
|
+
<%= render partial: source_partial_path, locals: { path.to_sym => list_item } %>
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<%= render "standard_view/list_item", material: list_item if render_default_partial %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<header class="navbar navbar-expand-lg navbar-dark bg-dark mb-3">
|
2
|
+
<div class="container">
|
3
|
+
<%= render "masthead_brand" %>
|
4
|
+
|
5
|
+
<button
|
6
|
+
class="navbar-toggler"
|
7
|
+
type="button"
|
8
|
+
data-toggle="collapse"
|
9
|
+
data-target="#masthead-nav"
|
10
|
+
aria-controls="masthead-nav"
|
11
|
+
aria-expanded="false"
|
12
|
+
aria-label="Toggle navigation"
|
13
|
+
>
|
14
|
+
<span class="navbar-toggler-icon"></span>
|
15
|
+
</button>
|
16
|
+
|
17
|
+
<section class="collapse navbar-collapse" id="masthead-nav">
|
18
|
+
<%= render "masthead_nav" %>
|
19
|
+
</section>
|
20
|
+
</div>
|
21
|
+
</header>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= link_to t("application.brand"), root_path, class: "navbar-brand" %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<!-- Define your own masthead navigation:
|
2
|
+
app/views/application/_masthead_nav_items.html.erb => Application Default
|
3
|
+
app/views/something_else/_masthead_nav_items.html.erb => Specific Override
|
4
|
+
|
5
|
+
Example:
|
6
|
+
<%#= masthead_nav_link_for_model School %>
|
7
|
+
<%#= masthead_nav_link reports_path, t(".reports"), active_for(controller: :reports) %>
|
8
|
+
-->
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div class="dropdown">
|
2
|
+
<%= link_to "#", class: "nav-link dropdown-toggle", id: "masthead-settings-menu", data: { toggle: "dropdown" } do %>
|
3
|
+
<%= render "masthead_nav_menu_icon" %>
|
4
|
+
<% end %>
|
5
|
+
<nav class="dropdown-menu dropdown-menu-right" aria-labelledby="masthead-settings-menu">
|
6
|
+
<%= render "masthead_nav_menu_items" %>
|
7
|
+
</nav>
|
8
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= icon_for :masthead_nav_menu %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<!-- Define your own masthead menu navigation:
|
2
|
+
app/views/application/_masthead_nav_menu_items.html.erb => Application Default
|
3
|
+
app/views/something_else/_masthead_nav_menu_items.html.erb => Specific Override
|
4
|
+
|
5
|
+
Example:
|
6
|
+
<h6 class="dropdown-header"><%#= t(".build") %></h6>
|
7
|
+
<%#= masthead_menu_link_for_model School %>
|
8
|
+
<div class="dropdown-divider"></div>
|
9
|
+
<%#= masthead_menu_link reports_path, "flag-checkered", t(".reports"), active_for(controller: :reports) %>
|
10
|
+
-->
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<link
|
2
|
+
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
|
3
|
+
rel="stylesheet"
|
4
|
+
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
|
5
|
+
crossorigin="anonymous"
|
6
|
+
>
|
7
|
+
<link
|
8
|
+
rel="stylesheet"
|
9
|
+
href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-colorpicker/2.5.3/css/bootstrap-colorpicker.min.css"
|
10
|
+
crossorigin="anonymous"
|
11
|
+
>
|
12
|
+
<%= render "stylesheet_font_awesome" %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render "standard_view/index" %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render "standard_view/show" %>
|
@@ -1,16 +1,17 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<title>
|
4
|
+
<title>
|
5
|
+
<%= "#{content_for(:title)} #{t("application.separator")} " if content_for?(:title) %><%= t("application.title") %>
|
6
|
+
</title>
|
5
7
|
<%= csrf_meta_tags %>
|
6
8
|
<%= csp_meta_tag %>
|
7
|
-
|
8
|
-
<%=
|
9
|
-
<%= javascript_include_tag "standard_view/application" %>
|
9
|
+
<%= render "stylesheets" %>
|
10
|
+
<%= render "javascripts" %>
|
10
11
|
</head>
|
11
12
|
<body>
|
12
|
-
|
13
|
-
<%=
|
14
|
-
|
13
|
+
<%= render "masthead" %>
|
14
|
+
<%= render "flash_messages" %>
|
15
|
+
<%= yield %>
|
15
16
|
</body>
|
16
17
|
</html>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<nav aria-label="breadcrumb">
|
2
|
+
<ol class="breadcrumb">
|
3
|
+
<% if material.parent? %>
|
4
|
+
<% parent = material.parent %>
|
5
|
+
<li class="breadcrumb-item">
|
6
|
+
<% if parent.index_path? %>
|
7
|
+
<%= link_to title_for_model(parent), public_send(parent.index_path) %>
|
8
|
+
<% else %>
|
9
|
+
…
|
10
|
+
<% end %>
|
11
|
+
</li>
|
12
|
+
<li class="breadcrumb-item"><%= link_to parent.breadcrumb_title, parent %></li>
|
13
|
+
|
14
|
+
<% unless on_page?(controller: parent.route_key, action: material.route_key) %>
|
15
|
+
<li class="breadcrumb-item"><%= link_to title_for_model(material), [ material.route_key, parent ] %></li>
|
16
|
+
<% end %>
|
17
|
+
<% else %>
|
18
|
+
<li class="breadcrumb-item">
|
19
|
+
<% if material.index_path? %>
|
20
|
+
<%= link_to title_for_model(material), public_send(material.index_path) %>
|
21
|
+
<% else %>
|
22
|
+
…
|
23
|
+
<% end %>
|
24
|
+
</li>
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
<% if on_page?(controller: material.route_key, action: :show) %>
|
28
|
+
<li class="breadcrumb-item active" aria-current="page"><%= material.breadcrumb_title %></li>
|
29
|
+
<% else %>
|
30
|
+
<% if on_page?(controller: material.route_key) %>
|
31
|
+
<li class="breadcrumb-item"><%= link_to material.breadcrumb_title, material %></li>
|
32
|
+
<% end %>
|
33
|
+
<li class="breadcrumb-item active" aria-current="page">
|
34
|
+
<% if local_assigns[:label].present? %>
|
35
|
+
<%= local_assigns[:label] %>
|
36
|
+
<% elsif I18n.exists?("breadcrumbs.#{controller_name}.#{action_name}") %>
|
37
|
+
<%= t("breadcrumbs.#{controller_name}.#{action_name}") %>
|
38
|
+
<% elsif I18n.exists?("breadcrumbs.actions.#{action_name}") %>
|
39
|
+
<%= t("breadcrumbs.actions.#{action_name}") %>
|
40
|
+
<% elsif I18n.exists?("breadcrumbs.controllers.#{controller_name}") %>
|
41
|
+
<%= t("breadcrumbs.controllers.#{controller_name}") %>
|
42
|
+
<% else %>
|
43
|
+
<%= action_name.humanize %>
|
44
|
+
<% end %>
|
45
|
+
</li>
|
46
|
+
<% end %>
|
47
|
+
</ol>
|
48
|
+
</nav>
|
@@ -0,0 +1,83 @@
|
|
1
|
+
<%# For the good-spirited and impossibly lazy developer, we attempt to jump-start, assuming conventions. %>
|
2
|
+
<% is_nested = local_assigns[:nested] %>
|
3
|
+
|
4
|
+
<% facet_source = local_assigns[:facet_source] %>
|
5
|
+
<% if is_nested && facet_source.nil? %>
|
6
|
+
<% facet_source = controller_name.singularize.camelize.constantize.find(params[:id]) %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<% if local_assigns[:facet].nil? %>
|
10
|
+
<% facet_name = is_nested ? action_name : controller_name %>
|
11
|
+
<% facet_class = local_assigns[:facet_class].presence || "#{facet_name.singularize.camelize}Facet".constantize %>
|
12
|
+
<% facet = facet_class.new(current_page: current_page, source: facet_source) %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% if local_assigns[:list].nil? %>
|
16
|
+
<% list = Material::List.for(facet.record_class) %>
|
17
|
+
<% list.contextualize(facet_source) if is_nested %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<%# Title must remain outside the cache block or it will not be assigned properly (since it affects the page layout) %>
|
21
|
+
<% content_for(:title) { list.title } %>
|
22
|
+
|
23
|
+
<% cache facet do %>
|
24
|
+
<%# Within the cache block, mount the facet for rendering %>
|
25
|
+
<% list.mount_facet(facet) %>
|
26
|
+
<% list_law = law(list.item_class) %>
|
27
|
+
|
28
|
+
<% if list.parent? %>
|
29
|
+
<% if lookup_context.template_exists?("navigation_tabs", controller_name, true) %>
|
30
|
+
<% content_for(:navigation_tabs) { render "navigation_tabs", material: list.parent } %>
|
31
|
+
<% elsif lookup_context.template_exists?("navigation_aside", controller_name, true) %>
|
32
|
+
<% content_for(:navigation_aside) { render "navigation_aside", material: list.parent } %>
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
35
|
+
|
36
|
+
<%= content_tag :main, id: "#{list.parameterized_title}-index", class: "container" do %>
|
37
|
+
<header>
|
38
|
+
<%= render "standard_view/breadcrumbs", material: list if list.parent? %>
|
39
|
+
|
40
|
+
<% if on_page?(action: :index) %>
|
41
|
+
<%= link_to t("common.new"), { action: :new }, class: "btn btn-primary btn-lg float-right" if list_law.new? %>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<%= content_tag(:h5, class: "text-muted") { heading_for_model(list.parent) } if list.parent? %>
|
45
|
+
|
46
|
+
<h1 class="mb-3"><%= list.title %></h1>
|
47
|
+
|
48
|
+
<%= render "standard_view/navigation_tabs" if content_for?(:navigation_tabs) %>
|
49
|
+
</header>
|
50
|
+
|
51
|
+
<%= content_tag(:hr) unless content_for?(:navigation_tabs) %>
|
52
|
+
|
53
|
+
<% unless content_for?(:page_content) %>
|
54
|
+
<% content_for(:page_content) do %>
|
55
|
+
<%# if content_for?(:subnav_content) || uses_filter %>
|
56
|
+
<%#= content_for(:subnav_content) if content_for?(:subnav_content) %>
|
57
|
+
|
58
|
+
<%# if uses_filter %>
|
59
|
+
<%#= render "filter", field: filter_by, default: local_assigns[:filter_default], model: collection.model %>
|
60
|
+
<%# end %>
|
61
|
+
<!-- <hr>-->
|
62
|
+
<%# end %>
|
63
|
+
|
64
|
+
<div class="row">
|
65
|
+
<div class="col-12">
|
66
|
+
<%# filtered_collection = collection %>
|
67
|
+
<%# if uses_filter %>
|
68
|
+
<%# if params[:filter].present? %>
|
69
|
+
<%# filtered_collection = filtered_collection.public_send(params[:filter].to_sym) %>
|
70
|
+
<%# elsif has_filter_default && !params[:all].present? %>
|
71
|
+
<%# filtered_collection = filtered_collection.public_send(filter_default) %>
|
72
|
+
<%# end %>
|
73
|
+
<%# end %>
|
74
|
+
|
75
|
+
<%= render "standard_view/paginated_collection", list: list, is_filtered: facet.filtered? %>
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
<% end %>
|
79
|
+
<% end %>
|
80
|
+
|
81
|
+
<%= render "standard_view/page_content" %>
|
82
|
+
<% end %>
|
83
|
+
<% end %>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<% content_for(:standard_list_item, flush: true) do %>
|
2
|
+
<%= render "icon", material: material %>
|
3
|
+
|
4
|
+
<% if material.list_title_truncated? %>
|
5
|
+
<%= content_tag :span, material.list_title, title: material.list_title_value, class: "px-2" %>
|
6
|
+
<% else %>
|
7
|
+
<%= content_tag :span, material.list_title, class: "px-2" %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<% if material.label? %>
|
11
|
+
<% label_options = { pill: true } %>
|
12
|
+
<% label_options[:type] = material.label_style if material.label_style? %>
|
13
|
+
<%= badge material.label, **label_options %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<% if material.badge? %>
|
17
|
+
<% badge_options = { right: true } %>
|
18
|
+
<% badge_options[:type] = material.badge_style if material.badge_style? %>
|
19
|
+
<%= badge material.badge, **badge_options %>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% list_item_style_class = material.list_item_style? ? " list-group-item-#{material.list_item_style}" : "" %>
|
24
|
+
<% class_name = "list-group-item list-group-item-action#{list_item_style_class}" %>
|
25
|
+
<% if material.path? %>
|
26
|
+
<%= link_to content_for(:standard_list_item), material, class: class_name %>
|
27
|
+
<% else %>
|
28
|
+
<%= content_tag :span, content_for(:standard_list_item), class: class_name %>
|
29
|
+
<% end %>
|