fix(settings): fix Vue reactivity and form keying on SMS templates save

This commit is contained in:
2026-08-15 22:03:29 +03:30
parent 28b75664ab
commit 9fbaf3c7fe
+15 -14
View File
@@ -86,7 +86,7 @@
<div v-else class="flex flex-column gap-2">
<div
v-for="(variable, vIdx) in templateForm[template.key].variables"
:key="vIdx"
:key="variable.id || vIdx"
class="flex flex-column sm:flex-row sm:align-items-center gap-2 p-2 border-round surface-card border-1 border-color"
>
<div class="flex align-items-center gap-2 sm:w-14rem flex-shrink-0">
@@ -248,7 +248,7 @@
</template>
<script setup>
import { computed, onMounted, reactive, ref } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { useConfirm } from 'primevue/useconfirm';
import Button from 'primevue/button';
import InputText from 'primevue/inputtext';
@@ -265,7 +265,7 @@ const { showSuccess, showError } = useToast();
const isSettingsLoading = ref(true);
const isSavingSettings = ref(false);
const smsTemplates = ref([]);
const templateForm = reactive({});
const templateForm = ref({});
const isStatusLoading = ref(true);
const isSeeding = ref(false);
@@ -291,7 +291,7 @@ const getSlotDefaultName = (template, slotKey) => {
};
const onSlotChange = (templateKey, vIdx) => {
const form = templateForm[templateKey];
const form = templateForm.value[templateKey];
if (!form || !form.variables[vIdx]) return;
const template = smsTemplates.value.find((t) => t.key === templateKey);
const currentVar = form.variables[vIdx];
@@ -301,7 +301,7 @@ const onSlotChange = (templateKey, vIdx) => {
};
const addVariable = (templateKey) => {
const form = templateForm[templateKey];
const form = templateForm.value[templateKey];
if (!form) return;
const template = smsTemplates.value.find((t) => t.key === templateKey);
const availableSlots = template?.availableSlots || [];
@@ -311,20 +311,21 @@ const addVariable = (templateKey) => {
const selectedSlot = unusedSlot || availableSlots[0] || { slot: 'param', defaultName: 'param' };
form.variables.push({
id: `var_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`,
slot: selectedSlot.slot,
name: selectedSlot.defaultName || ''
});
};
const removeVariable = (templateKey, index) => {
const form = templateForm[templateKey];
const form = templateForm.value[templateKey];
if (form && form.variables) {
form.variables.splice(index, 1);
}
};
const applyStatus = (payload) => {
const status = payload?.data || payload || {};
const status = payload?.data?.data || payload?.data || payload || {};
isLocked.value = Boolean(status.locked);
lockedAt.value = status.lockedAt || null;
};
@@ -411,6 +412,7 @@ const emptyFormEntry = (template) => ({
templateId: template?.templateId || '',
variables: Array.isArray(template?.variables)
? template.variables.map((variable) => ({
id: `var_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`,
slot: variable.slot,
name: variable.name || ''
}))
@@ -418,15 +420,14 @@ const emptyFormEntry = (template) => ({
});
const applySmsTemplates = (payload) => {
const data = payload?.data || payload || {};
const data = payload?.data?.data || payload?.data || payload || {};
const templates = Array.isArray(data.smsTemplates) ? data.smsTemplates : [];
smsTemplates.value = templates;
Object.keys(templateForm).forEach((key) => {
delete templateForm[key];
});
const newForm = {};
templates.forEach((template) => {
templateForm[template.key] = emptyFormEntry(template);
newForm[template.key] = emptyFormEntry(template);
});
templateForm.value = newForm;
};
const loadSettings = async () => {
@@ -446,7 +447,7 @@ const saveSmsTemplates = async () => {
try {
const smsTemplatesPayload = {};
smsTemplates.value.forEach((template) => {
const entry = templateForm[template.key] || emptyFormEntry(template);
const entry = templateForm.value[template.key] || emptyFormEntry(template);
smsTemplatesPayload[template.key] = {
templateId: entry.templateId || '',
variables: (entry.variables || [])
@@ -459,7 +460,7 @@ const saveSmsTemplates = async () => {
});
const response = await settingsApi.save({ smsTemplates: smsTemplatesPayload });
applySmsTemplates(response);
showSuccess('قالب‌های پیامک ذخیره شدند.');
showSuccess('قالب‌های پیامک با موفقیت ذخیره شدند.');
} catch (err) {
showError(err);
} finally {