lato_storage 3.0.2 → 3.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 163f2e079a0521ac508d0c993e3b353d50e7589b0361031be512036df9a2e479
4
- data.tar.gz: 6a9837ce532e777a9388c9028abaef7b2226516995d7dbcad0c568f2c658c460
3
+ metadata.gz: 6e3025eada87329a0eb5a53da4eabcb1e3876c09c5730fdcec324904ec420604
4
+ data.tar.gz: d17b7f2355f1118aa280b0c59df2a323666313f5db0b755e3ad137c5d18998b8
5
5
  SHA512:
6
- metadata.gz: ea6e1dce16bc511addb43be9aba320df4193f5e92a800ba80abaa166163680f2160276c97c2673130147385d85f5ddcaf54ecb1f5c67c1c68ece5a48f7ef78a6
7
- data.tar.gz: 5f2a149a7b271d31a1e9ffa1c049587258cc1dade6d3a535873a65fab8ab0721725f960ca0eb951b9027cb05af833210d4c7825a61283a018f1be8d2ac5cd472
6
+ metadata.gz: 9a6ad7617bcda1e29b62374f1e5c947a16a0c06b67f0b692ba41c45968773d354b307dbae0a387349a7988a5ed0db8425ba567815ff482c5f1e4b209a04dbdb6
7
+ data.tar.gz: cdd52bbe6f56d9990cb2edd821500c248addaa841ce72353081e70528953a5ba752423425a2cf48489a66b5f786e4b273183883fc0d1f9247433b9f31e139355
@@ -6,9 +6,9 @@ module LatoStorage
6
6
  before_action { active_sidebar(:lato_storage); active_navbar(:lato_storage) }
7
7
 
8
8
  def index
9
- @blobs_count = ActiveStorage::Blob.count
10
- @attachments_count = ActiveStorage::Attachment.count
11
- @variant_records_count = defined?(ActiveStorage::VariantRecord) ? ActiveStorage::VariantRecord.count : 0
9
+ @blobs_count = blobs_count
10
+ @attachments_count = attachments_count
11
+ @variant_records_count = variant_records_count
12
12
  @deletable_blobs_count = ActiveStorage::Blob.unattached.where('active_storage_blobs.created_at < ?', 12.hours.ago).count
13
13
 
14
14
  @total_storage = ActiveStorage::Blob.sum(:byte_size)
@@ -40,5 +40,39 @@ module LatoStorage
40
40
 
41
41
  redirect_to lato.root_path, alert: 'You have not access to this section.'
42
42
  end
43
+
44
+ private
45
+
46
+ def blobs_count
47
+ return ActiveStorage::Blob.count unless LatoStorage.config.optimize_performances
48
+
49
+ if ActiveRecord::Base.connection.adapter_name.downcase == "postgresql"
50
+ ActiveRecord::Base.connection.execute("SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = 'active_storage_blobs';").first["estimate"]
51
+ else
52
+ ActiveStorage::Blob.count
53
+ end
54
+ end
55
+
56
+ def attachments_count
57
+ return ActiveStorage::Attachment.count unless LatoStorage.config.optimize_performances
58
+
59
+ if ActiveRecord::Base.connection.adapter_name.downcase == "postgresql"
60
+ ActiveRecord::Base.connection.execute("SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = 'active_storage_attachments';").first["estimate"]
61
+ else
62
+ ActiveStorage::Attachment.count
63
+ end
64
+ end
65
+
66
+ def variant_records_count
67
+ return 0 unless defined?(ActiveStorage::VariantRecord)
68
+ return ActiveStorage::VariantRecord.count unless LatoStorage.config.optimize_performances
69
+
70
+ if defined?(ActiveStorage::VariantRecord) && ActiveRecord::Base.connection.adapter_name.downcase == "postgresql"
71
+ ActiveRecord::Base.connection.execute("SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = 'active_storage_variant_records';").first["estimate"]
72
+ else
73
+ ActiveStorage::VariantRecord.count
74
+ end
75
+ end
76
+
43
77
  end
