hyper-kitten-tables 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +3 -0
  5. data/lib/hyper-kitten-tables.rb +6 -0
  6. data/lib/hyper_kitten_tables/components/table.rb +7 -0
  7. data/lib/hyper_kitten_tables/concerns/table.rb +134 -0
  8. data/lib/hyper_kitten_tables/engine.rb +5 -0
  9. data/lib/hyper_kitten_tables/version.rb +3 -0
  10. data/lib/tasks/tables_tasks.rake +4 -0
  11. data/spec/components/table_spec.rb +209 -0
  12. data/spec/dummy/Rakefile +6 -0
  13. data/spec/dummy/app/assets/config/manifest.js +3 -0
  14. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  15. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  16. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  17. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  18. data/spec/dummy/app/controllers/pages_controller.rb +3 -0
  19. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  20. data/spec/dummy/app/jobs/application_job.rb +7 -0
  21. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  22. data/spec/dummy/app/models/application_record.rb +3 -0
  23. data/spec/dummy/app/views/hyper_kitten_meow/pages/hardcoded_page.html.haml +4 -0
  24. data/spec/dummy/app/views/pages/app_hardcoded_page.html.haml +4 -0
  25. data/spec/dummy/app/views/pages/show.html.haml +3 -0
  26. data/spec/dummy/bin/rails +4 -0
  27. data/spec/dummy/bin/rake +4 -0
  28. data/spec/dummy/bin/setup +33 -0
  29. data/spec/dummy/config/application.rb +26 -0
  30. data/spec/dummy/config/boot.rb +5 -0
  31. data/spec/dummy/config/cable.yml +10 -0
  32. data/spec/dummy/config/database.yml +16 -0
  33. data/spec/dummy/config/environment.rb +5 -0
  34. data/spec/dummy/config/environments/development.rb +56 -0
  35. data/spec/dummy/config/environments/production.rb +93 -0
  36. data/spec/dummy/config/environments/test.rb +50 -0
  37. data/spec/dummy/config/initializers/assets.rb +12 -0
  38. data/spec/dummy/config/initializers/content_security_policy.rb +26 -0
  39. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  40. data/spec/dummy/config/initializers/inflections.rb +16 -0
  41. data/spec/dummy/config/initializers/permissions_policy.rb +11 -0
  42. data/spec/dummy/config/locales/en.yml +33 -0
  43. data/spec/dummy/config/puma.rb +43 -0
  44. data/spec/dummy/config/routes.rb +3 -0
  45. data/spec/dummy/config/storage.yml +34 -0
  46. data/spec/dummy/config.ru +6 -0
  47. data/spec/dummy/db/migrate/20220805173427_create_action_text_tables.action_text.rb +26 -0
  48. data/spec/dummy/db/migrate/20220805173748_create_active_storage_tables.active_storage.rb +57 -0
  49. data/spec/dummy/db/schema.rb +134 -0
  50. data/spec/dummy/db/seeds.rb +23 -0
  51. data/spec/dummy/log/development.log +12689 -0
  52. data/spec/dummy/log/test.log +58989 -0
  53. data/spec/dummy/public/404.html +67 -0
  54. data/spec/dummy/public/422.html +67 -0
  55. data/spec/dummy/public/500.html +66 -0
  56. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  57. data/spec/dummy/public/apple-touch-icon.png +0 -0
  58. data/spec/dummy/public/favicon.ico +0 -0
  59. data/spec/dummy/storage/it/lb/itlbn65dlnw20cu9ii6epg3qtr0h +0 -0
  60. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-16-58-13.777.html +148 -0
  61. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-16-59-53.965.html +148 -0
  62. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-00-42.481.html +148 -0
  63. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-01-02.940.html +229 -0
  64. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-03-02.450.html +229 -0
  65. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-03-17.782.html +148 -0
  66. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-03-57.376.html +229 -0
  67. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-07-53.996.html +232 -0
  68. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-13-29.891.html +232 -0
  69. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-13-56.197.html +232 -0
  70. data/spec/dummy/tmp/capybara/screenshot_2022-10-04-17-15-26.557.html +232 -0
  71. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-14-43-43.563.html +165 -0
  72. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-14-45-19.375.html +157 -0
  73. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-15-29-06.088.html +1 -0
  74. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-15-29-06.102.html +1 -0
  75. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-15-29-06.116.html +1 -0
  76. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-15-29-06.193.html +1 -0
  77. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-15-29-06.206.html +1 -0
  78. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-26-51.644.html +96 -0
  79. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-26-54.957.html +91 -0
  80. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-30-28.415.html +91 -0
  81. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-30-34.037.html +96 -0
  82. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-43-01.197.html +91 -0
  83. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-43-04.942.html +96 -0
  84. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-45-09.535.html +96 -0
  85. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-45-14.082.html +91 -0
  86. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-45-26.094.html +96 -0
  87. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-45-26.446.html +91 -0
  88. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-57-08.858.html +96 -0
  89. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-57-11.332.html +91 -0
  90. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-58-08.456.html +91 -0
  91. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-16-58-08.832.html +96 -0
  92. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-02-35.674.html +91 -0
  93. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-02-39.415.html +96 -0
  94. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-03-38.082.html +96 -0
  95. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-03-38.564.html +91 -0
  96. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-04-08.143.html +91 -0
  97. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-04-08.472.html +96 -0
  98. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-04-34.570.html +91 -0
  99. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-04-40.657.html +96 -0
  100. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-04-52.001.html +91 -0
  101. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-04-52.410.html +96 -0
  102. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-06-40.488.html +91 -0
  103. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-06-46.796.html +96 -0
  104. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-09-28.828.html +91 -0
  105. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-09-32.459.html +96 -0
  106. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-09-45.931.html +91 -0
  107. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-09-46.318.html +96 -0
  108. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-12-03.393.html +96 -0
  109. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-12-06.113.html +91 -0
  110. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-12-11.111.html +96 -0
  111. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-12-16.868.html +91 -0
  112. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-15-57.176.html +91 -0
  113. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-16-03.653.html +96 -0
  114. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-29-32.001.html +91 -0
  115. data/spec/dummy/tmp/capybara/screenshot_2022-10-05-17-29-34.702.html +96 -0
  116. data/spec/dummy/tmp/capybara/screenshot_2022-10-11-16-24-42.604.html +85 -0
  117. data/spec/dummy/tmp/capybara/screenshot_2022-10-11-16-25-08.753.html +76 -0
  118. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-02-02.769.html +0 -0
  119. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-08-16.549.html +0 -0
  120. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-09-06.988.html +0 -0
  121. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-10-02.456.html +0 -0
  122. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-12-58.767.html +0 -0
  123. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-13-38.946.html +0 -0
  124. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-20-23.040.html +0 -0
  125. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-22-40.972.html +31 -0
  126. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-30-50.210.html +31 -0
  127. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-31-41.216.html +31 -0
  128. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-42-03.223.html +31 -0
  129. data/spec/dummy/tmp/capybara/screenshot_2022-10-12-14-53-14.392.html +0 -0
  130. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-52-54.850.html +35 -0
  131. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-53-03.992.html +0 -0
  132. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-53-40.077.html +0 -0
  133. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-53-55.068.html +0 -0
  134. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-54-08.951.html +0 -0
  135. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-54-39.523.html +0 -0
  136. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-55-46.588.html +0 -0
  137. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-56-53.302.html +0 -0
  138. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-57-13.712.html +0 -0
  139. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-16-59-55.972.html +0 -0
  140. data/spec/dummy/tmp/capybara/screenshot_2022-10-18-17-04-32.815.html +0 -0
  141. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-19-45-56.483.html +1 -0
  142. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-19-51-45.853.html +54 -0
  143. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-19-56-35.870.html +1 -0
  144. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-19-58-42.872.html +1 -0
  145. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-19-59-53.565.html +1 -0
  146. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-25-51.194.html +1 -0
  147. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-27-18.607.html +1 -0
  148. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-34-14.915.html +1 -0
  149. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-34-23.967.html +1 -0
  150. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-35-20.693.html +0 -0
  151. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-38-57.780.html +1 -0
  152. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-39-59.478.html +1 -0
  153. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-40-32.807.html +0 -0
  154. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-40-42.311.html +1 -0
  155. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-41-40.038.html +1 -0
  156. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-43-18.794.html +1 -0
  157. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-45-22.057.html +9 -0
  158. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-46-07.622.html +1 -0
  159. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-46-23.810.html +1 -0
  160. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-46-42.443.html +9 -0
  161. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-47-03.378.html +1 -0
  162. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-49-38.206.html +1 -0
  163. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-49-53.697.html +1 -0
  164. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-50-25.359.html +1 -0
  165. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-50-43.146.html +9 -0
  166. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-51-18.812.html +54 -0
  167. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-51-55.591.html +78 -0
  168. data/spec/dummy/tmp/capybara/screenshot_2022-11-16-20-52-42.586.html +78 -0
  169. data/spec/dummy/tmp/development_secret.txt +1 -0
  170. data/spec/dummy/tmp/restart.txt +0 -0
  171. data/spec/features/admin/create_first_user_spec.rb +34 -0
  172. data/spec/features/admin/menu_management_spec.rb +137 -0
  173. data/spec/features/admin/page_management_spec.rb +73 -0
  174. data/spec/features/admin/post_management_spec.rb +80 -0
  175. data/spec/features/admin/users_management_spec.rb +65 -0
  176. data/spec/features/display_pages_spec.rb +45 -0
  177. data/spec/features/display_posts_spec.rb +0 -0
  178. data/spec/rails_helper.rb +13 -0
  179. metadata +502 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 83419fee953f6b9bf30e241452485f7618895c4f736958b7fd892da7658c59fe
