recycle_bin 1.1.0 → 1.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/CHANGELOG.md +57 -0
- data/README.md +228 -13
- data/app/controllers/recycle_bin/trash_controller.rb +424 -21
- data/app/helpers/recycle_bin/application_helper.rb +175 -0
- data/app/views/{layouts/recycle_bin/application.html.erb → recycle_bin/layouts/recycle_bin.html.erb} +850 -609
- data/app/views/recycle_bin/shared/_error_messages.html.erb +10 -0
- data/app/views/recycle_bin/shared/_flash_messages.html.erb +6 -0
- data/app/views/recycle_bin/trash/_action_history.html.erb +75 -0
- data/app/views/recycle_bin/trash/_associations.html.erb +50 -0
- data/app/views/recycle_bin/trash/_filters.html.erb +561 -0
- data/app/views/recycle_bin/trash/_item.html.erb +267 -0
- data/app/views/recycle_bin/trash/_pagination.html.erb +75 -0
- data/app/views/recycle_bin/trash/_stats.html.erb +50 -0
- data/app/views/recycle_bin/trash/dashboard.html.erb +618 -0
- data/app/views/recycle_bin/trash/index.html.erb +247 -278
- data/app/views/recycle_bin/trash/show.html.erb +60 -215
- data/config/routes.rb +9 -2
- data/docs/index.html +928 -0
- data/docs/logo.svg +71 -0
- data/lib/recycle_bin/version.rb +1 -1
- data/lib/recycle_bin.rb +111 -1
- metadata +18 -8
- data/app/views/layouts/recycle_bin/recycle_bin/application.html.erb +0 -266
- data/app/views/layouts/recycle_bin/recycle_bin/trash/index.html.erb +0 -133
- data/app/views/layouts/recycle_bin/recycle_bin/trash/show.html.erb +0 -175
- data/recycle_bin.gemspec +0 -47
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
<% content_for :title, "#{@item.class.name} Details" %>
|
|
2
|
-
|
|
3
|
-
<!-- Breadcrumb -->
|
|
4
|
-
<div style="margin-bottom: 2rem;">
|
|
5
|
-
<%= link_to "← Back to Trash", recycle_bin.trash_index_path,
|
|
6
|
-
style: "color: #007bff; text-decoration: none;" %>
|
|
7
|
-
</div>
|
|
8
|
-
|
|
9
|
-
<!-- Item Header -->
|
|
10
|
-
<div class="card">
|
|
11
|
-
<div style="display: flex; justify-content: between; align-items: start; margin-bottom: 1.5rem;">
|
|
12
|
-
<div style="flex: 1;">
|
|
13
|
-
<h1 style="color: #495057; margin-bottom: 0.5rem;">
|
|
14
|
-
<span style="font-size: 0.8em; color: #6c757d;"><%= @item.class.name %></span><br>
|
|
15
|
-
<%= @item.recyclable_title %>
|
|
16
|
-
</h1>
|
|
17
|
-
<p style="color: #6c757d;">
|
|
18
|
-
Deleted <%= time_ago_in_words(@item.deleted_at) %> ago
|
|
19
|
-
(<%= @item.deleted_at.strftime('%B %d, %Y at %I:%M %p') %>)
|
|
20
|
-
</p>
|
|
21
|
-
</div>
|
|
22
|
-
|
|
23
|
-
<div style="flex-shrink: 0;">
|
|
24
|
-
<%= link_to "Restore", recycle_bin.restore_trash_path(@item),
|
|
25
|
-
method: :patch,
|
|
26
|
-
class: "btn btn-success",
|
|
27
|
-
style: "margin-right: 0.5rem;",
|
|
28
|
-
data: {
|
|
29
|
-
confirm: "Are you sure you want to restore this #{@item.class.name.downcase}?"
|
|
30
|
-
} %>
|
|
31
|
-
<%= link_to "Delete Forever", recycle_bin.trash_path(@item),
|
|
32
|
-
method: :delete,
|
|
33
|
-
class: "btn btn-danger",
|
|
34
|
-
data: {
|
|
35
|
-
confirm: "This will permanently delete this #{@item.class.name.downcase}. This action cannot be undone!"
|
|
36
|
-
} %>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
<!-- Item Status -->
|
|
41
|
-
<div style="background: #f8f9fa; padding: 1rem; border-radius: 4px; margin-bottom: 1.5rem;">
|
|
42
|
-
<strong>Status:</strong>
|
|
43
|
-
<span style="color: #dc3545;">🗑️ In Trash</span>
|
|
44
|
-
|
|
45
|
-
<% if @item.respond_to?(:deleted_at) && @item.deleted_at %>
|
|
46
|
-
<br><strong>Deleted At:</strong> <%= @item.deleted_at.strftime('%B %d, %Y at %I:%M %p') %>
|
|
47
|
-
<% end %>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
<!-- Item Data -->
|
|
52
|
-
<div class="card">
|
|
53
|
-
<h3 style="margin-bottom: 1.5rem; color: #495057;">Original Data</h3>
|
|
54
|
-
|
|
55
|
-
<% if @original_attributes.any? %>
|
|
56
|
-
<table class="table">
|
|
57
|
-
<thead>
|
|
58
|
-
<tr>
|
|
59
|
-
<th style="width: 30%;">Field</th>
|
|
60
|
-
<th>Value</th>
|
|
61
|
-
</tr>
|
|
62
|
-
</thead>
|
|
63
|
-
<tbody>
|
|
64
|
-
<% @original_attributes.each do |key, value| %>
|
|
65
|
-
<tr>
|
|
66
|
-
<td><strong><%= key.humanize %></strong></td>
|
|
67
|
-
<td>
|
|
68
|
-
<% if value.nil? %>
|
|
69
|
-
<em style="color: #6c757d;">nil</em>
|
|
70
|
-
<% elsif value.is_a?(String) && value.length > 100 %>
|
|
71
|
-
<div>
|
|
72
|
-
<%= truncate(value, length: 100) %>
|
|
73
|
-
<details style="margin-top: 0.5rem;">
|
|
74
|
-
<summary style="cursor: pointer; color: #007bff;">Show full content</summary>
|
|
75
|
-
<div style="margin-top: 0.5rem; padding: 0.5rem; background: #f8f9fa; border-radius: 4px;">
|
|
76
|
-
<%= simple_format(value) %>
|
|
77
|
-
</div>
|
|
78
|
-
</details>
|
|
79
|
-
</div>
|
|
80
|
-
<% elsif value.is_a?(Time) || value.is_a?(DateTime) %>
|
|
81
|
-
<%= value.strftime('%B %d, %Y at %I:%M %p') %>
|
|
82
|
-
<br><small style="color: #6c757d;">(<%= time_ago_in_words(value) %> ago)</small>
|
|
83
|
-
<% elsif value.is_a?(Date) %>
|
|
84
|
-
<%= value.strftime('%B %d, %Y') %>
|
|
85
|
-
<% elsif value == true %>
|
|
86
|
-
<span style="color: #28a745;">✓ Yes</span>
|
|
87
|
-
<% elsif value == false %>
|
|
88
|
-
<span style="color: #dc3545;">✗ No</span>
|
|
89
|
-
<% else %>
|
|
90
|
-
<%= value %>
|
|
91
|
-
<% end %>
|
|
92
|
-
</td>
|
|
93
|
-
</tr>
|
|
94
|
-
<% end %>
|
|
95
|
-
</tbody>
|
|
96
|
-
</table>
|
|
97
|
-
<% else %>
|
|
98
|
-
<div class="empty-state">
|
|
99
|
-
<p>No data available for this item.</p>
|
|
100
|
-
</div>
|
|
101
|
-
<% end %>
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
<!-- Associations (if any) -->
|
|
105
|
-
<% if @associations.any? %>
|
|
106
|
-
<div class="card">
|
|
107
|
-
<h3 style="margin-bottom: 1.5rem; color: #495057;">Related Items</h3>
|
|
108
|
-
|
|
109
|
-
<% @associations.each do |association_name, items| %>
|
|
110
|
-
<div style="margin-bottom: 2rem;">
|
|
111
|
-
<h4 style="color: #6c757d; margin-bottom: 1rem;"><%= association_name.humanize %></h4>
|
|
112
|
-
|
|
113
|
-
<% if items.any? %>
|
|
114
|
-
<ul style="list-style: none; padding: 0;">
|
|
115
|
-
<% items.each do |item| %>
|
|
116
|
-
<li style="padding: 0.5rem; background: #f8f9fa; margin-bottom: 0.5rem; border-radius: 4px;">
|
|
117
|
-
<%= item.class.name %> -
|
|
118
|
-
<%= item.respond_to?(:title) ? item.title :
|
|
119
|
-
item.respond_to?(:name) ? item.name :
|
|
120
|
-
"ID: #{item.id}" %>
|
|
121
|
-
|
|
122
|
-
<% if item.respond_to?(:deleted_at) && item.deleted_at %>
|
|
123
|
-
<span style="color: #dc3545; font-size: 0.875rem;">(Also deleted)</span>
|
|
124
|
-
<% end %>
|
|
125
|
-
</li>
|
|
126
|
-
<% end %>
|
|
127
|
-
</ul>
|
|
128
|
-
<% else %>
|
|
129
|
-
<p style="color: #6c757d; font-style: italic;">No related items found.</p>
|
|
130
|
-
<% end %>
|
|
131
|
-
</div>
|
|
132
|
-
<% end %>
|
|
133
|
-
</div>
|
|
134
|
-
<% end %>
|
|
135
|
-
|
|
136
|
-
<!-- Actions -->
|
|
137
|
-
<div class="card" style="background: #f8f9fa;">
|
|
138
|
-
<h4 style="color: #495057; margin-bottom: 1rem;">Available Actions</h4>
|
|
139
|
-
|
|
140
|
-
<div style="display: flex; gap: 1rem; flex-wrap: wrap;">
|
|
141
|
-
<%= link_to recycle_bin.restore_trash_path(@item),
|
|
142
|
-
method: :patch,
|
|
143
|
-
class: "btn btn-success",
|
|
144
|
-
data: { confirm: "Restore this #{@item.class.name.downcase}?" } do %>
|
|
145
|
-
↶ Restore Item
|
|
146
|
-
<% end %>
|
|
147
|
-
|
|
148
|
-
<%= link_to recycle_bin.trash_path(@item),
|
|
149
|
-
method: :delete,
|
|
150
|
-
class: "btn btn-danger",
|
|
151
|
-
data: { confirm: "Permanently delete this #{@item.class.name.downcase}? This cannot be undone!" } do %>
|
|
152
|
-
🗑️ Delete Forever
|
|
153
|
-
<% end %>
|
|
154
|
-
|
|
155
|
-
<%= link_to recycle_bin.trash_index_path, class: "btn btn-primary" do %>
|
|
156
|
-
📋 Back to List
|
|
157
|
-
<% end %>
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
|
|
161
|
-
<!-- Debug Info (only in development) -->
|
|
162
|
-
<% if Rails.env.development? %>
|
|
163
|
-
<div class="card" style="margin-top: 2rem; border: 1px dashed #dee2e6;">
|
|
164
|
-
<details>
|
|
165
|
-
<summary style="cursor: pointer; color: #6c757d;">🔍 Debug Info (Development Only)</summary>
|
|
166
|
-
<div style="margin-top: 1rem;">
|
|
167
|
-
<p><strong>Class:</strong> <%= @item.class.name %></p>
|
|
168
|
-
<p><strong>ID:</strong> <%= @item.id %></p>
|
|
169
|
-
<p><strong>Deleted At:</strong> <%= @item.deleted_at %></p>
|
|
170
|
-
<p><strong>Attributes:</strong></p>
|
|
171
|
-
<pre style="background: #f8f9fa; padding: 1rem; border-radius: 4px; overflow-x: auto;"><%= @item.attributes.to_yaml %></pre>
|
|
172
|
-
</div>
|
|
173
|
-
</details>
|
|
174
|
-
</div>
|
|
175
|
-
<% end %>
|
data/recycle_bin.gemspec
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'lib/recycle_bin/version'
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = 'recycle_bin'
|
|
7
|
-
spec.version = RecycleBin::VERSION
|
|
8
|
-
spec.authors = ['Rishi Somani', 'Shobhit Jain', 'Raghav Agrawal']
|
|
9
|
-
spec.email = ['somani.rishi81@gmail.com', 'shobhjain09@gmail.com', 'raghavagrawal019@gmail.com']
|
|
10
|
-
|
|
11
|
-
spec.summary = 'Soft delete and trash management for Ruby on Rails applications'
|
|
12
|
-
spec.description = 'RecycleBin provides soft delete functionality with a user-friendly trash/recycle bin interface for any Rails application. Easily restore deleted records with a simple web interface.'
|
|
13
|
-
spec.homepage = 'https://github.com/R95-del/recycle_bin'
|
|
14
|
-
spec.license = 'MIT'
|
|
15
|
-
spec.required_ruby_version = '>= 2.7.0'
|
|
16
|
-
|
|
17
|
-
# Specify which files should be added to the gem when it is released.
|
|
18
|
-
spec.files = Dir.chdir(__dir__) do
|
|
19
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
20
|
-
# Exclude the gemspec file itself and development files
|
|
21
|
-
(File.expand_path(f) == __FILE__) ||
|
|
22
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github]) ||
|
|
23
|
-
f.match?(/\A\./) || # Exclude dotfiles
|
|
24
|
-
f.end_with?('.gem') || # Exclude any .gem files
|
|
25
|
-
f.include?('Gemfile.lock') # Exclude Gemfile.lock
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
spec.require_paths = ['lib']
|
|
30
|
-
|
|
31
|
-
# Runtime dependencies - Use pessimistic version constraints
|
|
32
|
-
spec.add_dependency 'rails', '>= 6.0', '< 9.0'
|
|
33
|
-
|
|
34
|
-
# Development dependencies - FIXED to match Gemfile
|
|
35
|
-
spec.add_development_dependency 'factory_bot_rails', '~> 6.2'
|
|
36
|
-
spec.add_development_dependency 'rspec-rails', '>= 6.0' # Changed from '~> 6.0'
|
|
37
|
-
spec.add_development_dependency 'sqlite3', '~> 2.0' # Changed from '~> 2.1'
|
|
38
|
-
|
|
39
|
-
# Gem metadata with distinct URIs
|
|
40
|
-
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
41
|
-
spec.metadata['homepage_uri'] = spec.homepage
|
|
42
|
-
spec.metadata['source_code_uri'] = 'https://github.com/R95-del/recycle_bin'
|
|
43
|
-
spec.metadata['changelog_uri'] = 'https://github.com/R95-del/recycle_bin/blob/main/CHANGELOG.md'
|
|
44
|
-
spec.metadata['bug_tracker_uri'] = 'https://github.com/R95-del/recycle_bin/issues'
|
|
45
|
-
spec.metadata['documentation_uri'] = 'https://github.com/R95-del/recycle_bin/blob/main/README.md'
|
|
46
|
-
spec.metadata['wiki_uri'] = 'https://github.com/R95-del/recycle_bin/wiki'
|
|
47
|
-
end
|