fix(schedule): enhance attachment handling in scheduled message modal (#239)

* fix(schedule): enhance attachment handling in scheduled message modal

* fix(schedule): enable attachment removal in scheduled message updates
This commit is contained in:
Cayo P. R. Oliveira 2026-03-19 22:45:21 -03:00 committed by GitHub
parent a06354c6b2
commit 8ffdc16faf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 14 deletions

View File

@ -22,6 +22,7 @@ class Api::V1::Accounts::Conversations::ScheduledMessagesController < Api::V1::A
def update def update
@scheduled_message.assign_attributes(scheduled_message_params) @scheduled_message.assign_attributes(scheduled_message_params)
@scheduled_message.attachment.purge if params[:remove_attachment].present? && @scheduled_message.attachment.attached?
@scheduled_message.save! @scheduled_message.save!
dispatch_event(SCHEDULED_MESSAGE_UPDATED, scheduled_message: @scheduled_message) dispatch_event(SCHEDULED_MESSAGE_UPDATED, scheduled_message: @scheduled_message)
end end

View File

@ -7,6 +7,7 @@ export const buildScheduledMessagePayload = ({
scheduledAt, scheduledAt,
templateParams, templateParams,
attachment, attachment,
removeAttachment,
} = {}) => { } = {}) => {
if (!attachment) { if (!attachment) {
return { return {
@ -14,6 +15,7 @@ export const buildScheduledMessagePayload = ({
status, status,
scheduled_at: scheduledAt, scheduled_at: scheduledAt,
template_params: templateParams, template_params: templateParams,
remove_attachment: removeAttachment || undefined,
}; };
} }

View File

@ -87,11 +87,14 @@ const originalHasAttachment = ref(false);
// NOTE: Local ref to control modal visibility, prevents auto-close when unsaved changes exist // NOTE: Local ref to control modal visibility, prevents auto-close when unsaved changes exist
const localShowModal = ref(false); const localShowModal = ref(false);
const removedExistingAttachment = ref(false);
const resetForm = () => { const resetForm = () => {
messageContent.value = ''; messageContent.value = '';
scheduledDateTime.value = null; scheduledDateTime.value = null;
attachments.value = []; attachments.value = [];
existingAttachment.value = null; existingAttachment.value = null;
removedExistingAttachment.value = false;
templateParams.value = null; templateParams.value = null;
contentError.value = false; contentError.value = false;
dateTimeError.value = ''; dateTimeError.value = '';
@ -162,9 +165,30 @@ const hasTemplate = computed(
); );
const hasExistingAttachment = computed(() => !!existingAttachment.value); const hasExistingAttachment = computed(() => !!existingAttachment.value);
const showAttachmentUpload = computed( const showAttachmentUpload = computed(
() => !hasNewAttachment.value && !hasTemplate.value () =>
!hasNewAttachment.value &&
!hasExistingAttachment.value &&
!hasTemplate.value
); );
const displayAttachments = computed(() => {
if (attachments.value.length) return attachments.value;
if (existingAttachment.value) {
return [
{
id: existingAttachment.value.id,
thumb: existingAttachment.value.file_url,
resource: {
id: existingAttachment.value.id,
content_type: existingAttachment.value.file_type,
filename: existingAttachment.value.filename,
},
},
];
}
return [];
});
const templateName = computed(() => { const templateName = computed(() => {
return templateParams.value?.name || templateParams.value?.id || null; return templateParams.value?.name || templateParams.value?.id || null;
}); });
@ -258,6 +282,16 @@ const onAttachmentsChange = value => {
attachments.value = value.slice(0, 1); attachments.value = value.slice(0, 1);
}; };
const onDisplayAttachmentsChange = value => {
if (value.length === 0) {
if (existingAttachment.value) removedExistingAttachment.value = true;
attachments.value = [];
existingAttachment.value = null;
} else {
onAttachmentsChange(value);
}
};
const resolveAttachmentPayload = () => { const resolveAttachmentPayload = () => {
if (!attachments.value.length) return null; if (!attachments.value.length) return null;
const attachment = attachments.value[0]; const attachment = attachments.value[0];
@ -326,6 +360,8 @@ const buildPayload = status => {
const attachmentPayload = resolveAttachmentPayload(); const attachmentPayload = resolveAttachmentPayload();
if (attachmentPayload) { if (attachmentPayload) {
payload.attachment = attachmentPayload; payload.attachment = attachmentPayload;
} else if (removedExistingAttachment.value) {
payload.removeAttachment = true;
} }
return payload; return payload;
@ -532,21 +568,11 @@ watch(
@click="clearTemplate" @click="clearTemplate"
/> />
</div> </div>
<span
v-if="existingAttachment && !attachments.length"
class="text-xs text-n-slate-11"
>
{{
t('SCHEDULED_MESSAGES.MODAL.ATTACHMENT_CURRENT', {
filename: existingAttachment.filename,
})
}}
</span>
<AttachmentPreviews <AttachmentPreviews
v-if="attachments.length" v-if="displayAttachments.length"
class="!p-0" class="!p-0"
:attachments="attachments" :attachments="displayAttachments"
@update:attachments="onAttachmentsChange" @update:attachments="onDisplayAttachmentsChange"
/> />
</div> </div>
</div> </div>