44
78
  end
@@ -0,0 +1,18 @@
1
+ module LatoStorage
2
+ class AttachmentsController < ApplicationController
3
+ def index
4
+ columns = %i[id record_id blob_id created_at]
5
+ sortable_columns = %i[created_at]
6
+ searchable_columns = %i[id record_id record_type blob_id]
7
+
8
+ @attachments = lato_index_collection(
9
+ ActiveStorage::Attachment.all.includes(:blob),
10
+ columns: columns,
11
+ sortable_columns: sortable_columns,
12
+ searchable_columns: searchable_columns,
13
+ default_sort_by: 'created_at|DESC',
14
+ pagination: 10,
15
+ )
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module LatoStorage
2
+ class BlobsController < ApplicationController
3
+ def index
4
+ columns = %i[id filename byte_size created_at]
5
+ sortable_columns = %i[byte_size created_at]
6
+ searchable_columns = %i[id filename]
7
+
8
+ @blobs = lato_index_collection(
9
+ ActiveStorage::Blob.all,
10
+ columns: columns,
11
+ sortable_columns: sortable_columns,
12
+ searchable_columns: searchable_columns,
13
+ default_sort_by: 'created_at|DESC',
14
+ pagination: 10,
15
+ )
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module LatoStorage
2
+ class VariantRecordsController < ApplicationController
3
+ def index
4
+ unless defined?(ActiveStorage::VariantRecord)
5
+ flash[:alert] = 'ActiveStorage::VariantRecord is not available in this version of Rails.'
6
+ redirect_to lato_storage.root_path
7
+ return
8
+ end
9
+
10
+ columns = %i[id blob_id variation_digest]
11
+ sortable_columns = %i[]
12
+ searchable_columns = %i[id blob_id]
13
+
14
+ @variant_records = lato_index_collection(
15
+ ActiveStorage::VariantRecord.all,
16
+ columns: columns,
17
+ sortable_columns: sortable_columns,
18
+ searchable_columns: searchable_columns,
19
+ default_sort_by: 'blob_id|DESC',
20
+ pagination: 10,
21
+ )
22
+ end
23
+ end
24
+ end
@@ -12,5 +12,34 @@ module LatoStorage
12
12
  "#{format('%.2f', converted)} #{units[exponent]}"
13
13
  end
14
14
 
15
+ def active_storage_blob_byte_size(blob)
16
+ format_bytes blob.byte_size
17
+ end
18
+
19
+ def active_storage_blob_created_at(blob)
20
+ blob.created_at.strftime('%Y-%m-%d %H:%M:%S')
21
+ end
22
+
23
+ def active_storage_blob_filename(blob)
24
+ link_to blob.filename, main_app.url_for(blob), target: '_blank', class: 'text-truncate d-block', style: 'max-width: 250px;'
25
+ end
26
+
27
+ def active_storage_attachment_created_at(attachment)
28
+ attachment.created_at.strftime('%Y-%m-%d %H:%M:%S')
29
+ end
30
+
31
+ def active_storage_attachment_record_id(attachment)
32
+ "#{attachment.record_type}##{attachment.record_id}"
33
+ end
34
+
35
+ def active_storage_attachment_blob_id(attachment)
36
+ return ' - ' if attachment.blob.nil?
37
+ link_to attachment.blob.filename, main_app.url_for(attachment.blob), target: '_blank', class: 'text-truncate d-block', style: 'max-width: 250px;'
38
+ end
39
+
40
+ def active_storage_variant_record_blob_id(variant_record)
41
+ return ' - ' if variant_record.blob.nil?
42
+ link_to variant_record.blob.filename, main_app.url_for(variant_record.blob), target: '_blank', class: 'text-truncate d-block', style: 'max-width: 250px;'
43
+ end
15
44
  end
16
45
  end
@@ -6,6 +6,7 @@
6
6
  <div class="card-body text-center">
7
7
  <div class="fw-bold fs-2"><%= @blobs_count %></div>
