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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/plutonium.css +1 -1
  3. data/app/views/components/sidebar_menu/sidebar_menu_component.rb +1 -1
  4. data/app/views/components/table_search_input/table_search_input_component.html.erb +3 -3
  5. data/app/views/resource/_resource_table.html.erb +0 -321
  6. data/lib/plutonium/core/controllers/authorizable.rb +5 -0
  7. data/lib/plutonium/core/controllers/entity_scoping.rb +4 -4
  8. data/lib/plutonium/definition/base.rb +8 -0
  9. data/lib/plutonium/definition/defineable_props.rb +1 -1
  10. data/lib/plutonium/definition/presentable.rb +71 -0
  11. data/lib/plutonium/interaction/README.md +1 -1
  12. data/lib/plutonium/interaction/base.rb +6 -6
  13. data/lib/plutonium/lib/deep_freezer.rb +31 -0
  14. data/lib/plutonium/query/adhoc_block.rb +19 -0
  15. data/lib/plutonium/query/base.rb +29 -0
  16. data/lib/plutonium/query/filter.rb +12 -0
  17. data/lib/plutonium/query/filters/text.rb +77 -0
  18. data/lib/plutonium/query/model_scope.rb +19 -0
  19. data/lib/plutonium/resource/controller.rb +14 -7
  20. data/lib/plutonium/resource/controllers/authorizable.rb +1 -1
  21. data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +26 -0
  22. data/lib/plutonium/resource/controllers/crud_actions.rb +2 -5
  23. data/lib/plutonium/resource/controllers/defineable.rb +0 -2
  24. data/lib/plutonium/resource/controllers/queryable.rb +36 -20
  25. data/lib/plutonium/resource/policy.rb +1 -1
  26. data/lib/plutonium/resource/query_object.rb +61 -147
  27. data/lib/plutonium/{refinements/parameter_refinements.rb → support/parameters.rb} +5 -7
  28. data/lib/plutonium/ui/component/methods.rb +1 -1
  29. data/lib/plutonium/ui/display/resource.rb +19 -15
  30. data/lib/plutonium/ui/form/query.rb +171 -0
  31. data/lib/plutonium/ui/form/resource.rb +21 -17
  32. data/lib/plutonium/ui/table/components/scopes_bar.rb +1 -1
  33. data/lib/plutonium/ui/table/components/search_bar.rb +6 -139
  34. data/lib/plutonium/ui/table/resource.rb +10 -9
  35. data/lib/plutonium/version.rb +1 -1
  36. data/package-lock.json +2 -2
  37. data/package.json +1 -1
  38. metadata +12 -4
  39. 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
- scoped_entity = case scoped_entity_strategy
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
@@ -67,7 +67,7 @@ module Plutonium
67
67
  end
68
68
  # merged[name].compact!
69
69
  end
70
- merged
70
+ Plutonium::Lib::DeepFreezer.freeze(merged)
71
71
  end
72
72
  end
73
73
 
@@ -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::Interaction::Concerns::Presentable
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
- # include Concerns::WorkflowDSL
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
@@ -0,0 +1,12 @@
1
+ module Plutonium
2
+ module Query
3
+ class Filter < Base
4
+ attr_reader :key
5
+
6
+ def initialize(key:)
7
+ super()
8
+ @key = key
9
+ end
10
+ end
11
+ end
12
+ end