plutonium 0.15.3 → 0.15.5
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/assets/plutonium.css +1 -1
- data/app/views/components/sidebar_menu/sidebar_menu_component.rb +1 -1
- data/app/views/components/table_search_input/table_search_input_component.html.erb +3 -3
- data/app/views/resource/_resource_table.html.erb +0 -321
- data/lib/plutonium/core/controllers/authorizable.rb +5 -0
- data/lib/plutonium/core/controllers/entity_scoping.rb +4 -4
- data/lib/plutonium/definition/base.rb +8 -0
- data/lib/plutonium/definition/defineable_props.rb +1 -1
- data/lib/plutonium/definition/presentable.rb +71 -0
- data/lib/plutonium/interaction/README.md +1 -1
- data/lib/plutonium/interaction/base.rb +6 -6
- data/lib/plutonium/lib/deep_freezer.rb +31 -0
- data/lib/plutonium/query/adhoc_block.rb +19 -0
- data/lib/plutonium/query/base.rb +29 -0
- data/lib/plutonium/query/filter.rb +12 -0
- data/lib/plutonium/query/filters/text.rb +77 -0
- data/lib/plutonium/query/model_scope.rb +19 -0
- data/lib/plutonium/resource/controller.rb +14 -7
- data/lib/plutonium/resource/controllers/authorizable.rb +1 -1
- data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +26 -0
- data/lib/plutonium/resource/controllers/crud_actions.rb +2 -5
- data/lib/plutonium/resource/controllers/defineable.rb +0 -2
- data/lib/plutonium/resource/controllers/queryable.rb +36 -20
- data/lib/plutonium/resource/policy.rb +1 -1
- data/lib/plutonium/resource/query_object.rb +61 -147
- data/lib/plutonium/{refinements/parameter_refinements.rb → support/parameters.rb} +5 -7
- data/lib/plutonium/ui/component/methods.rb +1 -1
- data/lib/plutonium/ui/display/resource.rb +19 -15
- data/lib/plutonium/ui/form/query.rb +171 -0
- data/lib/plutonium/ui/form/resource.rb +21 -17
- data/lib/plutonium/ui/table/components/scopes_bar.rb +1 -1
- data/lib/plutonium/ui/table/components/search_bar.rb +6 -139
- data/lib/plutonium/ui/table/resource.rb +10 -9
- data/lib/plutonium/version.rb +1 -1
- data/package-lock.json +2 -2
- data/package.json +1 -1
- metadata +12 -4
- data/lib/plutonium/interaction/concerns/presentable.rb +0 -73
@@ -1,322 +1 @@
|
|
1
1
|
<%= render build_collection %>
|
2
|
-
|
3
|
-
<%#
|
4
|
-
|
5
|
-
<div class="space-y-2 mb-4 mt-6">
|
6
|
-
<!-- Search Bar -->
|
7
|
-
<div class="p-4 bg-white border border-gray-200 rounded-lg dark:bg-gray-800 dark:border-gray-700 space-y-2">
|
8
|
-
<div class="relative">
|
9
|
-
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
10
|
-
<svg class="w-5 h-5 text-gray-500 dark:text-gray-400" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
11
|
-
<path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"></path>
|
12
|
-
</svg>
|
13
|
-
</div>
|
14
|
-
<input type="text" id="table-search" class="block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Search for items" oninput="searchTable()">
|
15
|
-
</div>
|
16
|
-
<div class="flex flex-wrap items-center gap-4">
|
17
|
-
<span class="text-sm font-medium text-gray-900 dark:text-white">Filters:</span>
|
18
|
-
|
19
|
-
<select id="category-filter" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
20
|
-
<option selected value="">All Categories</option>
|
21
|
-
<option value="technology">Technology</option>
|
22
|
-
<option value="science">Science</option>
|
23
|
-
<option value="health">Health</option>
|
24
|
-
</select>
|
25
|
-
|
26
|
-
<div class="flex items-center space-x-2">
|
27
|
-
<input type="date" id="start-date" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
28
|
-
<span class="text-gray-500 dark:text-gray-400">to</span>
|
29
|
-
<input type="date" id="end-date" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
30
|
-
</div>
|
31
|
-
|
32
|
-
<select id="author-filter" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
33
|
-
<option selected value="">All Authors</option>
|
34
|
-
<option value="john-doe">John Doe</option>
|
35
|
-
<option value="jane-smith">Jane Smith</option>
|
36
|
-
</select>
|
37
|
-
|
38
|
-
<button onclick="applyFilters()" class="inline-flex items-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">
|
39
|
-
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
40
|
-
<path fill-rule="evenodd" d="M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z" clip-rule="evenodd"></path>
|
41
|
-
</svg>
|
42
|
-
Apply Filters
|
43
|
-
</button>
|
44
|
-
|
45
|
-
<button onclick="clearFilters()" class="inline-flex items-center text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg text-sm px-4 py-2 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700">
|
46
|
-
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
47
|
-
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
|
48
|
-
</svg>
|
49
|
-
Clear Filters
|
50
|
-
</button>
|
51
|
-
</div>
|
52
|
-
</div>
|
53
|
-
|
54
|
-
<!-- Scopes and Bulk Actions -->
|
55
|
-
<div class="flex flex-wrap justify-between items-center gap-4 p-4 bg-white border border-gray-200 rounded-lg dark:bg-gray-800 dark:border-gray-700">
|
56
|
-
<!-- Scopes -->
|
57
|
-
<div class="flex flex-wrap items-center gap-2">
|
58
|
-
<button id="all-scope" onclick="filterTable('all')" class="px-4 py-2 text-sm font-medium text-gray-900 bg-gray-100 border border-gray-200 rounded-lg hover:bg-gray-200 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-600">
|
59
|
-
All
|
60
|
-
</button>
|
61
|
-
<button id="featured-scope" onclick="filterTable('featured')" class="px-4 py-2 text-sm font-medium text-gray-900 bg-gray-100 border border-gray-200 rounded-lg hover:bg-gray-200 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-600">
|
62
|
-
Featured
|
63
|
-
</button>
|
64
|
-
<button id="draft-scope" onclick="filterTable('draft')" class="px-4 py-2 text-sm font-medium text-gray-900 bg-gray-100 border border-gray-200 rounded-lg hover:bg-gray-200 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-600">
|
65
|
-
Draft <span class="ml-1 text-gray-500 dark:text-gray-400">(1)</span>
|
66
|
-
</button>
|
67
|
-
<button id="published-scope" onclick="filterTable('published')" class="px-4 py-2 text-sm font-medium text-gray-900 bg-gray-100 border border-gray-200 rounded-lg hover:bg-gray-200 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-600">
|
68
|
-
Published <span class="ml-1 text-gray-500 dark:text-gray-400">(2)</span>
|
69
|
-
</button>
|
70
|
-
</div>
|
71
|
-
|
72
|
-
<!-- Bulk Actions -->
|
73
|
-
<div class="flex flex-wrap items-center gap-2">
|
74
|
-
<button onclick="bulkAction('delete')" class="inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-red-700 rounded-lg hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-800">
|
75
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
76
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
|
77
|
-
</svg>
|
78
|
-
Delete Selected
|
79
|
-
</button>
|
80
|
-
<button onclick="bulkAction('archive')" class="inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-yellow-700 rounded-lg hover:bg-yellow-800 focus:ring-4 focus:outline-none focus:ring-yellow-300 dark:bg-yellow-600 dark:hover:bg-yellow-700 dark:focus:ring-yellow-800">
|
81
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
82
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"></path>
|
83
|
-
</svg>
|
84
|
-
Archive Selected
|
85
|
-
</button>
|
86
|
-
<button id="dropdownActionButton" data-dropdown-toggle="dropdownAction" class="inline-flex items-center text-gray-500 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg text-sm px-3 py-2 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700" type="button">
|
87
|
-
<span class="sr-only">Action button</span>
|
88
|
-
More Actions
|
89
|
-
<svg class="w-2.5 h-2.5 ml-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
90
|
-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
91
|
-
</svg>
|
92
|
-
</button>
|
93
|
-
</div>
|
94
|
-
</div>
|
95
|
-
</div>
|
96
|
-
|
97
|
-
<!-- Table -->
|
98
|
-
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
|
99
|
-
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
100
|
-
<caption class="p-5 text-lg font-semibold text-left rtl:text-right text-gray-900 bg-white dark:text-white dark:bg-gray-800">
|
101
|
-
<div class="flex justify-between items-center">
|
102
|
-
<div>
|
103
|
-
Manage your blog posts
|
104
|
-
<p class="mt-1 text-sm font-normal text-gray-500 dark:text-gray-400">Manage your blog posts.</p>
|
105
|
-
</div>
|
106
|
-
<div class="flex space-x-2">
|
107
|
-
<button type="button" class="px-4 py-2 text-sm font-medium text-blue-700 hover:text-blue-800 focus:z-10 focus:outline-none focus:ring-2 focus:ring-blue-700 dark:text-blue-400 dark:hover:text-blue-500">
|
108
|
-
<span class="flex items-center">
|
109
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
110
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
111
|
-
</svg>
|
112
|
-
Select All
|
113
|
-
</span>
|
114
|
-
</button>
|
115
|
-
<button type="button" class="px-4 py-2 text-sm font-medium text-red-700 hover:text-red-800 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-700 dark:text-red-400 dark:hover:text-red-500">
|
116
|
-
<span class="flex items-center">
|
117
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
118
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
119
|
-
</svg>
|
120
|
-
Deselect All
|
121
|
-
</span>
|
122
|
-
</button>
|
123
|
-
</div>
|
124
|
-
</div>
|
125
|
-
</caption>
|
126
|
-
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
127
|
-
<tr>
|
128
|
-
<th scope="col" class="px-6 py-3">
|
129
|
-
<input type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
130
|
-
</th>
|
131
|
-
<th scope="col" class="px-6 py-3">Title</th>
|
132
|
-
<th scope="col" class="px-6 py-3">Slug</th>
|
133
|
-
<th scope="col" class="px-6 py-3">Is featured</th>
|
134
|
-
<th scope="col" class="px-6 py-3">Actions</th>
|
135
|
-
</tr>
|
136
|
-
</thead>
|
137
|
-
<tbody>
|
138
|
-
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
139
|
-
<td class="px-6 py-4">
|
140
|
-
<input type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
141
|
-
</td>
|
142
|
-
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">What is Plutonium?</th>
|
143
|
-
<td class="px-6 py-4">what-is-plutonium</td>
|
144
|
-
<td class="px-6 py-4"><span class="text-green-600 dark:text-green-400">✓</span></td>
|
145
|
-
<td class="px-6 py-4">
|
146
|
-
<div class="flex items-center space-x-2">
|
147
|
-
<button type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800 flex items-center">
|
148
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path></svg>
|
149
|
-
View
|
150
|
-
</button>
|
151
|
-
<button type="button" class="py-2 px-3 flex items-center text-sm font-medium text-center text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
|
152
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"></path></svg>
|
153
|
-
Edit
|
154
|
-
</button>
|
155
|
-
<button type="button" class="py-2 px-3 flex items-center text-sm font-medium text-center text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
|
156
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
|
157
|
-
Delete
|
158
|
-
</button>
|
159
|
-
<button id="dropdownDefaultButton" data-dropdown-toggle="dropdown" class="text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700" type="button">
|
160
|
-
More
|
161
|
-
<svg class="w-2.5 h-2.5 ml-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
162
|
-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
163
|
-
</svg>
|
164
|
-
</button>
|
165
|
-
<div id="dropdown" class="z-10 hidden absolute bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
|
166
|
-
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownDefaultButton">
|
167
|
-
<li>
|
168
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Duplicate</a>
|
169
|
-
</li>
|
170
|
-
<li>
|
171
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Archive</a>
|
172
|
-
</li>
|
173
|
-
<li>
|
174
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Download</a>
|
175
|
-
</li>
|
176
|
-
</ul>
|
177
|
-
</div>
|
178
|
-
</div>
|
179
|
-
</td>
|
180
|
-
</tr>
|
181
|
-
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
182
|
-
<td class="px-6 py-4">
|
183
|
-
<input type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
184
|
-
</td>
|
185
|
-
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">Top 5 best features of Plutonium</th>
|
186
|
-
<td class="px-6 py-4">top-5-features</td>
|
187
|
-
<td class="px-6 py-4"><span class="text-green-600 dark:text-green-400">✓</span></td>
|
188
|
-
<td class="px-6 py-4">
|
189
|
-
<div class="flex items-center space-x-2">
|
190
|
-
<button type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800 flex items-center">
|
191
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path></svg>
|
192
|
-
View
|
193
|
-
</button>
|
194
|
-
<button type="button" class="py-2 px-3 flex items-center text-sm font-medium text-center text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
|
195
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"></path></svg>
|
196
|
-
Edit
|
197
|
-
</button>
|
198
|
-
<button type="button" class="py-2 px-3 flex items-center text-sm font-medium text-center text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
|
199
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
|
200
|
-
Delete
|
201
|
-
</button>
|
202
|
-
<button id="dropdownDefaultButton" data-dropdown-toggle="dropdown" class="text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700" type="button">
|
203
|
-
More
|
204
|
-
<svg class="w-2.5 h-2.5 ml-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
205
|
-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
206
|
-
</svg>
|
207
|
-
</button>
|
208
|
-
<div id="dropdown" class="z-10 hidden absolute bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
|
209
|
-
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownDefaultButton">
|
210
|
-
<li>
|
211
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Duplicate</a>
|
212
|
-
</li>
|
213
|
-
<li>
|
214
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Archive</a>
|
215
|
-
</li>
|
216
|
-
<li>
|
217
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Download</a>
|
218
|
-
</li>
|
219
|
-
</ul>
|
220
|
-
</div>
|
221
|
-
</div>
|
222
|
-
</td>
|
223
|
-
</tr>
|
224
|
-
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
225
|
-
<td class="px-6 py-4">
|
226
|
-
<input type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
227
|
-
</td>
|
228
|
-
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">Customizing Plutonium's UI with a theme</th>
|
229
|
-
<td class="px-6 py-4">theme-guide</td>
|
230
|
-
<td class="px-6 py-4"><span class="text-green-600 dark:text-green-400">✓</span></td>
|
231
|
-
<td class="px-6 py-4">
|
232
|
-
<div class="flex items-center space-x-2">
|
233
|
-
<button type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800 flex items-center">
|
234
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path></svg>
|
235
|
-
View
|
236
|
-
</button>
|
237
|
-
<button type="button" class="py-2 px-3 flex items-center text-sm font-medium text-center text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
|
238
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"></path></svg>
|
239
|
-
Edit
|
240
|
-
</button>
|
241
|
-
<button type="button" class="py-2 px-3 flex items-center text-sm font-medium text-center text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
|
242
|
-
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path></svg>
|
243
|
-
Delete
|
244
|
-
</button>
|
245
|
-
<button id="dropdownDefaultButton" data-dropdown-toggle="dropdown" class="text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg text-sm px-3 py-2 text-center inline-flex items-center dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700" type="button">
|
246
|
-
More
|
247
|
-
<svg class="w-2.5 h-2.5 ml-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
248
|
-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
249
|
-
</svg>
|
250
|
-
</button>
|
251
|
-
<div id="dropdown" class="z-10 hidden absolute bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
|
252
|
-
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownDefaultButton">
|
253
|
-
<li>
|
254
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Duplicate</a>
|
255
|
-
</li>
|
256
|
-
<li>
|
257
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Archive</a>
|
258
|
-
</li>
|
259
|
-
<li>
|
260
|
-
<a href="#" class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Download</a>
|
261
|
-
</li>
|
262
|
-
</ul>
|
263
|
-
</div>
|
264
|
-
</div>
|
265
|
-
</td>
|
266
|
-
</tr>
|
267
|
-
</tbody>
|
268
|
-
</table>
|
269
|
-
</div>
|
270
|
-
|
271
|
-
<!-- display control -->
|
272
|
-
<div class="flex flex-col md:flex-row justify-between items-center mt-4 text-sm text-gray-500 dark:text-gray-400">
|
273
|
-
<div>
|
274
|
-
Showing 1 to 5 of 50 results
|
275
|
-
</div>
|
276
|
-
<div class="flex items-center space-x-2 mt-2 md:mt-0">
|
277
|
-
<label for="perPage" class="mr-2">Per page</label>
|
278
|
-
<select id="perPage" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
279
|
-
<option selected>5</option>
|
280
|
-
<option>10</option>
|
281
|
-
<option>25</option>
|
282
|
-
<option>50</option>
|
283
|
-
</select>
|
284
|
-
</div>
|
285
|
-
</div>
|
286
|
-
|
287
|
-
<!-- pagination -->
|
288
|
-
<div class="flex justify-center mt-4">
|
289
|
-
<nav aria-label="Page navigation example">
|
290
|
-
<ul class="inline-flex -space-x-px text-sm">
|
291
|
-
<li>
|
292
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">Previous</a>
|
293
|
-
</li>
|
294
|
-
<li>
|
295
|
-
<a href="#" aria-current="page" class="flex items-center justify-center px-3 h-8 text-blue-600 border border-gray-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white">1</a>
|
296
|
-
</li>
|
297
|
-
<li>
|
298
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">2</a>
|
299
|
-
</li>
|
300
|
-
<li>
|
301
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">3</a>
|
302
|
-
</li>
|
303
|
-
<li>
|
304
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">4</a>
|
305
|
-
</li>
|
306
|
-
<li>
|
307
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">...</a>
|
308
|
-
</li>
|
309
|
-
<li>
|
310
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">9</a>
|
311
|
-
</li>
|
312
|
-
<li>
|
313
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">10</a>
|
314
|
-
</li>
|
315
|
-
<li>
|
316
|
-
<a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">Next</a>
|
317
|
-
</li>
|
318
|
-
</ul>
|
319
|
-
</nav>
|
320
|
-
</div>
|
321
|
-
|
322
|
-
%>
|
@@ -28,6 +28,11 @@ module Plutonium
|
|
28
28
|
def entity_scope_for_authorize
|
29
29
|
scoped_to_entity? ? current_scoped_entity : nil
|
30
30
|
end
|
31
|
+
|
32
|
+
def verify_authorized
|
33
|
+
# we don't use action policy's inbuilt checks, so ensure they are neutered,
|
34
|
+
# also ensures pundit checks are disabled.
|
35
|
+
end
|
31
36
|
end
|
32
37
|
end
|
33
38
|
end
|
@@ -81,16 +81,16 @@ module Plutonium
|
|
81
81
|
# @return [ActiveRecord::Base, nil] the current scoped entity or nil if not found
|
82
82
|
# @raise [NotImplementedError] if the scoping strategy is unknown
|
83
83
|
def fetch_current_scoped_entity
|
84
|
-
|
84
|
+
case scoped_entity_strategy
|
85
85
|
when :path
|
86
|
-
fetch_entity_from_path
|
86
|
+
scoped_entity = fetch_entity_from_path
|
87
|
+
authorize! scoped_entity, to: :read?
|
88
|
+
scoped_entity
|
87
89
|
when Symbol
|
88
90
|
send(scoped_entity_strategy)
|
89
91
|
else
|
90
92
|
raise NotImplementedError, "Unknown scoped entity strategy: #{scoped_entity_strategy.inspect}"
|
91
93
|
end
|
92
|
-
authorize! scoped_entity, to: :read?
|
93
|
-
scoped_entity
|
94
94
|
end
|
95
95
|
|
96
96
|
# Fetches the scoped entity from the path parameters.
|
@@ -46,6 +46,10 @@ module Plutonium
|
|
46
46
|
|
47
47
|
class Display < Plutonium::UI::Display::Resource; end
|
48
48
|
|
49
|
+
class QueryForm < Plutonium::UI::Form::Query; end
|
50
|
+
|
51
|
+
class TextFilter < Plutonium::Query::Filters::Text; end
|
52
|
+
|
49
53
|
# fields
|
50
54
|
defineable_props :field, :input, :display, :column
|
51
55
|
|
@@ -94,6 +98,10 @@ module Plutonium
|
|
94
98
|
def detail_class
|
95
99
|
self.class::Display
|
96
100
|
end
|
101
|
+
|
102
|
+
def query_form
|
103
|
+
self.class::QueryForm
|
104
|
+
end
|
97
105
|
end
|
98
106
|
end
|
99
107
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Definition
|
3
|
+
# Provides presentation-related functionality for interactions.
|
4
|
+
#
|
5
|
+
# This module allows interactions to define metadata such as labels, icons,
|
6
|
+
# and descriptions, which can be used for UI generation or documentation.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class MyInteraction < Plutonium::Interaction::Base
|
10
|
+
# include Plutonium::Definition::Presentable
|
11
|
+
#
|
12
|
+
# presents label: "My Interaction",
|
13
|
+
# icon: "star",
|
14
|
+
# description: "Does something awesome"
|
15
|
+
#
|
16
|
+
# # ... rest of the interaction
|
17
|
+
# end
|
18
|
+
module Presentable
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
class_attribute :presentation_metadata, default: {}
|
23
|
+
end
|
24
|
+
|
25
|
+
class_methods do
|
26
|
+
# Defines presentation metadata for the interaction.
|
27
|
+
#
|
28
|
+
# @param options [Hash] The presentation options.
|
29
|
+
# @option options [String] :label The label for the interaction.
|
30
|
+
# @option options [String] :icon The icon for the interaction.
|
31
|
+
# @option options [String] :description The description of the interaction.
|
32
|
+
def presents(**options)
|
33
|
+
self.presentation_metadata = options
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the label for the interaction.
|
37
|
+
#
|
38
|
+
# @return [String] The label defined in the presentation metadata or a default generated from the class name.
|
39
|
+
def label
|
40
|
+
presentation_metadata[:label] || name.demodulize.titleize
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the icon for the interaction.
|
44
|
+
#
|
45
|
+
# @return [String, nil] The icon defined in the presentation metadata.
|
46
|
+
def icon
|
47
|
+
presentation_metadata[:icon]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the description for the interaction.
|
51
|
+
#
|
52
|
+
# @return [String, nil] The description defined in the presentation metadata.
|
53
|
+
def description
|
54
|
+
presentation_metadata[:description]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def label
|
59
|
+
self.class.label
|
60
|
+
end
|
61
|
+
|
62
|
+
def icon
|
63
|
+
self.class.icon
|
64
|
+
end
|
65
|
+
|
66
|
+
def description
|
67
|
+
self.class.description
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -252,7 +252,7 @@ The `Presentable` concern allows you to add metadata to your interactions, which
|
|
252
252
|
|
253
253
|
```ruby
|
254
254
|
class MyInteraction < Plutonium::Interaction::Base
|
255
|
-
include Plutonium::
|
255
|
+
include Plutonium::Definition::Presentable
|
256
256
|
|
257
257
|
presents label: "My Interaction",
|
258
258
|
icon: Phlex::TablerIcons::Activate,
|
@@ -22,10 +22,10 @@ module Plutonium
|
|
22
22
|
class Base
|
23
23
|
include ActiveModel::Model
|
24
24
|
include ActiveModel::Attributes
|
25
|
-
include Concerns::Presentable
|
26
25
|
include Plutonium::Definition::DefineableProps
|
27
26
|
include Plutonium::Definition::ConfigAttr
|
28
|
-
|
27
|
+
include Plutonium::Definition::Presentable
|
28
|
+
# include Plutonium::Interaction::Concerns::WorkflowDSL
|
29
29
|
|
30
30
|
class Form < Plutonium::UI::Form::Interaction; end
|
31
31
|
|
@@ -44,6 +44,10 @@ module Plutonium
|
|
44
44
|
self::Form.new(instance || new)
|
45
45
|
end
|
46
46
|
|
47
|
+
def build_form
|
48
|
+
self.class.build_form(self)
|
49
|
+
end
|
50
|
+
|
47
51
|
# Executes the interaction.
|
48
52
|
#
|
49
53
|
# @return [Plutonium::Interaction::Outcome] The result of the interaction.
|
@@ -60,10 +64,6 @@ module Plutonium
|
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
63
|
-
def build_form
|
64
|
-
self.class.build_form(self)
|
65
|
-
end
|
66
|
-
|
67
67
|
private
|
68
68
|
|
69
69
|
# Implement the main logic of the interaction.
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module Lib
|
5
|
+
class DeepFreezer
|
6
|
+
def self.freeze(object)
|
7
|
+
# Recursive calling #deep_freeze for enumerable objects.
|
8
|
+
if object.respond_to? :each
|
9
|
+
if object.instance_of?(Hash)
|
10
|
+
object.each { |key, val| freeze(val) }
|
11
|
+
else
|
12
|
+
object.each { |val| freeze(val) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# # Freezing of all instance variable values.
|
17
|
+
# object.instance_variables.each do |var|
|
18
|
+
# frozen_val = instance_variable_get(var)
|
19
|
+
# frozen_val.deep_freeze
|
20
|
+
# instance_variable_set(var, frozen_val)
|
21
|
+
# end
|
22
|
+
|
23
|
+
if object.frozen?
|
24
|
+
object
|
25
|
+
else
|
26
|
+
object.freeze
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Query
|
3
|
+
class AdhocBlock < Base
|
4
|
+
attr_reader :body
|
5
|
+
|
6
|
+
# Initializes a AdhocBlock with a given block of code.
|
7
|
+
#
|
8
|
+
# @param body [Proc] The block of code for the query.
|
9
|
+
def initialize(body)
|
10
|
+
super()
|
11
|
+
@body = body
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply(scope, **)
|
15
|
+
body.call(scope, **)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Query
|
3
|
+
class Base
|
4
|
+
include Plutonium::Definition::DefineableProps
|
5
|
+
include Plutonium::Definition::ConfigAttr
|
6
|
+
include Plutonium::Definition::Presentable
|
7
|
+
|
8
|
+
defineable_props :field, :input
|
9
|
+
|
10
|
+
# Applies a parameterized query to modify the given scope.
|
11
|
+
#
|
12
|
+
# @param scope [Object] The initial scope that will be filtered, sorted, or otherwise modified
|
13
|
+
# by applying this query. This is typically an ActiveRecord::Relation or similar query object.
|
14
|
+
#
|
15
|
+
# @param params [Hash] Optional parameters that configure how the query is applied.
|
16
|
+
# The specific parameters accepted depend on the implementing class.
|
17
|
+
#
|
18
|
+
# @return [Object] The modified scope with this query's conditions applied. Returns the same
|
19
|
+
# type as the input scope parameter.
|
20
|
+
#
|
21
|
+
# @example Basic usage
|
22
|
+
# query.apply(User.all, status: 'active')
|
23
|
+
#
|
24
|
+
def apply(scope, **params)
|
25
|
+
raise NotImplementedError, "#{self.class}#apply(scope, **params)"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|