8
8
  <div><%= I18n.t('lato_storage.total_blobs') %></div>
9
+ <%= link_to I18n.t('lato_storage.cta_see_all'), lato_storage.blobs_path, class: 'btn btn-primary btn-sm mt-3', data: { lato_action_target: 'trigger', turbo_frame: 'lato_index_default_active_storage_blob', action_size: 'xl', action_title: I18n.t('lato_storage.blobs') } %>
9
10
  </div>
10
11
  </div>
11
12
  </div>
@@ -15,6 +16,7 @@
15
16
  <div class="card-body text-center">
16
17
  <div class="fw-bold fs-2"><%= @attachments_count %></div>
17
18
  <div><%= I18n.t('lato_storage.total_attachments') %></div>
19
+ <%= link_to I18n.t('lato_storage.cta_see_all'), lato_storage.attachments_path, class: 'btn btn-primary btn-sm mt-3', data: { lato_action_target: 'trigger', turbo_frame: 'lato_index_default_active_storage_attachment', action_size: 'xl', action_title: I18n.t('lato_storage.attachments') } %>
18
20
  </div>
19
21
  </div>
20
22
  </div>
@@ -24,6 +26,7 @@
24
26
  <div class="card-body text-center">
25
27
  <div class="fw-bold fs-2"><%= @variant_records_count %></div>
26
28
  <div><%= I18n.t('lato_storage.total_variant_records') %></div>
29
+ <%= link_to I18n.t('lato_storage.cta_see_all'), lato_storage.variant_records_path, class: 'btn btn-primary btn-sm mt-3', data: { lato_action_target: 'trigger', turbo_frame: 'lato_index_default_active_storage_variant_record', action_size: 'xl', action_title: I18n.t('lato_storage.variant_records') } %>
27
30
  </div>
28
31
  </div>
29
32
  </div>
@@ -33,6 +36,7 @@
33
36
  <div class="card-body text-center">
34
37
  <div class="fw-bold fs-2"><%= @deletable_blobs_count %></div>
35
38
  <div><%= I18n.t('lato_storage.deletable_blobs') %></div>
39
+ <%= link_to I18n.t('lato_storage.cta_free_space'), lato_storage.cleaner_path, class: 'btn btn-primary btn-sm mt-3', data: { turbo_method: :post, lato_action_target: 'trigger', turbo_frame: 'lato_operation' } %>
36
40
  </div>
37
41
  </div>
38
42
  </div>
@@ -82,10 +86,6 @@
82
86
  <h5 class="card-title mb-0">
83
87
  <%= I18n.t('lato_storage.storage_usage') %>
84
88
  </h5>
85
-
86
- <div class="btn-group btn-group-sm" role="group" aria-label="Basic example">
87
- <%= link_to I18n.t('lato_storage.cta_free_space'), lato_storage.cleaner_path, class: 'btn btn-primary', data: { turbo_method: :post, lato_action_target: 'trigger', turbo_frame: 'lato_operation' } %>
88
- </div>
89
89
  </div>
90
90
  <div class="card-body row">
91
91
  <div class="col col-12 col-md-6 mb-3 mb-md-0">
@@ -121,7 +121,7 @@
121
121
  <a class="list-group-item list-group-item-action" href="<%= main_app.url_for(blob) %>" target="_blank" rel="noopener noreferrer" download>
122
122
  <div class="d-flex justify-content-between align-items-center">
123
123
  <strong class="text-truncate"><%= blob.filename %></strong>
124
- <div class="d-flex align-items-center">
124
+ <div class="d-flex align-items-center ms-3">
125
125
  <span class="badge bg-primary rounded-pill">
126
126
  <%= format_bytes blob.byte_size %>
127
127
  </span>
