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
@scheduled_message.assign_attributes(scheduled_message_params)
@scheduled_message.attachment.purge if params[:remove_attachment].present? && @scheduled_message.attachment.attached?
@scheduled_message.save!
dispatch_event(SCHEDULED_MESSAGE_UPDATED, scheduled_message: @scheduled_message)
end

View File

@ -7,6 +7,7 @@ export const buildScheduledMessagePayload = ({
scheduledAt,
templateParams,
attachment,
removeAttachment,
} = {}) => {
if (!attachment) {
return {
@ -14,6 +15,7 @@ export const buildScheduledMessagePayload = ({
status,
scheduled_at: scheduledAt,
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
const localShowModal = ref(false);
const removedExistingAttachment = ref(false);
const resetForm = () => {
messageContent.value = '';
scheduledDateTime.value = null;
attachments.value = [];
existingAttachment.value = null;
removedExistingAttachment.value = false;
templateParams.value = null;
contentError.value = false;
dateTimeError.value = '';
@ -162,9 +165,30 @@ const hasTemplate = computed(
);
const hasExistingAttachment = computed(() => !!existingAttachment.value);
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(() => {
return templateParams.value?.name || templateParams.value?.id || null;
});
@ -258,6 +282,16 @@ const onAttachmentsChange = value => {
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 = () => {
if (!attachments.value.length) return null;
const attachment = attachments.value[0];
@ -326,6 +360,8 @@ const buildPayload = status => {
const attachmentPayload = resolveAttachmentPayload();
if (attachmentPayload) {
payload.attachment = attachmentPayload;
} else if (removedExistingAttachment.value) {
payload.removeAttachment = true;
}
return payload;
@ -532,21 +568,11 @@ watch(
@click="clearTemplate"
/>
</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
v-if="attachments.length"
v-if="displayAttachments.length"
class="!p-0"
:attachments="attachments"
@update:attachments="onAttachmentsChange"
:attachments="displayAttachments"
@update:attachments="onDisplayAttachmentsChange"
/>
</div>
</div>