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
|
@@ -27,5 +27,180 @@ module RecycleBin
|
|
|
27
27
|
time.strftime('%B %d, %Y')
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
|
+
|
|
31
|
+
# Check if any filters are currently active
|
|
32
|
+
def any_filters_active?
|
|
33
|
+
%w[search type time deleted_by size date_from date_to].any? { |param| params[param].present? }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Generate human-readable label for time filter
|
|
37
|
+
def time_filter_label(time_value)
|
|
38
|
+
case time_value
|
|
39
|
+
when 'today'
|
|
40
|
+
'Today'
|
|
41
|
+
when 'week'
|
|
42
|
+
'This Week'
|
|
43
|
+
when 'month'
|
|
44
|
+
'This Month'
|
|
45
|
+
when 'year'
|
|
46
|
+
'This Year'
|
|
47
|
+
else
|
|
48
|
+
time_value.to_s.humanize
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Generate human-readable label for size filter
|
|
53
|
+
def size_filter_label(size_value)
|
|
54
|
+
case size_value
|
|
55
|
+
when 'small'
|
|
56
|
+
'Small (< 1KB)'
|
|
57
|
+
when 'medium'
|
|
58
|
+
'Medium (1KB - 100KB)'
|
|
59
|
+
when 'large'
|
|
60
|
+
'Large (> 100KB)'
|
|
61
|
+
else
|
|
62
|
+
size_value.to_s.humanize
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Classify item size for CSS styling
|
|
67
|
+
def size_class(item)
|
|
68
|
+
size_bytes = calculate_item_memory_size(item)
|
|
69
|
+
|
|
70
|
+
if size_bytes < 1.kilobyte
|
|
71
|
+
'small'
|
|
72
|
+
elsif size_bytes < 100.kilobytes
|
|
73
|
+
'medium'
|
|
74
|
+
else
|
|
75
|
+
'large'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Calculate item memory size (helper method for views)
|
|
80
|
+
def calculate_item_memory_size(item)
|
|
81
|
+
return 0 unless item.respond_to?(:attributes)
|
|
82
|
+
|
|
83
|
+
# Simple calculation of item memory footprint
|
|
84
|
+
item.attributes.to_s.bytesize
|
|
85
|
+
rescue StandardError => e
|
|
86
|
+
Rails.logger.debug("Error calculating memory size: #{e.message}")
|
|
87
|
+
0
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Format file size in human-readable format
|
|
91
|
+
def human_file_size(bytes)
|
|
92
|
+
return '0 B' if bytes.nil? || bytes.zero?
|
|
93
|
+
|
|
94
|
+
units = %w[B KB MB GB TB]
|
|
95
|
+
size = bytes.to_f
|
|
96
|
+
unit_index = 0
|
|
97
|
+
|
|
98
|
+
while size >= 1024 && unit_index < units.length - 1
|
|
99
|
+
size /= 1024
|
|
100
|
+
unit_index += 1
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
"#{size.round(2)} #{units[unit_index]}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Highlight search terms in text
|
|
107
|
+
def highlight_search_terms(text, search_term)
|
|
108
|
+
return text if search_term.blank? || text.blank?
|
|
109
|
+
|
|
110
|
+
text.to_s.gsub(/(#{Regexp.escape(search_term)})/i, '<mark>\1</mark>').html_safe
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Generate search result summary
|
|
114
|
+
def search_result_summary(total_count, search_term)
|
|
115
|
+
if search_term.present?
|
|
116
|
+
"Found #{total_count} result#{total_count == 1 ? '' : 's'} for \"#{search_term}\""
|
|
117
|
+
else
|
|
118
|
+
"#{total_count} item#{total_count == 1 ? '' : 's'} in trash"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Check if current page has search results
|
|
123
|
+
def search_results?
|
|
124
|
+
@deleted_items&.any?
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Generate export filename with current filters
|
|
128
|
+
def export_filename_with_filters(base_name, format)
|
|
129
|
+
filters = []
|
|
130
|
+
filters << "search_#{params[:search]}" if params[:search].present?
|
|
131
|
+
filters << "type_#{params[:type]}" if params[:type].present?
|
|
132
|
+
filters << "time_#{params[:time]}" if params[:time].present?
|
|
133
|
+
filters << "user_#{params[:deleted_by]}" if params[:deleted_by].present?
|
|
134
|
+
filters << "size_#{params[:size]}" if params[:size].present?
|
|
135
|
+
|
|
136
|
+
if params[:date_from].present? || params[:date_to].present?
|
|
137
|
+
date_range = [params[:date_from], params[:date_to]].compact.join('_to_')
|
|
138
|
+
filters << "date_#{date_range}" if date_range.present?
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
timestamp = Time.current.strftime('%Y%m%d_%H%M%S')
|
|
142
|
+
filter_suffix = filters.any? ? "_#{filters.join('_')}" : ''
|
|
143
|
+
|
|
144
|
+
"#{base_name}#{filter_suffix}_#{timestamp}.#{format}"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Generate filter breadcrumb
|
|
148
|
+
def filter_breadcrumb
|
|
149
|
+
return unless any_filters_active?
|
|
150
|
+
|
|
151
|
+
breadcrumbs = []
|
|
152
|
+
|
|
153
|
+
breadcrumbs << "Search: \"#{params[:search]}\"" if params[:search].present?
|
|
154
|
+
|
|
155
|
+
breadcrumbs << "Type: #{params[:type]}" if params[:type].present?
|
|
156
|
+
|
|
157
|
+
breadcrumbs << "Time: #{time_filter_label(params[:time])}" if params[:time].present?
|
|
158
|
+
|
|
159
|
+
breadcrumbs << "User: #{params[:deleted_by]}" if params[:deleted_by].present?
|
|
160
|
+
|
|
161
|
+
breadcrumbs << "Size: #{size_filter_label(params[:size])}" if params[:size].present?
|
|
162
|
+
|
|
163
|
+
if params[:date_from].present? || params[:date_to].present?
|
|
164
|
+
date_range = [params[:date_from], params[:date_to]].compact.join(' to ')
|
|
165
|
+
breadcrumbs << "Date: #{date_range}"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
breadcrumbs.join(' • ')
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Check if advanced filters are visible
|
|
172
|
+
def advanced_filters_visible?
|
|
173
|
+
%w[deleted_by size date_from date_to].any? { |param| params[param].present? }
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Generate filter count badge
|
|
177
|
+
def active_filter_count
|
|
178
|
+
count = 0
|
|
179
|
+
count += 1 if params[:search].present?
|
|
180
|
+
count += 1 if params[:type].present?
|
|
181
|
+
count += 1 if params[:time].present?
|
|
182
|
+
count += 1 if params[:deleted_by].present?
|
|
183
|
+
count += 1 if params[:size].present?
|
|
184
|
+
count += 1 if params[:date_from].present? || params[:date_to].present?
|
|
185
|
+
count
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Check if item matches current search
|
|
189
|
+
def item_matches_search?(item, search_term)
|
|
190
|
+
return true if search_term.blank?
|
|
191
|
+
|
|
192
|
+
search_term = search_term.downcase
|
|
193
|
+
|
|
194
|
+
# Check common fields
|
|
195
|
+
%w[title name email content body description].any? do |field|
|
|
196
|
+
item.send(field).to_s.downcase.include?(search_term) if item.respond_to?(field) && item.send(field).present?
|
|
197
|
+
end ||
|
|
198
|
+
# Check ID
|
|
199
|
+
item.id.to_s.include?(search_term) ||
|
|
200
|
+
# Check model class name
|
|
201
|
+
item.class.name.downcase.include?(search_term) ||
|
|
202
|
+
# Check all attributes
|
|
203
|
+
item.attributes.values.any? { |val| val.to_s.downcase.include?(search_term) }
|
|
204
|
+
end
|
|
30
205
|
end
|
|
31
206
|
end
|