@@ -0,0 +1,9 @@
1
+ <%= lato_page_head I18n.t('lato_storage.attachments'), [
2
+ { label: I18n.t('lato_storage.storage'), path: lato_storage.root_path },
3
+ ] %>
4
+
5
+ <div class="card">
6
+ <div class="card-body">
7
+ <%= lato_index @attachments, skip_total_count: LatoStorage.config.optimize_performances %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,9 @@
1
+ <%= lato_page_head I18n.t('lato_storage.blobs'), [
2
+ { label: I18n.t('lato_storage.storage'), path: lato_storage.root_path },
3
+ ] %>
4
+
5
+ <div class="card">
6
+ <div class="card-body">
7
+ <%= lato_index @blobs, skip_total_count: LatoStorage.config.optimize_performances %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,9 @@
1
+ <%= lato_page_head I18n.t('lato_storage.variant_records'), [
2
+ { label: I18n.t('lato_storage.storage'), path: lato_storage.root_path },
3
+ ] %>
4
+
5
+ <div class="card">
6
+ <div class="card-body">
7
+ <%= lato_index @variant_records, skip_total_count: LatoStorage.config.optimize_performances %>
8
+ </div>
9
+ </div>
@@ -12,4 +12,8 @@ en:
12
12
  largest_blobs: "Largest Blobs"
13
13
  no_largest_blobs: "No Blobs available"
14
14
  deletable_blobs: "Deletable Blobs"
15
- cta_free_space: "Free up space"
15
+ cta_free_space: "Free up space"
16
+ cta_see_all: "See all"
17
+ blobs: "Blobs"
18
+ attachments: "Attachments"
19
+ variant_records: "Variant Records"
@@ -13,3 +13,7 @@ it:
13
13
  no_largest_blobs: "Nessun blob disponibile"
14
14
  deletable_blobs: "Blob eliminabili"
15
15
  cta_free_space: "Libera spazio"
16
+ cta_see_all: "Vedi tutti"
17
+ blobs: "Blob"
18
+ attachments: "Allegati"
19
+ variant_records: "Varianti"
data/config/routes.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  LatoStorage::Engine.routes.draw do
2
2
  root 'application#index'
3
3
  post 'cleaner', to: 'application#cleaner', as: :cleaner
4
+
5
+ resources :blobs, only: [:index]
6
+ resources :attachments, only: [:index]
7
+ resources :variant_records, only: [:index]
4
8
  end
@@ -3,8 +3,16 @@ module LatoStorage
3
3
  # This class contains the default configuration of the engine.
4
4
  ##
5
5
  class Config
6
-
6
+
7
+ # This option allows to optimize performances by skipping count queries.
8
+ # If set to true, it will not perform count queries for collections and use other methods instead.
9
+ # This can significantly speed up operations but may lead to inaccuracies in counts.
10
+ # This is really useful for large datasets where performance is critical.
11
+ # Default is false.
12
+ attr_accessor :optimize_performances
13
+
7
14
  def initialize
15
+ @optimize_performances = false
8
16
  end
9
17
  end
10
18
  end
@@ -1,3 +1,3 @@
1
1
  module LatoStorage
2
- VERSION = "3.0.2"
2
+ VERSION = "3.0.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lato_storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregorio Galante
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-18 00:00:00.000000000 Z
11
+ date: 2025-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,10 +52,16 @@ files:
52
52
  - app/assets/javascripts/lato_storage/application.js
53
53
  - app/assets/stylesheets/lato_storage/application.scss
54
54
  - app/controllers/lato_storage/application_controller.rb
55
+ - app/controllers/lato_storage/attachments_controller.rb
56
+ - app/controllers/lato_storage/blobs_controller.rb
57
+ - app/controllers/lato_storage/variant_records_controller.rb
55
58
  - app/helpers/lato_storage/application_helper.rb
56
59
  - app/jobs/lato_storage/application_job.rb
57
60
  - app/mailers/lato_storage/application_mailer.rb
58
61
  - app/views/lato_storage/application/index.html.erb
62
+ - app/views/lato_storage/attachments/index.html.erb
63
+ - app/views/lato_storage/blobs/index.html.erb
64
+ - app/views/lato_storage/variant_records/index.html.erb
59
65
  - config/importmap.rb
60
66
  - config/locales/en.yml
61
67
  - config/locales/it.yml