power_grid 0.1.1 → 0.2.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.
- checksums.yaml +4 -4
- data/app/components/power_grid/table_component.html.erb +62 -32
- data/lib/power_grid/base.rb +23 -3
- data/lib/power_grid/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41ecea06e53d056880150b46b4df3bce98af40631d2e4c8092b0389c97662cad
|
|
4
|
+
data.tar.gz: 816ce274026b3cf42f4e5d200ff16f874920db45cf8130dba2b0ac0aa31d4249
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ec2f602a81ae2e5d2ecb77cb476a75421dc4d20607870193b019c6bd14cef66f65d4adbae76dd3235b6b1f248544cfffcd045520d841ef7db707cf7f2ecaf70d
|
|
7
|
+
data.tar.gz: acbe88c38a671072bbd2b88f85cb812251872a2d4b05fd11af746ec292447b9a1877e3c3022e2c921fc715421bd4ea1a110be00a12913db1195091735799a83d
|
|
@@ -1,40 +1,68 @@
|
|
|
1
1
|
<div class="power-grid-container w-full bg-white dark:bg-slate-900 rounded-lg shadow ring-1 ring-slate-900/5" data-controller="power-grid-table">
|
|
2
2
|
|
|
3
|
-
<!-- Top Controls: Per Page & Search -->
|
|
4
|
-
<div class="flex flex-col
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
<!-- Top Controls: Per Page & Search & Filters -->
|
|
4
|
+
<div class="flex flex-col space-y-4 p-4 border-b border-slate-200 dark:border-slate-700">
|
|
5
|
+
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center space-y-3 sm:space-y-0 text-sm">
|
|
6
|
+
|
|
7
|
+
<!-- Left: Per Page & Filters -->
|
|
8
|
+
<div class="flex flex-wrap items-center gap-4 w-full sm:w-auto">
|
|
9
|
+
<%= form_with url: request.path, method: :get, data: { turbo_frame: "power_grid_table", turbo_action: "advance", power_grid_table_target: "form" }, class: "flex flex-wrap items-center gap-4 w-full", id: "power_grid_form_#{request.path.parameterize}" do |f| %>
|
|
10
|
+
<% params.except(:per_page, :page, :q, *(@grid.class.defined_filters.keys)).each do |key, value| %>
|
|
11
|
+
<%= hidden_field_tag key, value %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<!-- Reset page to 1 on update -->
|
|
14
|
+
<%= hidden_field_tag :page, 1 %>
|
|
15
|
+
|
|
16
|
+
<!-- Per Page -->
|
|
17
|
+
<div class="flex items-center">
|
|
18
|
+
<span class="mr-2 text-slate-700 dark:text-slate-300">Show</span>
|
|
19
|
+
<%= select_tag :per_page, options_for_select([10, 25, 50, 100], @grid.per_page),
|
|
20
|
+
class: "block w-20 rounded-md border-slate-300 py-1.5 text-base focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm dark:bg-slate-800 dark:border-slate-600 dark:text-white",
|
|
21
|
+
data: { action: "change->power-grid-table#search" }
|
|
22
|
+
%>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<!-- Dynamic Filters -->
|
|
26
|
+
<% @grid.class.defined_filters.each do |name, options| %>
|
|
27
|
+
<div class="flex items-center">
|
|
28
|
+
<% if options[:collection] %>
|
|
29
|
+
<%= select_tag name, options_for_select(options[:collection], params[name]),
|
|
30
|
+
include_blank: options[:label] || name.to_s.humanize,
|
|
31
|
+
class: "block w-40 rounded-md border-slate-300 py-1.5 text-base focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm dark:bg-slate-800 dark:border-slate-600 dark:text-white",
|
|
32
|
+
data: { action: "change->power-grid-table#search" }
|
|
33
|
+
%>
|
|
34
|
+
<% else %>
|
|
35
|
+
<%= text_field_tag name, params[name],
|
|
36
|
+
placeholder: options[:label] || name.to_s.humanize,
|
|
37
|
+
class: "block w-40 rounded-md border-slate-300 py-1.5 text-base focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm dark:bg-slate-800 dark:border-slate-600 dark:text-white",
|
|
38
|
+
data: { action: "change->power-grid-table#search" } # Debounce handled by controller if implemented for change, otherwise change triggers immediately
|
|
39
|
+
%>
|
|
40
|
+
<% end %>
|
|
41
|
+
</div>
|
|
42
|
+
<% end %>
|
|
43
|
+
|
|
11
44
|
<% end %>
|
|
12
|
-
|
|
13
|
-
<%= hidden_field_tag :page, 1 %>
|
|
14
|
-
|
|
15
|
-
<%= select_tag :per_page, options_for_select([10, 25, 50, 100], @grid.per_page),
|
|
16
|
-
class: "mx-1 mt-1 block w-20 rounded-md border-slate-300 py-1.5 text-base focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm dark:bg-slate-800 dark:border-slate-600 dark:text-white",
|
|
17
|
-
data: { action: "change->power-grid-table#search" }
|
|
18
|
-
%>
|
|
19
|
-
<% end %>
|
|
20
|
-
<span class="ml-2">entries</span>
|
|
21
|
-
</div>
|
|
45
|
+
</div>
|
|
22
46
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
47
|
+
<!-- Right: Search -->
|
|
48
|
+
<% if @grid.searchable? %>
|
|
49
|
+
<div class="w-full sm:w-auto">
|
|
50
|
+
<label for="search" class="sr-only">Search</label>
|
|
51
|
+
<div class="relative rounded-md shadow-sm">
|
|
52
|
+
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
|
53
|
+
<svg class="h-5 w-5 text-slate-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
54
|
+
<path fill-rule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clip-rule="evenodd" />
|
|
55
|
+
</svg>
|
|
56
|
+
</div>
|
|
57
|
+
<%= text_field_tag :q, params[:q], placeholder: "Search...",
|
|
58
|
+
class: "block w-full rounded-md border-0 py-1.5 pl-10 text-slate-900 ring-1 ring-inset ring-slate-300 placeholder:text-slate-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 dark:bg-slate-800 dark:text-white dark:ring-slate-600 dark:placeholder-slate-500",
|
|
59
|
+
data: { action: "input->power-grid-table#search" },
|
|
60
|
+
form: "power_grid_form_#{request.path.parameterize}"
|
|
61
|
+
%>
|
|
62
|
+
</div>
|
|
31
63
|
</div>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
data: { action: "input->power-grid-table#search" },
|
|
35
|
-
form: "power_grid_form_#{request.path.parameterize}"
|
|
36
|
-
%>
|
|
37
|
-
</div>
|
|
64
|
+
<% end %>
|
|
65
|
+
|
|
38
66
|
</div>
|
|
39
67
|
</div>
|
|
40
68
|
|
|
@@ -101,6 +129,7 @@
|
|
|
101
129
|
</div>
|
|
102
130
|
<div>
|
|
103
131
|
<!-- Numbered Pagination Controls -->
|
|
132
|
+
<% if @grid.total_pages > 1 %>
|
|
104
133
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
|
105
134
|
<% if @grid.current_page > 1 %>
|
|
106
135
|
<%= link_to "Previous", request.params.merge(page: @grid.current_page - 1), class: "relative inline-flex items-center rounded-l-md px-2 py-2 text-slate-400 ring-1 ring-inset ring-slate-300 hover:bg-slate-50 focus:z-20 focus:outline-offset-0 dark:ring-slate-600 dark:hover:bg-slate-800", data: { turbo_action: "advance" } %>
|
|
@@ -120,6 +149,7 @@
|
|
|
120
149
|
<%= link_to "Next", request.params.merge(page: @grid.current_page + 1), class: "relative inline-flex items-center rounded-r-md px-2 py-2 text-slate-400 ring-1 ring-inset ring-slate-300 hover:bg-slate-50 focus:z-20 focus:outline-offset-0 dark:ring-slate-600 dark:hover:bg-slate-800", data: { turbo_action: "advance" } %>
|
|
121
150
|
<% end %>
|
|
122
151
|
</nav>
|
|
152
|
+
<% end %>
|
|
123
153
|
</div>
|
|
124
154
|
</div>
|
|
125
155
|
</div>
|
data/lib/power_grid/base.rb
CHANGED
|
@@ -30,8 +30,8 @@ module PowerGrid
|
|
|
30
30
|
|
|
31
31
|
attr_reader :params, :initial_scope
|
|
32
32
|
|
|
33
|
-
def initialize(params = {}, initial_scope: nil)
|
|
34
|
-
@params = params
|
|
33
|
+
def initialize(params = {}, initial_scope: nil, **options)
|
|
34
|
+
@params = params.merge(options)
|
|
35
35
|
@initial_scope = initial_scope
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -39,7 +39,7 @@ module PowerGrid
|
|
|
39
39
|
@records ||= begin
|
|
40
40
|
scope = @initial_scope || instance_eval(&self.class.defined_scope)
|
|
41
41
|
scope = apply_includes(scope)
|
|
42
|
-
scope =
|
|
42
|
+
scope = apply_filters(scope)
|
|
43
43
|
scope = apply_search(scope)
|
|
44
44
|
scope = apply_sort(scope)
|
|
45
45
|
|
|
@@ -57,6 +57,10 @@ module PowerGrid
|
|
|
57
57
|
@total_count
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
def searchable?
|
|
61
|
+
self.class.defined_columns.any? { |_, opts| opts[:searchable] }
|
|
62
|
+
end
|
|
63
|
+
|
|
60
64
|
def current_page
|
|
61
65
|
(params[:page] || 1).to_i
|
|
62
66
|
end
|
|
@@ -150,5 +154,21 @@ module PowerGrid
|
|
|
150
154
|
scope.order(sort_expr => direction)
|
|
151
155
|
end
|
|
152
156
|
|
|
157
|
+
def apply_filters(scope)
|
|
158
|
+
self.class.defined_filters.each do |name, options|
|
|
159
|
+
value = params[name]
|
|
160
|
+
next if value.blank?
|
|
161
|
+
|
|
162
|
+
# Basic equality filter for now.
|
|
163
|
+
# TODO: Support blocks/procs for custom filtering
|
|
164
|
+
|
|
165
|
+
# If sql_expression option exists, use that
|
|
166
|
+
col_name = options[:sql_expression] || name
|
|
167
|
+
|
|
168
|
+
scope = scope.where(col_name => value)
|
|
169
|
+
end
|
|
170
|
+
scope
|
|
171
|
+
end
|
|
172
|
+
|
|
153
173
|
end
|
|
154
174
|
end
|
data/lib/power_grid/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: power_grid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bhavin Nandani
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-12-
|
|
11
|
+
date: 2025-12-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|