Merge pull request #8221 from colinux/attachments-downloadable
feat: attachments viewable after upload (dossier en brouillon)
This commit is contained in:
commit
93de4cf821
19 changed files with 138 additions and 54 deletions
|
@ -2,8 +2,6 @@
|
||||||
class Attachment::EditComponent < ApplicationComponent
|
class Attachment::EditComponent < ApplicationComponent
|
||||||
attr_reader :champ
|
attr_reader :champ
|
||||||
attr_reader :attachment
|
attr_reader :attachment
|
||||||
attr_reader :user_can_download
|
|
||||||
alias user_can_download? user_can_download
|
|
||||||
attr_reader :user_can_destroy
|
attr_reader :user_can_destroy
|
||||||
alias user_can_destroy? user_can_destroy
|
alias user_can_destroy? user_can_destroy
|
||||||
attr_reader :as_multiple
|
attr_reader :as_multiple
|
||||||
|
@ -11,14 +9,14 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
|
|
||||||
EXTENSIONS_ORDER = ['jpeg', 'png', 'pdf', 'zip'].freeze
|
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
|
@as_multiple = as_multiple
|
||||||
@attached_file = attached_file
|
@attached_file = attached_file
|
||||||
@auto_attach_url = auto_attach_url
|
@auto_attach_url = auto_attach_url
|
||||||
@champ = champ
|
@champ = champ
|
||||||
@direct_upload = direct_upload
|
@direct_upload = direct_upload
|
||||||
@index = index
|
@index = index
|
||||||
@user_can_download = user_can_download
|
@view_as = view_as
|
||||||
@user_can_destroy = user_can_destroy
|
@user_can_destroy = user_can_destroy
|
||||||
|
|
||||||
# attachment passed by kwarg because we don't want a default (nil) value.
|
# attachment passed by kwarg because we don't want a default (nil) value.
|
||||||
|
@ -80,10 +78,16 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
if champ.present?
|
if champ.present?
|
||||||
auto_attach_url
|
auto_attach_url
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def poll_context
|
||||||
|
return :dossier if champ.present?
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
def field_name
|
def field_name
|
||||||
helpers.field_name(@form_object_name || ActiveModel::Naming.param_key(@attached_file.record), attribute_name)
|
helpers.field_name(@form_object_name || ActiveModel::Naming.param_key(@attached_file.record), attribute_name)
|
||||||
end
|
end
|
||||||
|
@ -112,7 +116,12 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
end
|
end
|
||||||
|
|
||||||
def downloadable?
|
def downloadable?
|
||||||
return false unless user_can_download?
|
return false unless @view_as == :download
|
||||||
|
|
||||||
|
viewable?
|
||||||
|
end
|
||||||
|
|
||||||
|
def viewable?
|
||||||
return false if attachment.virus_scanner_error?
|
return false if attachment.virus_scanner_error?
|
||||||
return false if attachment.watermark_pending?
|
return false if attachment.watermark_pending?
|
||||||
|
|
||||||
|
@ -195,6 +204,8 @@ class Attachment::EditComponent < ApplicationComponent
|
||||||
|
|
||||||
def verify_initialization!(kwargs)
|
def verify_initialization!(kwargs)
|
||||||
fail ArgumentError, "Unknown kwarg #{kwargs.keys.join(', ')}" unless kwargs.empty?
|
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
|
end
|
||||||
|
|
||||||
def track_issue_with_missing_validators
|
def track_issue_with_missing_validators
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
- if downloadable?
|
- if downloadable?
|
||||||
= render Dsfr::DownloadComponent.new(attachment:)
|
= render Dsfr::DownloadComponent.new(attachment:)
|
||||||
- else
|
- 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)
|
= render Attachment::ProgressComponent.new(attachment: attachment)
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
= file_field(champ, field_name, **file_field_options)
|
= file_field(champ, field_name, **file_field_options)
|
||||||
|
|
||||||
- if persisted?
|
- 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
|
.fr-mt-2w
|
||||||
= render component
|
= render component
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,17 @@ class Attachment::MultipleComponent < ApplicationComponent
|
||||||
attr_reader :champ
|
attr_reader :champ
|
||||||
attr_reader :form_object_name
|
attr_reader :form_object_name
|
||||||
attr_reader :max
|
attr_reader :max
|
||||||
|
attr_reader :view_as
|
||||||
attr_reader :user_can_destroy
|
attr_reader :user_can_destroy
|
||||||
alias user_can_destroy? 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
|
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
|
@champ = champ
|
||||||
@attached_file = attached_file
|
@attached_file = attached_file
|
||||||
@form_object_name = form_object_name
|
@form_object_name = form_object_name
|
||||||
@user_can_download = user_can_download
|
@view_as = view_as
|
||||||
@user_can_destroy = user_can_destroy
|
@user_can_destroy = user_can_destroy
|
||||||
@max = max || DEFAULT_MAX_ATTACHMENTS
|
@max = max || DEFAULT_MAX_ATTACHMENTS
|
||||||
|
|
||||||
|
@ -43,4 +42,10 @@ class Attachment::MultipleComponent < ApplicationComponent
|
||||||
helpers.auto_attach_url(champ)
|
helpers.auto_attach_url(champ)
|
||||||
end
|
end
|
||||||
alias poll_url auto_attach_url
|
alias poll_url auto_attach_url
|
||||||
|
|
||||||
|
def poll_context
|
||||||
|
return :dossier if champ.present?
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
.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
|
= template
|
||||||
|
|
||||||
%ul
|
%ul
|
||||||
- each_attachment do |attachment, index|
|
- each_attachment do |attachment, index|
|
||||||
%li{ id: dom_id(attachment) }
|
%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?) }
|
%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:)
|
= 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
|
// 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)
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
class Attachment::PendingPollComponent < ApplicationComponent
|
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
|
@poll_url = poll_url
|
||||||
@attachments = if attachment.present?
|
@attachments = if attachment.present?
|
||||||
[attachment]
|
[attachment]
|
||||||
else
|
else
|
||||||
attachments
|
attachments
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@context = context
|
||||||
end
|
end
|
||||||
|
|
||||||
def render?
|
def render?
|
||||||
|
@ -14,7 +18,7 @@ class Attachment::PendingPollComponent < ApplicationComponent
|
||||||
|
|
||||||
def long_pending?
|
def long_pending?
|
||||||
@attachments.any? do
|
@attachments.any? do
|
||||||
pending_attachment?(_1) && _1.created_at < 30.seconds.ago
|
pending_attachment?(_1) && _1.created_at < 60.seconds.ago
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -25,6 +29,10 @@ class Attachment::PendingPollComponent < ApplicationComponent
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def as_dossier?
|
||||||
|
@context == :dossier
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def pending_attachment?(attachment)
|
def pending_attachment?(attachment)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
---
|
---
|
||||||
en:
|
en:
|
||||||
reload: Reload
|
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.
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
---
|
---
|
||||||
fr:
|
fr:
|
||||||
reload: Recharger
|
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.
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
- if long_pending?
|
- if long_pending?
|
||||||
= render Dsfr::CalloutComponent.new(title: nil) do |c|
|
= render Dsfr::CalloutComponent.new(title: nil) do |c|
|
||||||
- c.with_body do
|
- c.with_body do
|
||||||
= t(".explanation")
|
= t(".explanation", count: attachments.count)
|
||||||
|
|
||||||
- c.with_bottom do
|
- c.with_bottom do
|
||||||
= button_tag t(".reload"), type: "button", class: "fr-btn", data: { action: 'click->turbo-poll#refresh' }
|
= 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")
|
||||||
|
|
|
@ -1,2 +1,17 @@
|
||||||
class EditableChamp::PieceJustificativeComponent < EditableChamp::EditableChampBaseComponent
|
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
|
end
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
- user_can_destroy = !@champ.mandatory? || @champ.dossier.brouillon?
|
= 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|
|
||||||
- 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|
|
|
||||||
- if @champ.type_de_champ.piece_justificative_template&.attached?
|
- if @champ.type_de_champ.piece_justificative_template&.attached?
|
||||||
- c.with_template do
|
- c.with_template do
|
||||||
= render partial: "shared/piece_justificative_template", locals: { champ: @champ }
|
= render partial: "shared/piece_justificative_template", locals: { champ: @champ }
|
||||||
|
|
|
@ -77,7 +77,7 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent
|
||||||
{
|
{
|
||||||
attached_file: type_de_champ.piece_justificative_template,
|
attached_file: type_de_champ.piece_justificative_template,
|
||||||
auto_attach_url: helpers.auto_attach_url(type_de_champ),
|
auto_attach_url: helpers.auto_attach_url(type_de_champ),
|
||||||
user_can_download: true
|
view_as: :download
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ class AttachmentsController < ApplicationController
|
||||||
@attachment = @blob.attachments.find(params[:id])
|
@attachment = @blob.attachments.find(params[:id])
|
||||||
|
|
||||||
@user_can_edit = cast_bool(params[:user_can_edit])
|
@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]
|
@auto_attach_url = params[:auto_attach_url]
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { httpRequest } from '@utils';
|
||||||
import { ApplicationController } from './application_controller';
|
import { ApplicationController } from './application_controller';
|
||||||
|
|
||||||
const DEFAULT_POLL_INTERVAL = 3000;
|
const DEFAULT_POLL_INTERVAL = 3000;
|
||||||
const DEFAULT_MAX_CHECKS = 5;
|
const DEFAULT_MAX_CHECKS = 20;
|
||||||
|
|
||||||
// Periodically check the state of a URL.
|
// Periodically check the state of a URL.
|
||||||
//
|
//
|
||||||
|
@ -26,10 +26,7 @@ export class TurboPollController extends ApplicationController {
|
||||||
#abortController?: AbortController;
|
#abortController?: AbortController;
|
||||||
|
|
||||||
connect(): void {
|
connect(): void {
|
||||||
const state = this.nextState();
|
this.schedule();
|
||||||
if (state) {
|
|
||||||
this.schedule(state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect(): void {
|
disconnect(): void {
|
||||||
|
@ -37,7 +34,6 @@ export class TurboPollController extends ApplicationController {
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.cancel();
|
|
||||||
this.#abortController = new AbortController();
|
this.#abortController = new AbortController();
|
||||||
|
|
||||||
httpRequest(this.urlValue, { signal: this.#abortController.signal })
|
httpRequest(this.urlValue, { signal: this.#abortController.signal })
|
||||||
|
@ -45,15 +41,21 @@ export class TurboPollController extends ApplicationController {
|
||||||
.catch(() => null);
|
.catch(() => null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private schedule(state: PollState): void {
|
private schedule(): void {
|
||||||
this.cancel();
|
this.cancel();
|
||||||
this.#timer = setTimeout(() => {
|
this.#timer = setInterval(() => {
|
||||||
this.refresh();
|
const nextState = this.nextState();
|
||||||
}, state.interval);
|
|
||||||
|
if (!nextState) {
|
||||||
|
this.cancel();
|
||||||
|
} else {
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
}, this.intervalValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private cancel(): void {
|
private cancel(): void {
|
||||||
clearTimeout(this.#timer);
|
clearInterval(this.#timer);
|
||||||
this.#abortController?.abort();
|
this.#abortController?.abort();
|
||||||
this.#abortController = window.AbortController
|
this.#abortController = window.AbortController
|
||||||
? new AbortController()
|
? new AbortController()
|
||||||
|
@ -62,10 +64,11 @@ export class TurboPollController extends ApplicationController {
|
||||||
|
|
||||||
private nextState(): PollState | false {
|
private nextState(): PollState | false {
|
||||||
const state = pollers.get(this.urlValue);
|
const state = pollers.get(this.urlValue);
|
||||||
|
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return this.resetState();
|
return this.resetState();
|
||||||
}
|
}
|
||||||
state.interval *= 1.5;
|
|
||||||
state.checks += 1;
|
state.checks += 1;
|
||||||
if (state.checks <= this.maxChecksValue) {
|
if (state.checks <= this.maxChecksValue) {
|
||||||
return state;
|
return state;
|
||||||
|
@ -86,7 +89,6 @@ export class TurboPollController extends ApplicationController {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PollState = {
|
type PollState = {
|
||||||
interval: number;
|
|
||||||
checks: number;
|
checks: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
= f.text_area :description, rows: '6', placeholder: 'Description de la démarche, destinataires, etc. ', class: 'form-control'
|
= 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
|
%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
|
%h3.header-subsection Conservation des données
|
||||||
= f.label :duree_conservation_dossiers_dans_ds do
|
= 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.text_field :cadre_juridique, class: 'form-control', placeholder: 'https://www.legifrance.gouv.fr/'
|
||||||
|
|
||||||
= f.label :deliberation, 'Importer le texte'
|
= 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
|
%h3.header-subsection
|
||||||
RGPD
|
RGPD
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
= f.label :notice, 'Notice'
|
= f.label :notice, 'Notice'
|
||||||
%p.notice
|
%p.notice
|
||||||
Formats acceptés : .doc, .odt, .pdf, .ppt, .pptx
|
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?
|
- if !@procedure.locked?
|
||||||
%h3.header-subsection À qui s’adresse ma démarche ?
|
%h3.header-subsection À qui s’adresse ma démarche ?
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
= turbo_stream.replace dom_id(@attachment, :edit) do
|
= turbo_stream.replace dom_id(@attachment, :edit) do
|
||||||
- if @user_can_edit
|
- 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
|
- else
|
||||||
= render Attachment::ShowComponent.new(attachment: @attachment)
|
= render Attachment::ShowComponent.new(attachment: @attachment)
|
||||||
|
|
|
@ -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|
|
= 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
|
= 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
|
.flex.justify-between.align-baseline
|
||||||
%p.confidentiel.flex
|
%p.confidentiel.flex
|
||||||
|
|
|
@ -386,15 +386,15 @@
|
||||||
%h3.fr-mt-4w New attachment on TypeDeChamp
|
%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)
|
= 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)
|
= 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
|
%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, user_can_download: true)
|
= 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
|
%h3.fr-mt-4w New attachment on generic object
|
||||||
= render Attachment::EditComponent.new(attached_file: avis.introduction_file)
|
= render Attachment::EditComponent.new(attached_file: avis.introduction_file)
|
||||||
|
|
||||||
%h3.fr-mt-4w Existing attachment on generic object, can download
|
%h3.fr-mt-4w Existing attachment on generic object, view as download
|
||||||
= render Attachment::EditComponent.new(attached_file: avis.introduction_file, attachment: attachment.reload, user_can_download: true)
|
= render Attachment::EditComponent.new(attached_file: avis.introduction_file, attachment: attachment.reload, view_as: :download)
|
||||||
|
|
||||||
|
|
|
@ -83,16 +83,22 @@ RSpec.describe Attachment::EditComponent, type: :component do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user can download' do
|
context 'when view as download' do
|
||||||
let(:kwargs) { { user_can_download: true } }
|
let(:kwargs) { { view_as: :download } }
|
||||||
|
|
||||||
it 'renders a link to download the file' do
|
context 'when watermarking is done' do
|
||||||
expect(subject).to have_link(filename)
|
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
|
end
|
||||||
|
|
||||||
context 'when watermark is pending' do
|
context 'when watermark is pending' do
|
||||||
let(:champ) { create(:champ_titre_identite) }
|
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
|
it 'displays the filename, but doesn’t allow to download the file' do
|
||||||
expect(attachment.watermark_pending?).to be_truthy
|
expect(attachment.watermark_pending?).to be_truthy
|
||||||
|
@ -104,6 +110,21 @@ RSpec.describe Attachment::EditComponent, type: :component do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when view as link' do
|
||||||
|
let(:kwargs) { { view_as: :link } }
|
||||||
|
|
||||||
|
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
|
context 'with non nominal or final antivirus status' do
|
||||||
before do
|
before do
|
||||||
champ.piece_justificative_file[0].blob.update(metadata: attachment.blob.metadata.merge(virus_scan_result: virus_scan_result))
|
champ.piece_justificative_file[0].blob.update(metadata: attachment.blob.metadata.merge(virus_scan_result: virus_scan_result))
|
||||||
|
|
|
@ -56,4 +56,18 @@ RSpec.describe Attachment::PendingPollComponent, type: :component do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in a new issue