4
+ data.tar.gz: e958eb144264555b6107282a2cfb8d3f04466745715a097692be34889f97ef56
5
+ SHA512:
6
+ metadata.gz: 826fd4136a3ef599cf4e8e16355859b8dd021167a07ea85589282c13e8dc2ea5cecd75b75c51b9c105276c675d1309ed5b3d64da0c52700477a7cc1737928cff
7
+ data.tar.gz: 192b353c5bbd6a2dffdd29d460e9580e8dc4f6d150335ef163d22d4b4a2d3a2e8295318b400c46d4e6b44d61e0696c4ff569ff9cf857d4194f0433b0818aa228
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022 Joshua Klina
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Tables
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "tables"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install tables
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ require "hyper_kitten_tables/version"
2
+ require "hyper_kitten_tables/concerns/table"
3
+ require "hyper_kitten_tables/components/table"
4
+
5
+ module Tables
6
+ end
@@ -0,0 +1,7 @@
1
+ module HyperKittenTables
2
+ module Components
3
+ class Table
4
+ include HyperKittenTables::Concerns::Table
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,134 @@
1
+ require "active_support/concern"
2
+ require "forwardable"
3
+
4
+ module HyperKittenTables
5
+ module Concerns
6
+ module Table
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ extend Forwardable
11
+
12
+ def_delegators :@view_context, :content_tag, :capture, :request
13
+
14
+ Column = Struct.new(:name, :method_name, :sort_key, :block, :sortable, :options)
15
+ end
16
+
17
+ def initialize(collection: [], requested_columns: [], &block)
18
+ @collection = collection
19
+ @columns = []
20
+
21
+ @table_options = {}
22
+ @thead_options = {}
23
+ @tbody_options = {}
24
+ @tr_options = {}
25
+ @th_options = {}
26
+
27
+ @requested_columns = requested_columns
28
+ yield self if block_given?
29
+ end
30
+
31
+ def td(name, method_name: nil, sort_key: nil, sortable: true, **options, &block)
32
+ if method_name.nil?
33
+ method_name = name.to_s.parameterize.underscore
34
+ name = name.to_s.titleize unless block_given?
35
+ end
36
+ sort_key = method_name if sort_key.blank?
37
+ @columns << Column.new(name, method_name, sort_key, block, sortable, options)
38
+ end
39
+
40
+ def define_header_sort_url(&block)
41
+ define_singleton_method(:header_sort_url, &block)
42
+ end
43
+
44
+ def header_sort_url(column, query_params)
45
+ # Override this method to define the sort url for the header.
46
+
47
+ raise NotImplementedError, "You must define #header_sort_url if you want sortable table columns."
48
+ end
49
+
50
+ def footer(&block)
51
+ @footer = block
52
+ end
53
+
54
+ def table(**options)
55
+ @table_options = options
56
+ end
57
+
58
+ def tbody(**options)
59
+ @tbody_options = options
60
+ end
61
+
62
+ def thead(**options)
63
+ @thead_options = options
64
+ end
65
+
66
+ def tr(**options)
67
+ @tr_options = options
68
+ end
69
+
70
+ def th(**options)
71
+ @th_options = options
72
+ end
73
+
74
+ def render_in(view_context)
75
+ @view_context = view_context
76
+
77
+ render_table
78
+ end
79
+
80
+ private
81
+
82
+ def visible_columns
83
+ return @columns if @requested_columns.empty?
84
+
85
+ @columns.select { |column| @requested_columns.include?(column.name) }
86
+ end
87
+
88
+ def render_table
89
+ content_tag(:table, @table_options) { render_header + render_body } + render_footer
90
+ end
91
+
92
+ def render_header
93
+ content_tag(:thead, @thead_options) do
94
+ content_tag(:tr, @tr_options) do
95
+ visible_columns.map do |column|
96
+ if column.sortable
97
+ content_tag(:th, @th_options) do
98
+ header_sort_url(column, query_params).html_safe
99
+ end
100
+ else
101
+ content_tag(:th, column.name, @th_options)
102
+ end
103
+ end.join.html_safe
104
+ end
105
+ end
106
+ end
107
+
108
+ def render_body
109
+ content_tag(:tbody, @tbody_options) do
110
+ @collection.map do |record|
111
+ content_tag(:tr, @tr_options) do
112
+ visible_columns.map do |column|
113
+ column_content = if column.block
114
+ capture(record, &column.block)
115
+ else
116
+ record.public_send(column.method_name)
117
+ end
118
+ content_tag(:td, column_content, column.options)
119
+ end.join.html_safe
120
+ end
121
+ end.join.html_safe
122
+ end
123
+ end
124
+
125
+ def render_footer
126
+ capture(&@footer) if @footer
127
+ end
128
+
129
+ def query_params
130
+ request.query_parameters
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,5 @@
1
+ module HyperKittenMeow
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace HyperKittenTables
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module HyperKittenTables
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :tables do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,209 @@
1
+ require "rails_helper"
2
+
3
+ RSpec.describe HyperKittenTables::Components::Table do
4
+ User = Struct.new(:name)
5
+
6
+ describe "rendering a table" do
7
+ it "with defaults" do
8
+ component = described_class.new(collection: []) do |table|
9
+ table.td(:name, sortable: false)
10
+ end
11
+
12
+ render component
13
+
14
+ assert_select "table" do
15
+ assert_select "thead" do
16
+ assert_select "tr" do
17
+ assert_select "th", text: "Name"
18
+ end
19
+ end
20
+ assert_select "tbody" do
21
+ assert_select "tr", count: 0
22
+ end
23
+ end
24
+ end
25
+
26
+ it "with custom column options" do
27
+ user = User.new("Hyper Kitten")
28
+ component = described_class.new(collection: [user]) do |table|
29
+ table.td(:name, sortable: false, class: "custom-class")
30
+ end
31
+
32
+ render component
33
+
34
+ assert_select "table" do
35
+ assert_select "tbody" do
36
+ assert_select "tr" do
37
+ assert_select "td.custom-class", text: "Hyper Kitten"
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ it "with custom table options" do
44
+ component = described_class.new(collection: []) do |table|
45
+ table.td(:name, sortable: false)
46
+ table.table(class: "custom-class")
47
+ end
48
+
49
+ render component
50
+
51
+ assert_select "table.custom-class"
52
+ end
53
+
54
+ it "with custom tbody options" do
55
+ component = described_class.new(collection: []) do |table|
56
+ table.tbody(class: "custom-class")
57
+ table.td(:name, sortable: false)
58
+ end
59
+
60
+ render component
61
+
62
+ assert_select "table" do
63
+ assert_select "tbody.custom-class"
64
+ end
65
+ end
66
+
67
+ it "with custom thead options" do
68
+ component = described_class.new(collection: []) do |table|
69
+ table.thead(class: "custom-class")
70
+ table.td(:name, sortable: false)
71
+ end
72
+
73
+ render component
74
+
75
+ assert_select "table" do
76
+ assert_select "thead.custom-class"
77
+ end
78
+ end
79
+
80
+ it "with custom tr options" do
81
+ component = described_class.new(collection: []) do |table|
82
+ table.tr(class: "custom-class")
83
+ table.td(:name, sortable: false)
84
+ end
85
+
86
+ render component
87
+
88
+ assert_select "table" do
89
+ assert_select "thead" do
90
+ assert_select "tr.custom-class"
91
+ end
92
+ end
93
+ end
94
+
95
+ it "with custom th options" do
96
+ component = described_class.new(collection: []) do |table|
97
+ table.th(class: "custom-class")
98
+ table.td(:name, sortable: false)
99
+ end
100
+
101
+ render component
102
+
103
+ assert_select "table" do
104
+ assert_select "thead" do
105
+ assert_select "tr" do
106
+ assert_select "th.custom-class"
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ it "rendered only the specified columns when requested" do
113
+ component = described_class.new(collection: [], requested_columns: ["Name"]) do |table|
114
+ table.td(:name, sortable: false)
115
+ table.td(:email, sortable: false)
116
+ end
117
+
118
+ html = render component
119
+
120
+ assert_select "table" do
121
+ assert_select "thead" do
122
+ assert_select "tr" do
123
+ assert_select "th", text: "Name"
124
+ assert_select "th", text: "Email", count: 0
125
+ end
126
+ end
127
+ assert_select "tbody" do
128
+ assert_select "tr", count: 0
129
+ end
130
+ end
131
+ end
132
+
133
+ it "with sortable columns" do
134
+ component = described_class.new(collection: []) do |table|
135
+ table.define_header_sort_url do |column, params|
136
+ link_direction = case params
137
+ when { column.sort_key => "asc" }
138
+ "desc"
139
+ when { column.sort_key => "" }
140
+ "desc"
141
+ else
142
+ "asc"
143
+ end
144
+ "<a href='/?order[#{column.sort_key}]=#{link_direction}'>#{column.name}</a>"
145
+ end
146
+ table.td(:name, sortable: true)
147
+ table.td(:age, sortable: true)
148
+ end
149
+
150
+ render component, params: { "name" => "asc" }
151
+
152
+ assert_select "table" do
153
+ assert_select "thead" do
154
+ assert_select "tr" do
155
+ assert_select "th" do
156
+ assert_select "a", text: "Name" do
157
+ assert_select "[href=?]", "/?order[name]=desc"
158
+ end
159
+ assert_select "a", text: "Age" do
160
+ assert_select "[href=?]", "/?order[age]=asc"
161
+ end
162
+ end
163
+ end
164
+ end
165
+ assert_select "tbody" do
166
+ assert_select "tr", count: 0
167
+ end
168
+ end
169
+ end
170
+
171
+ it "with a footer " do
172
+ component = described_class.new(collection: []) do |table|
173
+ table.td(:name, sortable: false)
174
+ table.footer do
175
+ "Footer"
176
+ end
177
+ end
178
+
179
+ html = render component
180
+
181
+ assert_select "body", text: /Footer/
182
+ assert_select "table", text: /Footer/, count: 0
183
+ end
184
+
185
+ def render(component, params: {})
186
+ request = Struct.new(:query_parameters).new(params)
187
+
188
+ view = Class.new(ActionView::Base.with_empty_template_cache) do
189
+ attr_accessor :request
190
+ def view_cache_dependencies; []; end
191
+ # def params; parameters; end
192
+
193
+ def combined_fragment_cache_key(key)
194
+ [ :views, key ]
195
+ end
196
+ end.with_view_paths([])
197
+
198
+ view.request = request
199
+
200
+ html = view.render component
201
+
202
+ @html_document = Nokogiri::HTML::Document.parse(html)
203
+ end
204
+
205
+ def document_root_element
206
+ @html_document.root
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative "config/application"
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../stylesheets .css
3
+ //= link_tree ../javascripts/hyper_kitten_meow .js
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,3 @@
1
+ class PagesController < ApplicationController
2
+ include ::HyperKittenMeow::Concerns::Controllers::PagesController
3
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,7 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ # Automatically retry jobs that encountered a deadlock
3
+ # retry_on ActiveRecord::Deadlocked
4
+
5
+ # Most jobs are safe to ignore if the underlying records are no longer available
6
+ # discard_on ActiveJob::DeserializationError
7
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: "from@example.com"
3
+ layout "mailer"
4
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ primary_abstract_class
3
+ end
@@ -0,0 +1,4 @@
1
+ %h2 This is a hardcoded page
2
+
3
+ %p Used for testing that the pages controller falls back to reading templates from the pages directory.
4
+
@@ -0,0 +1,4 @@
1
+ %h2 This is an app hardcoded page
2
+
3
+ %p Used for testing that the pages controller falls back to reading templates from the pages directory.
4
+
@@ -0,0 +1,3 @@
1
+ .container
2
+ %h2= @page.title
3
+ != @page.body
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path("../config/application", __dir__)
3
+ require_relative "../config/boot"
4
+ require "rails/commands"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative "../config/boot"
3
+ require "rake"
4
+ Rake.application.run
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require "fileutils"
3
+
4
+ # path to your application root.
5
+ APP_ROOT = File.expand_path("..", __dir__)
6
+
7
+ def system!(*args)
8
+ system(*args) || abort("\n== Command #{args} failed ==")
9
+ end
10
+
11
+ FileUtils.chdir APP_ROOT do
12
+ # This script is a way to set up or update your development environment automatically.
13
+ # This script is idempotent, so that you can run it at any time and get an expectable outcome.
14
+ # Add necessary setup steps to this file.
15
+
16
+ puts "== Installing dependencies =="
17
+ system! "gem install bundler --conservative"
18
+ system("bundle check") || system!("bundle install")
19
+
20
+ # puts "\n== Copying sample files =="
21
+ # unless File.exist?("config/database.yml")
22
+ # FileUtils.cp "config/database.yml.sample", "config/database.yml"
23
+ # end
24
+
25
+ puts "\n== Preparing database =="
26
+ system! "bin/rails db:prepare"
27
+
28
+ puts "\n== Removing old logs and tempfiles =="
29
+ system! "bin/rails log:clear tmp:clear"
30
+
31
+ puts "\n== Restarting application server =="
32
+ system! "bin/rails restart"
33
+ end
@@ -0,0 +1,26 @@
1
+ require_relative "boot"
2
+
3
+ require "action_controller/railtie"
4
+ require "action_view/railtie"
5
+
6
+ # Require the gems listed in Gemfile, including any gems
7
+ # you've limited to :test, :development, or :production.
8
+ Bundler.require(*Rails.groups)
9
+
10
+ module Dummy
11
+ class Application < Rails::Application
12
+ config.load_defaults Rails::VERSION::STRING.to_f
13
+
14
+ # For compatibility with applications that use this config
15
+ config.action_controller.include_all_helpers = false
16
+
17
+ # Configuration for the application, engines, and railties goes here.
18
+ #
19
+ # These settings can be overridden in specific environments using the files
20
+ # in config/environments, which are processed later.
21
+ #
22
+ # config.time_zone = "Central Time (US & Canada)"
23
+ # config.eager_load_paths << Rails.root.join("extras")
24
+ config.autoload_paths << Rails.root.join("lib")
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", __dir__)
3
+
4
+ require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
5
+ $LOAD_PATH.unshift File.expand_path("../../../lib", __dir__)
@@ -0,0 +1,10 @@
1
+ development:
2
+ adapter: async
3
+
4
+ test:
5
+ adapter: test
6
+
7
+ production:
8
+ adapter: redis
9
+ url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10
+ channel_prefix: dummy_production
@@ -0,0 +1,16 @@
1
+ default: &default
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ host: <%= ENV['APP_DB_HOST'] || 'localhost' %>
5
+ database: <%= ENV['APP_DB_NAME'] %>
6
+ username: <%= ENV['APP_DB_USERNAME'] || 'root' %>
7
+ password: <%= ENV['APP_DB_PASSWORD'] || '' %>
8
+ port: 5432
9
+
10
+ development:
11
+ <<: *default
12
+ database: hyper_kitten_meow_development
13
+ test:
14
+ <<: *default
15
+ database: hyper_kitten_meow_test
16
+
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require_relative "application"
3
+
4
+ # Initialize the Rails application.
5
+ Rails.application.initialize!