From 7719ce18659e693325ce4b7a0043e523599e6b9a Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 7 Dec 2022 18:36:03 +0100 Subject: [PATCH 1/4] chore(attachment): increase poll antivirus timeout and make it clear it's not blocker --- app/components/attachment/edit_component.rb | 6 ++++++ .../edit_component/edit_component.html.haml | 2 +- app/components/attachment/multiple_component.rb | 6 ++++++ .../multiple_component.html.haml | 2 +- .../attachment/pending_poll_component.rb | 12 ++++++++++-- .../pending_poll_component.en.yml | 5 ++++- .../pending_poll_component.fr.yml | 6 +++++- .../pending_poll_component.html.haml | 6 +++++- .../controllers/turbo_poll_controller.ts | 5 +++-- .../attachment/pending_poll_component_spec.rb | 14 ++++++++++++++ 10 files changed, 55 insertions(+), 9 deletions(-) diff --git a/app/components/attachment/edit_component.rb b/app/components/attachment/edit_component.rb index c14aadfae..28bcf969e 100644 --- a/app/components/attachment/edit_component.rb +++ b/app/components/attachment/edit_component.rb @@ -84,6 +84,12 @@ class Attachment::EditComponent < ApplicationComponent end end + def poll_context + return :dossier if champ.present? + + nil + end + def field_name helpers.field_name(@form_object_name || ActiveModel::Naming.param_key(@attached_file.record), attribute_name) end diff --git a/app/components/attachment/edit_component/edit_component.html.haml b/app/components/attachment/edit_component/edit_component.html.haml index 92de59e40..e98f990c4 100644 --- a/app/components/attachment/edit_component/edit_component.html.haml +++ b/app/components/attachment/edit_component/edit_component.html.haml @@ -28,7 +28,7 @@ = file_field(champ, field_name, **file_field_options) - if persisted? - - Attachment::PendingPollComponent.new(attachment: attachment, poll_url:).then do |component| + - Attachment::PendingPollComponent.new(attachment: attachment, poll_url:, context: poll_context).then do |component| .fr-mt-2w = render component diff --git a/app/components/attachment/multiple_component.rb b/app/components/attachment/multiple_component.rb index ab0356256..f13b40317 100644 --- a/app/components/attachment/multiple_component.rb +++ b/app/components/attachment/multiple_component.rb @@ -43,4 +43,10 @@ class Attachment::MultipleComponent < ApplicationComponent helpers.auto_attach_url(champ) end alias poll_url auto_attach_url + + def poll_context + return :dossier if champ.present? + + nil + end end diff --git a/app/components/attachment/multiple_component/multiple_component.html.haml b/app/components/attachment/multiple_component/multiple_component.html.haml index 3d750b6c9..05aec6ada 100644 --- a/app/components/attachment/multiple_component/multiple_component.html.haml +++ b/app/components/attachment/multiple_component/multiple_component.html.haml @@ -10,4 +10,4 @@ = render Attachment::EditComponent.new(champ:, attached_file:, attachment: nil, index: attachments_count, user_can_destroy:, form_object_name:) // single poll and refresh message for all attachments - = render Attachment::PendingPollComponent.new(attachments: attachments, poll_url:) + = render Attachment::PendingPollComponent.new(attachments: attachments, poll_url:, context: poll_context) diff --git a/app/components/attachment/pending_poll_component.rb b/app/components/attachment/pending_poll_component.rb index 78ff9a139..cb198fa89 100644 --- a/app/components/attachment/pending_poll_component.rb +++ b/app/components/attachment/pending_poll_component.rb @@ -1,11 +1,15 @@ class Attachment::PendingPollComponent < ApplicationComponent - def initialize(poll_url:, attachment: nil, attachments: nil) + attr_reader :attachments + + def initialize(poll_url:, attachment: nil, attachments: nil, context: nil) @poll_url = poll_url @attachments = if attachment.present? [attachment] else attachments end + + @context = context end def render? @@ -14,7 +18,7 @@ class Attachment::PendingPollComponent < ApplicationComponent def long_pending? @attachments.any? do - pending_attachment?(_1) && _1.created_at < 30.seconds.ago + pending_attachment?(_1) && _1.created_at < 60.seconds.ago end end @@ -25,6 +29,10 @@ class Attachment::PendingPollComponent < ApplicationComponent } end + def as_dossier? + @context == :dossier + end + private def pending_attachment?(attachment) diff --git a/app/components/attachment/pending_poll_component/pending_poll_component.en.yml b/app/components/attachment/pending_poll_component/pending_poll_component.en.yml index 8de79812a..e6a9110bb 100644 --- a/app/components/attachment/pending_poll_component/pending_poll_component.en.yml +++ b/app/components/attachment/pending_poll_component/pending_poll_component.en.yml @@ -1,4 +1,7 @@ --- en: reload: Reload - explanation: Scanning for viruses and processing your attachment(s) takes longer than expected. + explanation: + one: Scanning for viruses and processing your attachment takes longer than expected. + other: Scanning for viruses and processing your attachments takes longer than expected. + dossier_submittable: This does not prevent you from submitting your file if you wish. diff --git a/app/components/attachment/pending_poll_component/pending_poll_component.fr.yml b/app/components/attachment/pending_poll_component/pending_poll_component.fr.yml index 4b34083a7..25a6dc3e8 100644 --- a/app/components/attachment/pending_poll_component/pending_poll_component.fr.yml +++ b/app/components/attachment/pending_poll_component/pending_poll_component.fr.yml @@ -1,4 +1,8 @@ --- fr: reload: Recharger - explanation: L’analyse antivirus et le traitement de votre ou de vos pièces jointes prend plus de temps que prévu. + explanation: + one: L’analyse antivirus et le traitement de votre pièce jointe prend plus de temps que prévu. + other: L’analyse antivirus et le traitement de vos pièces jointes prend plus de temps que prévu. + + dossier_submittable: Cela ne vous empêche pas de déposer votre dossier si vous le souhaitez. diff --git a/app/components/attachment/pending_poll_component/pending_poll_component.html.haml b/app/components/attachment/pending_poll_component/pending_poll_component.html.haml index 665b4779e..1e3d63b1b 100644 --- a/app/components/attachment/pending_poll_component/pending_poll_component.html.haml +++ b/app/components/attachment/pending_poll_component/pending_poll_component.html.haml @@ -2,6 +2,10 @@ - if long_pending? = render Dsfr::CalloutComponent.new(title: nil) do |c| - c.with_body do - = t(".explanation") + = t(".explanation", count: attachments.count) + - c.with_bottom do = button_tag t(".reload"), type: "button", class: "fr-btn", data: { action: 'click->turbo-poll#refresh' } + + - if as_dossier? + %p.fr-callout__text.fr-mt-4w= t(".dossier_submittable") diff --git a/app/javascript/controllers/turbo_poll_controller.ts b/app/javascript/controllers/turbo_poll_controller.ts index ea88484ae..c44dc66fd 100644 --- a/app/javascript/controllers/turbo_poll_controller.ts +++ b/app/javascript/controllers/turbo_poll_controller.ts @@ -3,7 +3,8 @@ import { httpRequest } from '@utils'; import { ApplicationController } from './application_controller'; const DEFAULT_POLL_INTERVAL = 3000; -const DEFAULT_MAX_CHECKS = 5; +const DEFAULT_MAX_CHECKS = 10; +const DEFAULT_EXPONENTIAL_FACTOR = 1.2; // Periodically check the state of a URL. // @@ -65,7 +66,7 @@ export class TurboPollController extends ApplicationController { if (!state) { return this.resetState(); } - state.interval *= 1.5; + state.interval *= DEFAULT_EXPONENTIAL_FACTOR; state.checks += 1; if (state.checks <= this.maxChecksValue) { return state; diff --git a/spec/components/attachment/pending_poll_component_spec.rb b/spec/components/attachment/pending_poll_component_spec.rb index 90232aea5..4b8e93df9 100644 --- a/spec/components/attachment/pending_poll_component_spec.rb +++ b/spec/components/attachment/pending_poll_component_spec.rb @@ -56,4 +56,18 @@ RSpec.describe Attachment::PendingPollComponent, type: :component do end end end + + context "when it's a dossier context" do + before do + attachment.created_at = 5.minutes.ago + end + + let(:component) { + described_class.new(poll_url: "poll-here", attachment:, context: :dossier) + } + + it "indicates it's not blocker to submit" do + expect(subject).to have_content("déposer votre dossier") + end + end end From 7c5d27d8e9a254576defec6554e31ae6b8abb921 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 7 Dec 2022 23:04:50 +0100 Subject: [PATCH 2/4] feat(attachment): allow user to "view" a file without the complete download UI --- app/components/attachment/edit_component.rb | 5 ++++ .../edit_component/edit_component.html.haml | 2 +- .../attachment/edit_component_spec.rb | 27 ++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/app/components/attachment/edit_component.rb b/app/components/attachment/edit_component.rb index 28bcf969e..16a08f85a 100644 --- a/app/components/attachment/edit_component.rb +++ b/app/components/attachment/edit_component.rb @@ -119,6 +119,11 @@ class Attachment::EditComponent < ApplicationComponent def downloadable? return false unless user_can_download? + + viewable? + end + + def viewable? return false if attachment.virus_scanner_error? return false if attachment.watermark_pending? diff --git a/app/components/attachment/edit_component/edit_component.html.haml b/app/components/attachment/edit_component/edit_component.html.haml index e98f990c4..90ddb9512 100644 --- a/app/components/attachment/edit_component/edit_component.html.haml +++ b/app/components/attachment/edit_component/edit_component.html.haml @@ -9,7 +9,7 @@ - if downloadable? = render Dsfr::DownloadComponent.new(attachment:) - else - %span.attachment-filename.fr-mr-1w-= attachment.filename.to_s + %span.attachment-filename.fr-mr-1w= link_to_if(viewable?, attachment.filename.to_s, helpers.url_for(attachment.blob), title: "Ouvrir le fichier #{attachment.filename.to_s}", **helpers.external_link_attributes) = render Attachment::ProgressComponent.new(attachment: attachment) diff --git a/spec/components/attachment/edit_component_spec.rb b/spec/components/attachment/edit_component_spec.rb index 8fd077374..51c24fbaf 100644 --- a/spec/components/attachment/edit_component_spec.rb +++ b/spec/components/attachment/edit_component_spec.rb @@ -86,13 +86,19 @@ RSpec.describe Attachment::EditComponent, type: :component do context 'when user can download' do let(:kwargs) { { user_can_download: true } } - it 'renders a link to download the file' do - expect(subject).to have_link(filename) + context 'when watermarking is done' do + before do + attachment.metadata['watermark'] = true + end + + it 'renders a complete downlaod interface with details to download the file' do + expect(subject).to have_link(text: filename) + expect(subject).to have_text(/PNG.+\d+ octets/) + end end context 'when watermark is pending' do let(:champ) { create(:champ_titre_identite) } - let(:kwargs) { { user_can_download: true } } it 'displays the filename, but doesn’t allow to download the file' do expect(attachment.watermark_pending?).to be_truthy @@ -104,6 +110,21 @@ RSpec.describe Attachment::EditComponent, type: :component do end end + context 'when user cannot download' do + let(:kwargs) { { user_can_download: false } } + + context 'when watermarking is done' do + before do + attachment.metadata['watermark'] = true + end + + it 'renders a simple link to view file' do + expect(subject).to have_link(text: filename) + expect(subject).not_to have_text(/PNG.+\d+ octets/) + end + end + end + context 'with non nominal or final antivirus status' do before do champ.piece_justificative_file[0].blob.update(metadata: attachment.blob.metadata.merge(virus_scan_result: virus_scan_result)) From 48243638794e010fa6ea2a760a039d978751246d Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Thu, 8 Dec 2022 00:15:05 +0100 Subject: [PATCH 3/4] refactor(attachment): rename user_can_download -> explicit view_as - link: shows a simple link to open attachment - download: shows complete DSFR download UI --- app/components/attachment/edit_component.rb | 12 ++++++------ app/components/attachment/multiple_component.rb | 7 +++---- .../multiple_component.html.haml | 4 ++-- .../piece_justificative_component.rb | 15 +++++++++++++++ .../piece_justificative_component.html.haml | 5 +---- .../types_de_champ_editor/champ_component.rb | 2 +- app/controllers/attachments_controller.rb | 2 +- .../procedures/_informations.html.haml | 6 +++--- app/views/attachments/show.turbo_stream.haml | 2 +- app/views/experts/avis/instruction.html.haml | 2 +- app/views/root/patron.html.haml | 10 +++++----- spec/components/attachment/edit_component_spec.rb | 8 ++++---- 12 files changed, 43 insertions(+), 32 deletions(-) diff --git a/app/components/attachment/edit_component.rb b/app/components/attachment/edit_component.rb index 16a08f85a..7abb27f93 100644 --- a/app/components/attachment/edit_component.rb +++ b/app/components/attachment/edit_component.rb @@ -2,8 +2,6 @@ class Attachment::EditComponent < ApplicationComponent attr_reader :champ attr_reader :attachment - attr_reader :user_can_download - alias user_can_download? user_can_download attr_reader :user_can_destroy alias user_can_destroy? user_can_destroy attr_reader :as_multiple @@ -11,14 +9,14 @@ class Attachment::EditComponent < ApplicationComponent EXTENSIONS_ORDER = ['jpeg', 'png', 'pdf', 'zip'].freeze - def initialize(champ: nil, auto_attach_url: nil, attached_file:, direct_upload: true, index: 0, as_multiple: false, user_can_download: false, user_can_destroy: true, **kwargs) + def initialize(champ: nil, auto_attach_url: nil, attached_file:, direct_upload: true, index: 0, as_multiple: false, view_as: :link, user_can_destroy: true, **kwargs) @as_multiple = as_multiple @attached_file = attached_file @auto_attach_url = auto_attach_url @champ = champ @direct_upload = direct_upload @index = index - @user_can_download = user_can_download + @view_as = view_as @user_can_destroy = user_can_destroy # attachment passed by kwarg because we don't want a default (nil) value. @@ -80,7 +78,7 @@ class Attachment::EditComponent < ApplicationComponent if champ.present? auto_attach_url else - attachment_path(user_can_edit: true, user_can_download: @user_can_download, auto_attach_url: @auto_attach_url) + attachment_path(user_can_edit: true, view_as: @view_as, auto_attach_url: @auto_attach_url) end end @@ -118,7 +116,7 @@ class Attachment::EditComponent < ApplicationComponent end def downloadable? - return false unless user_can_download? + return false unless @view_as == :download viewable? end @@ -206,6 +204,8 @@ class Attachment::EditComponent < ApplicationComponent def verify_initialization!(kwargs) fail ArgumentError, "Unknown kwarg #{kwargs.keys.join(', ')}" unless kwargs.empty? + + fail ArgumentError, "Invalid view_as:#{@view_as}, must be :download or :link" if [:download, :link].exclude?(@view_as) end def track_issue_with_missing_validators diff --git a/app/components/attachment/multiple_component.rb b/app/components/attachment/multiple_component.rb index f13b40317..c0229bf90 100644 --- a/app/components/attachment/multiple_component.rb +++ b/app/components/attachment/multiple_component.rb @@ -9,18 +9,17 @@ class Attachment::MultipleComponent < ApplicationComponent attr_reader :champ attr_reader :form_object_name attr_reader :max + attr_reader :view_as attr_reader :user_can_destroy alias user_can_destroy? user_can_destroy - attr_reader :user_can_download - alias user_can_download? user_can_download delegate :count, :empty?, to: :attachments, prefix: true - def initialize(champ:, attached_file:, form_object_name: nil, user_can_download: false, user_can_destroy: true, max: nil) + def initialize(champ:, attached_file:, form_object_name: nil, view_as: :link, user_can_destroy: true, max: nil) @champ = champ @attached_file = attached_file @form_object_name = form_object_name - @user_can_download = user_can_download + @view_as = view_as @user_can_destroy = user_can_destroy @max = max || DEFAULT_MAX_ATTACHMENTS diff --git a/app/components/attachment/multiple_component/multiple_component.html.haml b/app/components/attachment/multiple_component/multiple_component.html.haml index 05aec6ada..b7a9036e8 100644 --- a/app/components/attachment/multiple_component/multiple_component.html.haml +++ b/app/components/attachment/multiple_component/multiple_component.html.haml @@ -1,10 +1,10 @@ -.fr-mb-4w.attachment-multiple{ class: class_names("fr-downloads-group": user_can_download?, "destroyable": user_can_destroy?) } +.fr-mb-4w.attachment-multiple{ class: class_names("fr-downloads-group": view_as == :download, "destroyable": user_can_destroy?) } = template %ul - each_attachment do |attachment, index| %li{ id: dom_id(attachment) } - = render Attachment::EditComponent.new(champ:, attached_file:, attachment:, index:, as_multiple: true, user_can_destroy:, user_can_download:, form_object_name:) + = render Attachment::EditComponent.new(champ:, attached_file:, attachment:, index:, as_multiple: true, view_as:, user_can_destroy:, form_object_name:) %div{ id: empty_component_id, class: class_names("hidden": !can_attach_next?) } = render Attachment::EditComponent.new(champ:, attached_file:, attachment: nil, index: attachments_count, user_can_destroy:, form_object_name:) diff --git a/app/components/editable_champ/piece_justificative_component.rb b/app/components/editable_champ/piece_justificative_component.rb index fb6469fea..9a14d389f 100644 --- a/app/components/editable_champ/piece_justificative_component.rb +++ b/app/components/editable_champ/piece_justificative_component.rb @@ -1,2 +1,17 @@ class EditableChamp::PieceJustificativeComponent < EditableChamp::EditableChampBaseComponent + def view_as + if @champ.dossier.brouillon? + :link + else + :download + end + end + + def user_can_destroy? + !@champ.mandatory? || @champ.dossier.brouillon? + end + + def max + [true, nil].include?(@champ.procedure&.piece_justificative_multiple?) ? Attachment::MultipleComponent::DEFAULT_MAX_ATTACHMENTS : 1 + end end diff --git a/app/components/editable_champ/piece_justificative_component/piece_justificative_component.html.haml b/app/components/editable_champ/piece_justificative_component/piece_justificative_component.html.haml index d1e146e10..4d549cb22 100644 --- a/app/components/editable_champ/piece_justificative_component/piece_justificative_component.html.haml +++ b/app/components/editable_champ/piece_justificative_component/piece_justificative_component.html.haml @@ -1,7 +1,4 @@ -- user_can_destroy = !@champ.mandatory? || @champ.dossier.brouillon? -- user_can_download = !@champ.dossier.brouillon? -- max = [true, nil].include?(@champ.procedure&.piece_justificative_multiple?) ? Attachment::MultipleComponent::DEFAULT_MAX_ATTACHMENTS : 1 -= render Attachment::MultipleComponent.new(champ: @champ, attached_file: @champ.piece_justificative_file, form_object_name: @form.object_name, user_can_destroy:, user_can_download:, max:) do |c| += render Attachment::MultipleComponent.new(champ: @champ, attached_file: @champ.piece_justificative_file, form_object_name: @form.object_name, view_as:, user_can_destroy: user_can_destroy?, max:) do |c| - if @champ.type_de_champ.piece_justificative_template&.attached? - c.with_template do = render partial: "shared/piece_justificative_template", locals: { champ: @champ } diff --git a/app/components/types_de_champ_editor/champ_component.rb b/app/components/types_de_champ_editor/champ_component.rb index ccfb2289f..856d0d06a 100644 --- a/app/components/types_de_champ_editor/champ_component.rb +++ b/app/components/types_de_champ_editor/champ_component.rb @@ -77,7 +77,7 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent { attached_file: type_de_champ.piece_justificative_template, auto_attach_url: helpers.auto_attach_url(type_de_champ), - user_can_download: true + view_as: :download } end diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index d5477c2cf..ee5d20d79 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -6,7 +6,7 @@ class AttachmentsController < ApplicationController @attachment = @blob.attachments.find(params[:id]) @user_can_edit = cast_bool(params[:user_can_edit]) - @user_can_download = cast_bool(params[:user_can_download]) + @view_as = params[:view_as]&.to_sym @auto_attach_url = params[:auto_attach_url] respond_to do |format| diff --git a/app/views/administrateurs/procedures/_informations.html.haml b/app/views/administrateurs/procedures/_informations.html.haml index e0990f3e2..2991dc649 100644 --- a/app/views/administrateurs/procedures/_informations.html.haml +++ b/app/views/administrateurs/procedures/_informations.html.haml @@ -14,7 +14,7 @@ = f.text_area :description, rows: '6', placeholder: 'Description de la démarche, destinataires, etc. ', class: 'form-control' %h3.header-subsection Logo de la démarche -= render Attachment::EditComponent.new(attached_file: @procedure.logo, user_can_download: true) += render Attachment::EditComponent.new(attached_file: @procedure.logo, view_as: :link) %h3.header-subsection Conservation des données = f.label :duree_conservation_dossiers_dans_ds do @@ -52,7 +52,7 @@ = f.text_field :cadre_juridique, class: 'form-control', placeholder: 'https://www.legifrance.gouv.fr/' = f.label :deliberation, 'Importer le texte' -= render Attachment::EditComponent.new(attached_file: @procedure.deliberation, user_can_download: true) += render Attachment::EditComponent.new(attached_file: @procedure.deliberation, view_as: :download) %h3.header-subsection RGPD @@ -81,7 +81,7 @@ = f.label :notice, 'Notice' %p.notice Formats acceptés : .doc, .odt, .pdf, .ppt, .pptx -= render Attachment::EditComponent.new(attached_file: @procedure.notice, user_can_download: true) += render Attachment::EditComponent.new(attached_file: @procedure.notice, view_as: :download) - if !@procedure.locked? %h3.header-subsection À qui s’adresse ma démarche ? diff --git a/app/views/attachments/show.turbo_stream.haml b/app/views/attachments/show.turbo_stream.haml index fd0b23580..440cf52b2 100644 --- a/app/views/attachments/show.turbo_stream.haml +++ b/app/views/attachments/show.turbo_stream.haml @@ -1,5 +1,5 @@ = turbo_stream.replace dom_id(@attachment, :edit) do - if @user_can_edit - = render Attachment::EditComponent.new(attachment: @attachment, attached_file: @attachment.record.public_send(@attachment.name), auto_attach_url: @auto_attach_url, user_can_download: @user_can_download) + = render Attachment::EditComponent.new(attachment: @attachment, attached_file: @attachment.record.public_send(@attachment.name), auto_attach_url: @auto_attach_url, view_as: @view_as) - else = render Attachment::ShowComponent.new(attachment: @attachment) diff --git a/app/views/experts/avis/instruction.html.haml b/app/views/experts/avis/instruction.html.haml index 914587395..0075ee54e 100644 --- a/app/views/experts/avis/instruction.html.haml +++ b/app/views/experts/avis/instruction.html.haml @@ -17,7 +17,7 @@ = form_for @avis, url: expert_avis_path(@avis.procedure, @avis), html: { class: 'form', data: { controller: 'persisted-form', persisted_form_key_value: dom_id(@avis) }, multipart: true } do |f| = f.text_area :answer, rows: 3, placeholder: 'Votre avis', required: true - = render Attachment::EditComponent.new(attached_file: @avis.piece_justificative_file, user_can_download: true) + = render Attachment::EditComponent.new(attached_file: @avis.piece_justificative_file, view_as: :download) .flex.justify-between.align-baseline %p.confidentiel.flex diff --git a/app/views/root/patron.html.haml b/app/views/root/patron.html.haml index d0c4fe1b7..a7ffeae8b 100644 --- a/app/views/root/patron.html.haml +++ b/app/views/root/patron.html.haml @@ -386,15 +386,15 @@ %h3.fr-mt-4w New attachment on TypeDeChamp = render Attachment::EditComponent.new(auto_attach_url: "/some-auto-attach-path", attached_file: tdc.piece_justificative_template, attachment: nil) - %h3.fr-mt-4w Existing attachment on TypeDeChamp + %h3.fr-mt-4w Existing attachment on TypeDeChamp, view as link = render Attachment::EditComponent.new(auto_attach_url: "/some-auto-attach-path", attached_file: tdc.piece_justificative_template, attachment: attachment.reload) - %h3.fr-mt-4w Existing attachment on TypeDeChamp can download - = render Attachment::EditComponent.new(auto_attach_url: "/some-auto-attach-path", attached_file: tdc.piece_justificative_template, attachment: attachment.reload, user_can_download: true) + %h3.fr-mt-4w Existing attachment on TypeDeChamp view as download + = render Attachment::EditComponent.new(auto_attach_url: "/some-auto-attach-path", attached_file: tdc.piece_justificative_template, attachment: attachment.reload, view_as: :download) %h3.fr-mt-4w New attachment on generic object = render Attachment::EditComponent.new(attached_file: avis.introduction_file) - %h3.fr-mt-4w Existing attachment on generic object, can download - = render Attachment::EditComponent.new(attached_file: avis.introduction_file, attachment: attachment.reload, user_can_download: true) + %h3.fr-mt-4w Existing attachment on generic object, view as download + = render Attachment::EditComponent.new(attached_file: avis.introduction_file, attachment: attachment.reload, view_as: :download) diff --git a/spec/components/attachment/edit_component_spec.rb b/spec/components/attachment/edit_component_spec.rb index 51c24fbaf..2c1c48264 100644 --- a/spec/components/attachment/edit_component_spec.rb +++ b/spec/components/attachment/edit_component_spec.rb @@ -83,8 +83,8 @@ RSpec.describe Attachment::EditComponent, type: :component do end end - context 'when user can download' do - let(:kwargs) { { user_can_download: true } } + context 'when view as download' do + let(:kwargs) { { view_as: :download } } context 'when watermarking is done' do before do @@ -110,8 +110,8 @@ RSpec.describe Attachment::EditComponent, type: :component do end end - context 'when user cannot download' do - let(:kwargs) { { user_can_download: false } } + context 'when view as link' do + let(:kwargs) { { view_as: :link } } context 'when watermarking is done' do before do From c93eba38eaad1836d1f3fa02c8f081fa63a57f6f Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Thu, 8 Dec 2022 13:04:44 +0100 Subject: [PATCH 4/4] chore(turbo-poll): convert to setInterval, turbo morph compatible. Interval is not exponential anymore, so increase max checks. --- .../controllers/turbo_poll_controller.ts | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/app/javascript/controllers/turbo_poll_controller.ts b/app/javascript/controllers/turbo_poll_controller.ts index c44dc66fd..29d2afac9 100644 --- a/app/javascript/controllers/turbo_poll_controller.ts +++ b/app/javascript/controllers/turbo_poll_controller.ts @@ -3,8 +3,7 @@ import { httpRequest } from '@utils'; import { ApplicationController } from './application_controller'; const DEFAULT_POLL_INTERVAL = 3000; -const DEFAULT_MAX_CHECKS = 10; -const DEFAULT_EXPONENTIAL_FACTOR = 1.2; +const DEFAULT_MAX_CHECKS = 20; // Periodically check the state of a URL. // @@ -27,10 +26,7 @@ export class TurboPollController extends ApplicationController { #abortController?: AbortController; connect(): void { - const state = this.nextState(); - if (state) { - this.schedule(state); - } + this.schedule(); } disconnect(): void { @@ -38,7 +34,6 @@ export class TurboPollController extends ApplicationController { } refresh() { - this.cancel(); this.#abortController = new AbortController(); httpRequest(this.urlValue, { signal: this.#abortController.signal }) @@ -46,15 +41,21 @@ export class TurboPollController extends ApplicationController { .catch(() => null); } - private schedule(state: PollState): void { + private schedule(): void { this.cancel(); - this.#timer = setTimeout(() => { - this.refresh(); - }, state.interval); + this.#timer = setInterval(() => { + const nextState = this.nextState(); + + if (!nextState) { + this.cancel(); + } else { + this.refresh(); + } + }, this.intervalValue); } private cancel(): void { - clearTimeout(this.#timer); + clearInterval(this.#timer); this.#abortController?.abort(); this.#abortController = window.AbortController ? new AbortController() @@ -63,10 +64,11 @@ export class TurboPollController extends ApplicationController { private nextState(): PollState | false { const state = pollers.get(this.urlValue); + if (!state) { return this.resetState(); } - state.interval *= DEFAULT_EXPONENTIAL_FACTOR; + state.checks += 1; if (state.checks <= this.maxChecksValue) { return state; @@ -87,7 +89,6 @@ export class TurboPollController extends ApplicationController { } type PollState = { - interval: number; checks: number; };