From 7ead99ad118c7ba989cd1a4c81f8ae349e28ec32 Mon Sep 17 00:00:00 2001 From: B_Rass Date: Thu, 17 Oct 2024 17:59:47 +0200 Subject: [PATCH 1/8] Add delivery attributes --- app/models/site.rb | 2 ++ ...17155157_add_delivery_related_attributes_to_site.rb | 10 ++++++++++ db/schema.rb | 5 ++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20241017155157_add_delivery_related_attributes_to_site.rb diff --git a/app/models/site.rb b/app/models/site.rb index 3d74373f0..ce4581dcc 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -7,6 +7,8 @@ class Site < ApplicationRecord has_many :rooms, dependent: :restrict_with_error has_many :frames, through: :rooms, dependent: :restrict_with_error + has_one_attached :delivery_map + after_validation :geocode scope :sorted, -> { order(:position) } diff --git a/db/migrate/20241017155157_add_delivery_related_attributes_to_site.rb b/db/migrate/20241017155157_add_delivery_related_attributes_to_site.rb new file mode 100644 index 000000000..bf7dbcab2 --- /dev/null +++ b/db/migrate/20241017155157_add_delivery_related_attributes_to_site.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddDeliveryRelatedAttributesToSite < ActiveRecord::Migration[7.2] + def change + change_table :sites, bulk: true do |t| + t.text :delivery_address + t.text :delivery_times + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 356397ea3..3d3819372 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_09_18_141423) do +ActiveRecord::Schema[7.2].define(version: 2024_10_17_155157) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -485,6 +485,9 @@ t.decimal "latitude" t.decimal "longitude" t.integer "rooms_count", default: 0, null: false + t.text "description" + t.text "delivery_address" + t.text "delivery_times" end create_table "stacks", force: :cascade do |t| From 29f4d261ef22ffe57999466589c060625c2a94bc Mon Sep 17 00:00:00 2001 From: B_Rass Date: Thu, 17 Oct 2024 18:31:36 +0200 Subject: [PATCH 2/8] Add new attributes to show and _form --- app/controllers/sites_controller.rb | 7 ++++++- app/views/sites/_form.html.erb | 18 ++++++++++++++++++ app/views/sites/show.html.erb | 20 +++++++++++++++++--- config/locales/activerecord.fr.yml | 3 +++ config/locales/fr.yml | 2 -- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index fc4937b6f..7c3dc0e61 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -63,6 +63,11 @@ def set_site # Never trust parameters from the scary internet, only allow the white list through. def site_params - params.require(:site).permit(:name, :position, :street, :country, :city, :latitude, :longitude) + params.require(:site).permit( + :name, + :position, + :street, :country, :city, :latitude, :longitude, + :delivery_address, :delivery_times, :delivery_map + ) end end diff --git a/app/views/sites/_form.html.erb b/app/views/sites/_form.html.erb index 2c5da728a..efd5ca29f 100644 --- a/app/views/sites/_form.html.erb +++ b/app/views/sites/_form.html.erb @@ -51,6 +51,24 @@ <%= f.text_field :longitude, class: "form-control" %> + +
+ <%= f.label :delivery_address, class: "form-label" %> + <%= f.text_area :delivery_address, class: "form-control" %> +
+ +
+ <%= f.label :delivery_times, class: "form-label" %> + <%= f.text_area :delivery_times, class: "form-control" %> +
+ +
+ <%= f.label :delivery_map, class: "form-label" %> + <%= f.file_field :delivery_map, class: "form-control" %> + <% if @site.delivery_map.attached? %> + <%= image_tag @site.delivery_map.variant(resize_to_limit: [200, 200]), class: "ms-0 mt-2" %> + <% end %> +
<% end %>
diff --git a/app/views/sites/show.html.erb b/app/views/sites/show.html.erb index 05d4c3358..b5cc4f0ef 100644 --- a/app/views/sites/show.html.erb +++ b/app/views/sites/show.html.erb @@ -3,9 +3,7 @@ breadcrumb_steps = { Site.model_name.human.pluralize => sites_path, @site.name => "" } %> -<%= render Page::HeadingShowComponent.new( - resource: @site, title: t(".title", site_id: @site.id, site_name: @site.name), breadcrumb_steps: -) %> +<%= render Page::HeadingShowComponent.new(resource: @site, title: @site.name, breadcrumb_steps:) %>
@@ -42,6 +40,22 @@
<%= @site.public_send(attribute_name) %>
<% end %> + +
+ <% %i[delivery_address delivery_times].each do |attribute_name| %> +
<%= Site.human_attribute_name(attribute_name) %>
+
<%= @site.public_send(attribute_name) %>
+ <% end %> + +
<%= Site.human_attribute_name(:delivery_map) %>
+
+ <% if @site.delivery_map.attached? %> + <%= link_to @site.delivery_map, rel: :noopener, target: :_blank do %> + <%= image_tag @site.delivery_map, class: "w-100" %> + <% end %> + <% end %> +
+
<% end %>
diff --git a/config/locales/activerecord.fr.yml b/config/locales/activerecord.fr.yml index b7fa8063a..b557b8162 100644 --- a/config/locales/activerecord.fr.yml +++ b/config/locales/activerecord.fr.yml @@ -112,6 +112,9 @@ fr: country: Pays latitude: Latitude longitude: Longitude + delivery_address: Adresse livraison + delivery_times: Horaires de livraison + delivery_map: Plan de livraison rooms_count: zero: 0 salle one: 1 salle diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 56f1c8f21..5cd10e7fd 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -113,8 +113,6 @@ fr: title: Sites new_site: Ajouter un site delete_confirmation: Ce site ne pourra pas être supprimé tant qu'il sera associé à au moins une salle. Voulez-vous continuer ? - show: - title: 'Site #%{site_id} - %{site_name}' new: title: Nouveau site create: From ac2dd6f18e53e1fef60a53f71ba2fded74d31c9b Mon Sep 17 00:00:00 2001 From: B_Rass Date: Fri, 18 Oct 2024 11:04:42 +0200 Subject: [PATCH 3/8] After-review cleans --- app/views/sites/_form.html.erb | 2 +- app/views/sites/show.html.erb | 2 +- db/schema.rb | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/views/sites/_form.html.erb b/app/views/sites/_form.html.erb index efd5ca29f..ad548e7c7 100644 --- a/app/views/sites/_form.html.erb +++ b/app/views/sites/_form.html.erb @@ -66,7 +66,7 @@ <%= f.label :delivery_map, class: "form-label" %> <%= f.file_field :delivery_map, class: "form-control" %> <% if @site.delivery_map.attached? %> - <%= image_tag @site.delivery_map.variant(resize_to_limit: [200, 200]), class: "ms-0 mt-2" %> + <%= image_tag @site.delivery_map.representation(resize_to_limit: [200, 200]), class: "ms-0 mt-2" %> <% end %> <% end %> diff --git a/app/views/sites/show.html.erb b/app/views/sites/show.html.erb index b5cc4f0ef..a0a8e541d 100644 --- a/app/views/sites/show.html.erb +++ b/app/views/sites/show.html.erb @@ -51,7 +51,7 @@
<% if @site.delivery_map.attached? %> <%= link_to @site.delivery_map, rel: :noopener, target: :_blank do %> - <%= image_tag @site.delivery_map, class: "w-100" %> + <%= image_tag @site.delivery_map.representation(resize_to_limit: [1200, 1200]), class: "w-100" %> <% end %> <% end %>
diff --git a/db/schema.rb b/db/schema.rb index 3d3819372..6304c727c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -485,7 +485,6 @@ t.decimal "latitude" t.decimal "longitude" t.integer "rooms_count", default: 0, null: false - t.text "description" t.text "delivery_address" t.text "delivery_times" end From 790b5b495cf74e6ca934b4165b56d9b67ed2c5dd Mon Sep 17 00:00:00 2001 From: B_Rass Date: Fri, 18 Oct 2024 11:05:14 +0200 Subject: [PATCH 4/8] Rename export_pdf_controller to frame_export_pdf_controller --- ...troller.js => frame_export_pdf_controller.js} | 1 - app/views/bays/_export_button.html.erb | 16 ++++++++-------- app/views/islets/_export_button.html.erb | 16 ++++++++-------- app/views/moves/index.html.erb | 12 ++++++------ app/views/rooms/_action_buttons.html.erb | 14 +++++++------- app/views/rooms/_export_button.html.erb | 16 ++++++++-------- 6 files changed, 37 insertions(+), 38 deletions(-) rename app/javascript/controllers/{export_pdf_controller.js => frame_export_pdf_controller.js} (99%) diff --git a/app/javascript/controllers/export_pdf_controller.js b/app/javascript/controllers/frame_export_pdf_controller.js similarity index 99% rename from app/javascript/controllers/export_pdf_controller.js rename to app/javascript/controllers/frame_export_pdf_controller.js index a990a2c08..0f021658e 100644 --- a/app/javascript/controllers/export_pdf_controller.js +++ b/app/javascript/controllers/frame_export_pdf_controller.js @@ -46,7 +46,6 @@ export default class extends Controller { for (let i = 0; i < this.modelIdsValue.length; i++) { const modelId = this.modelIdsValue[i] - const url = this.isMoveValue ? `moves/print/${modelId}`: `/visualization/frames/${modelId}/print?view=${viewTarget}${ bgWiring ? "&bg=wiring" : ""}` diff --git a/app/views/bays/_export_button.html.erb b/app/views/bays/_export_button.html.erb index 240b22e57..ef6c446c6 100644 --- a/app/views/bays/_export_button.html.erb +++ b/app/views/bays/_export_button.html.erb @@ -1,14 +1,14 @@
+ data-controller="frame-export-pdf" + data-frame-export-pdf-model-ids-value="<%= bay.frames.order(:name).pluck(:id) %>" + data-frame-export-pdf-filename-value="bay-<%= bay.id %>"> diff --git a/app/views/bays/index.html.erb b/app/views/bays/index.html.erb index 744e0254b..b3e122418 100644 --- a/app/views/bays/index.html.erb +++ b/app/views/bays/index.html.erb @@ -88,7 +88,7 @@ <% end %> <% end %> - <% table.with_column(style: "min-width: 140px; width: 140px") do |bay| %> + <% table.with_column(style: "min-width: 132px; width: 132px") do |bay| %>
<%= render partial: "bays/export_button", locals: { bay: bay } %> <%= link_to visualization_bay_path(bay), class: "btn btn-primary", data: { turbo_frame: :_top } do %> diff --git a/app/views/islets/_export_button.html.erb b/app/views/islets/_export_button.html.erb index c354045a8..ea08f46cf 100644 --- a/app/views/islets/_export_button.html.erb +++ b/app/views/islets/_export_button.html.erb @@ -7,9 +7,9 @@ data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - - + <%= t("export_button.label") %> diff --git a/app/views/islets/index.html.erb b/app/views/islets/index.html.erb index 30f653c76..450c4d4bf 100644 --- a/app/views/islets/index.html.erb +++ b/app/views/islets/index.html.erb @@ -75,7 +75,7 @@ <%= Islet.human_attribute_name(:frames_count, count: islet.frames.count) %> <% end %> - <% table.with_column(style: "min-width: 140px; width: 140px") do |islet| %> + <% table.with_column(style: "min-width: 132px; width: 132px") do |islet| %>
<%= render partial: "islets/export_button", locals: { islet: islet } %> <%= link_to edit_islet_path(islet), class: "btn btn-info", data: { turbo_frame: :_top } do %> diff --git a/app/views/moves/index.html.erb b/app/views/moves/index.html.erb index b8168bc06..17446d4f2 100644 --- a/app/views/moves/index.html.erb +++ b/app/views/moves/index.html.erb @@ -88,7 +88,7 @@ <%= t("export_button.exports.pdf") %> - diff --git a/app/views/rooms/_action_buttons.html.erb b/app/views/rooms/_action_buttons.html.erb index 467bbafd1..46b86b191 100644 --- a/app/views/rooms/_action_buttons.html.erb +++ b/app/views/rooms/_action_buttons.html.erb @@ -53,8 +53,8 @@
diff --git a/app/views/rooms/_export_button.html.erb b/app/views/rooms/_export_button.html.erb index 5af029c82..42311f12d 100644 --- a/app/views/rooms/_export_button.html.erb +++ b/app/views/rooms/_export_button.html.erb @@ -7,9 +7,9 @@ data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - - + <%= t("export_button.label") %> diff --git a/app/views/rooms/index.html.erb b/app/views/rooms/index.html.erb index d7c717ab6..19e3dc24f 100644 --- a/app/views/rooms/index.html.erb +++ b/app/views/rooms/index.html.erb @@ -69,7 +69,7 @@ disabled> <% end %> - <% table.with_column(style: "min-width: 140px; width: 140px") do |room| %> + <% table.with_column(style: "min-width: 132px; width: 132px") do |room| %>
<%= render partial: "rooms/export_button", locals: { room: room } %> <%= link_to visualization_room_path(room), class: "btn btn-primary", data: { turbo_frame: :_top } do %> From e6795eee6db6f0d10f8d2f0433f3d4c40fbc1c3f Mon Sep 17 00:00:00 2001 From: B_Rass Date: Fri, 18 Oct 2024 12:48:43 +0200 Subject: [PATCH 6/8] Add export to PDF on delivery block on Site#show --- .../controllers/export_pdf_controller.js | 42 +++++++++++++++++++ .../frame_export_pdf_controller.js | 18 ++------ app/views/sites/show.html.erb | 29 ++++++++----- 3 files changed, 64 insertions(+), 25 deletions(-) create mode 100644 app/javascript/controllers/export_pdf_controller.js diff --git a/app/javascript/controllers/export_pdf_controller.js b/app/javascript/controllers/export_pdf_controller.js new file mode 100644 index 000000000..af585b15b --- /dev/null +++ b/app/javascript/controllers/export_pdf_controller.js @@ -0,0 +1,42 @@ +import { Controller } from "@hotwired/stimulus" + +import { html2pdf } from "html2pdf.js" + +const exportOptions = { + margin: 10, + image: { + type: "jpeg", + quality: 1.0 + }, + enableLinks: false, + html2canvas: { scale: 1.5 }, + jsPDF: { format: "legal" } +} + +export default class extends Controller { + static targets = ["spinner"] + static values = { filename: String } + + async export() { + this.showSpinner() + + const opt = { ...exportOptions, ...{ + filename: `export_${this.filenameValue}` + }} + + var element = document.getElementById("export-to-pdf").cloneNode(true) + element.prepend(document.getElementsByTagName("h1")[0].cloneNode(true)) + await html2pdf().set(opt) + .from(element) + .save() + .finally(() => this.hideSpinner()) + } + + showSpinner() { + this.spinnerTarget.classList.remove("d-none") + } + + hideSpinner() { + this.spinnerTarget.classList.add("d-none") + } +} diff --git a/app/javascript/controllers/frame_export_pdf_controller.js b/app/javascript/controllers/frame_export_pdf_controller.js index 0f021658e..05406b307 100644 --- a/app/javascript/controllers/frame_export_pdf_controller.js +++ b/app/javascript/controllers/frame_export_pdf_controller.js @@ -1,4 +1,4 @@ -import { Controller } from "@hotwired/stimulus" +import ExportPdfController from "./export_pdf_controller.js" import { get } from "@rails/request.js" import { html2pdf, saveAs, PDFDocument } from "html2pdf.js" @@ -15,11 +15,9 @@ const exportOptions = { jsPDF: { format: "legal" } } -export default class extends Controller { - static targets = ["spinner"] +export default class extends ExportPdfController { static values = { modelIds: Array, - filename: String, isMove: Boolean } @@ -49,9 +47,7 @@ export default class extends Controller { const url = this.isMoveValue ? `moves/print/${modelId}`: `/visualization/frames/${modelId}/print?view=${viewTarget}${ bgWiring ? "&bg=wiring" : ""}` - const response = await get(url, { - responseKind: "application/pdf" - }) + const response = await get(url) if (response.ok) { const html = await response.text @@ -70,12 +66,4 @@ export default class extends Controller { return pdfDoc } - - showSpinner() { - this.spinnerTarget.classList.remove("d-none") - } - - hideSpinner() { - this.spinnerTarget.classList.add("d-none") - } } diff --git a/app/views/sites/show.html.erb b/app/views/sites/show.html.erb index a0a8e541d..886ea0a81 100644 --- a/app/views/sites/show.html.erb +++ b/app/views/sites/show.html.erb @@ -3,7 +3,23 @@ breadcrumb_steps = { Site.model_name.human.pluralize => sites_path, @site.name => "" } %> -<%= render Page::HeadingShowComponent.new(resource: @site, title: @site.name, breadcrumb_steps:) %> +<%= render Page::HeadingShowComponent.new(resource: @site, title: @site.name, breadcrumb_steps:) do |heading| %> + <% heading.with_extra_buttons do %> + + <% end %> +<% end %>
@@ -28,21 +44,14 @@ <% end %>
-
+
<%= render CardComponent.new(type: :primary) do |card| %> <% card.with_header do %> <%= t("layouts.sidebar.location.title") %> <% end %>
- <% %i[street city country latitude longitude].each do |attribute_name| %> -
<%= Site.human_attribute_name(attribute_name) %>
-
<%= @site.public_send(attribute_name) %>
- <% end %> -
- -
- <% %i[delivery_address delivery_times].each do |attribute_name| %> + <% %i[street city country latitude longitude delivery_address delivery_times].each do |attribute_name| %>
<%= Site.human_attribute_name(attribute_name) %>
<%= @site.public_send(attribute_name) %>
<% end %> From 5fc4541986e2a309450ef6f4ad7dcbed760f5738 Mon Sep 17 00:00:00 2001 From: B_Rass Date: Tue, 22 Oct 2024 17:39:56 +0200 Subject: [PATCH 7/8] Add content_type validation on delivery_map --- Gemfile | 1 + Gemfile.lock | 6 ++++++ app/models/site.rb | 4 +++- app/views/sites/_form.html.erb | 6 ++++-- spec/models/site_spec.rb | 11 ++++++++++- spec/rails_helper.rb | 3 +++ 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index c416b005f..4cfe47eff 100644 --- a/Gemfile +++ b/Gemfile @@ -77,6 +77,7 @@ group :production do gem "passenger" end +gem "active_storage_validations" gem "acts_as_list" gem "friendly_id", "~> 5.2" gem "record_tag_helper", "~> 1.0" # Add helpers removed from Rails core in Rails 5 diff --git a/Gemfile.lock b/Gemfile.lock index b48954f31..9e9568ea2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -47,6 +47,11 @@ GEM rails-html-sanitizer (~> 1.6) active_record_doctor (1.15.0) activerecord (>= 4.2.0) + active_storage_validations (1.3.0) + activejob (>= 6.1.4) + activemodel (>= 6.1.4) + activestorage (>= 6.1.4) + activesupport (>= 6.1.4) activejob (7.2.1.1) activesupport (= 7.2.1.1) globalid (>= 0.3.6) @@ -588,6 +593,7 @@ PLATFORMS DEPENDENCIES active_record_doctor + active_storage_validations acts_as_list bootsnap bootstrap (~> 5.3.2) diff --git a/app/models/site.rb b/app/models/site.rb index ce4581dcc..8936df9f2 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class Site < ApplicationRecord - geocoded_by :address has_changelog has_many :rooms, dependent: :restrict_with_error @@ -9,6 +8,9 @@ class Site < ApplicationRecord has_one_attached :delivery_map + validates :delivery_map, content_type: [:png, :jpg, :jpeg, :pdf, :gif] + + geocoded_by :address after_validation :geocode scope :sorted, -> { order(:position) } diff --git a/app/views/sites/_form.html.erb b/app/views/sites/_form.html.erb index ad548e7c7..a4a484630 100644 --- a/app/views/sites/_form.html.erb +++ b/app/views/sites/_form.html.erb @@ -64,8 +64,10 @@
<%= f.label :delivery_map, class: "form-label" %> - <%= f.file_field :delivery_map, class: "form-control" %> - <% if @site.delivery_map.attached? %> + <%= f.file_field :delivery_map, + class: "form-control", + accept: "image/png, image/jpeg, image/gif, application/pdf" %> + <% if @site.delivery_map.attached? && @site.persisted? %> <%= image_tag @site.delivery_map.representation(resize_to_limit: [200, 200]), class: "ms-0 mt-2" %> <% end %>
diff --git a/spec/models/site_spec.rb b/spec/models/site_spec.rb index 2610e3c76..31bdd8fd9 100644 --- a/spec/models/site_spec.rb +++ b/spec/models/site_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'rails_helper' +require "rails_helper" RSpec.describe Site do subject(:site) { described_class.new(name: "Site A", street: "Rue du Cactus", city: "92055 La Défense", country: "France") } @@ -11,6 +11,15 @@ it { is_expected.to have_many(:rooms) } end + describe "validations" do + it do + is_expected.to validate_content_type_of(:delivery_map).allowing("image/png", + "image/jpeg", + "image/gif", + "application/pdf") + end + end + describe "#to_s" do it { expect(site.to_s).to eq site.name } end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index d9c2ccaa9..caf119799 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -8,6 +8,7 @@ abort("The Rails environment is running in production mode!") if Rails.env.production? require 'rspec/rails' # Add additional requires below this line. Rails is not loaded until this point! +require "active_storage_validations/matchers" # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are @@ -68,4 +69,6 @@ config.include ActiveJob::TestHelper, type: :job config.include ActiveJob::TestHelper, type: :controller + + config.include ActiveStorageValidations::Matchers end From 2fe812d8b9be45523fe006877b64022b2b5c25cc Mon Sep 17 00:00:00 2001 From: B_Rass Date: Tue, 22 Oct 2024 17:57:40 +0200 Subject: [PATCH 8/8] rubocop clean --- spec/models/site_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/site_spec.rb b/spec/models/site_spec.rb index 31bdd8fd9..3223deb28 100644 --- a/spec/models/site_spec.rb +++ b/spec/models/site_spec.rb @@ -13,7 +13,7 @@ describe "validations" do it do - is_expected.to validate_content_type_of(:delivery_map).allowing("image/png", + is_expected.to validate_content_type_of(:delivery_map).allowing("image/png", # rubocop:disable RSpec/ImplicitSubject "image/jpeg", "image/gif", "application/pdf")