fix(settings): keep extra SMS variables after save
Avoid Vue's reserved slot field on the variable dropdown so newly added rows survive save.
This commit is contained in:
@@ -95,7 +95,7 @@
|
||||
v-model="variable.slot"
|
||||
:options="getAvailableSlots(template.key)"
|
||||
optionLabel="label"
|
||||
optionValue="slot"
|
||||
optionValue="value"
|
||||
placeholder="انتخاب مقدار داده"
|
||||
class="w-full text-sm"
|
||||
@change="onSlotChange(template.key, vIdx)"
|
||||
@@ -283,30 +283,30 @@ const importResult = ref(null);
|
||||
|
||||
const TEMPLATE_SLOT_DEFS = {
|
||||
accountCreated: [
|
||||
{ slot: 'username', label: 'نام کاربری', defaultName: 'user' },
|
||||
{ slot: 'password', label: 'رمز عبور', defaultName: 'password' },
|
||||
{ slot: 'fullName', label: 'نام و نام خانوادگی', defaultName: 'name' },
|
||||
{ slot: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||
{ value: 'username', label: 'نام کاربری', defaultName: 'user' },
|
||||
{ value: 'password', label: 'رمز عبور', defaultName: 'password' },
|
||||
{ value: 'fullName', label: 'نام و نام خانوادگی', defaultName: 'name' },
|
||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||
],
|
||||
classRegistered: [
|
||||
{ slot: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||
{ slot: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||
{ slot: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||
{ slot: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||
],
|
||||
classReminder: [
|
||||
{ slot: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||
{ slot: 'time', label: 'ساعت برگزاری', defaultName: 'time' },
|
||||
{ slot: 'place', label: 'مکان برگزاری', defaultName: 'place' },
|
||||
{ slot: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||
{ slot: 'fullName', label: 'نام کاربر', defaultName: 'fullName' },
|
||||
{ slot: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||
{ value: 'time', label: 'ساعت برگزاری', defaultName: 'time' },
|
||||
{ value: 'place', label: 'مکان برگزاری', defaultName: 'place' },
|
||||
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||
{ value: 'fullName', label: 'نام کاربر', defaultName: 'fullName' },
|
||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||
],
|
||||
invoiceCreated: [
|
||||
{ slot: 'amount', label: 'مبلغ صورتحساب (تومان)', defaultName: 'PAYMENT_PRICE' },
|
||||
{ slot: 'fullName', label: 'نام کارآموز', defaultName: 'FULLNAME' },
|
||||
{ slot: 'course', label: 'نام دوره / کلاس', defaultName: 'COURSE' },
|
||||
{ slot: 'phoneNumber', label: 'شماره همراه', defaultName: 'MOBILE' }
|
||||
{ value: 'amount', label: 'مبلغ صورتحساب (تومان)', defaultName: 'PAYMENT_PRICE' },
|
||||
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'FULLNAME' },
|
||||
{ value: 'course', label: 'نام دوره / کلاس', defaultName: 'COURSE' },
|
||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'MOBILE' }
|
||||
]
|
||||
};
|
||||
|
||||
@@ -316,7 +316,7 @@ const getAvailableSlots = (templateKey) => {
|
||||
|
||||
const getSlotDefaultName = (templateKey, slotKey) => {
|
||||
const slots = getAvailableSlots(templateKey);
|
||||
const found = slots.find((s) => s.slot === slotKey);
|
||||
const found = slots.find((s) => s.value === slotKey);
|
||||
return found?.defaultName || '';
|
||||
};
|
||||
|
||||
@@ -341,15 +341,18 @@ const onSlotChange = (templateKey, vIdx) => {
|
||||
const addVariable = (templateKey) => {
|
||||
const form = templateForm.value[templateKey];
|
||||
if (!form) return;
|
||||
if (!Array.isArray(form.variables)) {
|
||||
form.variables = [];
|
||||
}
|
||||
const availableSlots = getAvailableSlots(templateKey);
|
||||
|
||||
const existingSlots = new Set((form.variables || []).map((v) => v.slot));
|
||||
const unusedSlot = availableSlots.find((s) => !existingSlots.has(s.slot));
|
||||
const selectedSlot = unusedSlot || availableSlots[0] || { slot: 'amount', defaultName: 'PAYMENT_PRICE' };
|
||||
const existingSlots = new Set(form.variables.map((v) => v.slot));
|
||||
const unusedSlot = availableSlots.find((s) => !existingSlots.has(s.value));
|
||||
const selectedSlot = unusedSlot || availableSlots[0] || { value: 'amount', defaultName: 'PAYMENT_PRICE' };
|
||||
|
||||
form.variables.push({
|
||||
id: nextVarId(),
|
||||
slot: selectedSlot.slot,
|
||||
slot: selectedSlot.value,
|
||||
name: selectedSlot.defaultName || ''
|
||||
});
|
||||
};
|
||||
@@ -448,16 +451,19 @@ const confirmImport = () => {
|
||||
const emptyFormEntry = (template) => {
|
||||
const slots = getAvailableSlots(template?.key);
|
||||
let vars = [];
|
||||
if (Array.isArray(template?.variables) && template.variables.length > 0) {
|
||||
vars = template.variables.map((variable) => ({
|
||||
const incomingVars = Array.isArray(template?.variables)
|
||||
? template.variables
|
||||
: Object.values(template?.variables || {});
|
||||
if (incomingVars.length > 0) {
|
||||
vars = incomingVars.map((variable) => ({
|
||||
id: nextVarId(),
|
||||
slot: variable.slot || slots[0]?.slot || 'amount',
|
||||
slot: variable.slot || slots[0]?.value || 'amount',
|
||||
name: variable.name || getSlotDefaultName(template?.key, variable.slot) || ''
|
||||
}));
|
||||
} else if (!template?.variables) {
|
||||
vars = slots.map((s) => ({
|
||||
id: nextVarId(),
|
||||
slot: s.slot,
|
||||
slot: s.value,
|
||||
name: s.defaultName
|
||||
}));
|
||||
}
|
||||
@@ -497,9 +503,12 @@ const saveSmsTemplates = async () => {
|
||||
const smsTemplatesPayload = {};
|
||||
smsTemplates.value.forEach((template) => {
|
||||
const entry = templateForm.value[template.key] || emptyFormEntry(template);
|
||||
const rawVariables = Array.isArray(entry.variables)
|
||||
? entry.variables
|
||||
: Object.values(entry.variables || {});
|
||||
smsTemplatesPayload[template.key] = {
|
||||
templateId: String(entry.templateId || '').trim(),
|
||||
variables: (entry.variables || [])
|
||||
variables: rawVariables
|
||||
.filter((v) => v && v.slot)
|
||||
.map((v) => {
|
||||
const raw = String(v.name || '').trim().replace(/^#+|#+$/g, '');
|
||||
|
||||
Reference in New Issue
Block a user