Fix SMS campaigns people list 400 by capping limit at 100 and searching via API.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import axios from 'axios';
|
||||
import { api } from '@/lib/api';
|
||||
import type {
|
||||
@@ -21,6 +21,7 @@ import UiIcon from '@/components/UiIcon.vue';
|
||||
import { formatJalaliNumeric, toFaDigits } from '@/lib/jalali';
|
||||
|
||||
const loading = ref(false);
|
||||
const peopleLoading = ref(false);
|
||||
const saving = ref(false);
|
||||
const error = ref('');
|
||||
const ok = ref('');
|
||||
@@ -32,17 +33,6 @@ const body = ref('');
|
||||
const queueNow = ref(true);
|
||||
const peopleQ = ref('');
|
||||
|
||||
const filteredPeople = computed(() => {
|
||||
const q = peopleQ.value.trim();
|
||||
if (!q) return people.value.slice(0, 80);
|
||||
return people.value
|
||||
.filter((p) => {
|
||||
const hay = `${p.fullName} ${p.mobile ?? ''} ${p.email ?? ''}`.toLowerCase();
|
||||
return hay.includes(q.toLowerCase());
|
||||
})
|
||||
.slice(0, 80);
|
||||
});
|
||||
|
||||
const statusLabel: Record<string, string> = {
|
||||
draft: 'پیشنویس',
|
||||
queued: 'در صف',
|
||||
@@ -51,18 +41,31 @@ const statusLabel: Record<string, string> = {
|
||||
cancelled: 'لغو شده',
|
||||
};
|
||||
|
||||
async function loadPeople(q?: string) {
|
||||
peopleLoading.value = true;
|
||||
try {
|
||||
const { data } = await api.get<PaginatedResponse<PersonDto>>('/people', {
|
||||
params: {
|
||||
page: 1,
|
||||
limit: 100,
|
||||
...(q?.trim() ? { q: q.trim() } : {}),
|
||||
},
|
||||
});
|
||||
people.value = data.items;
|
||||
} finally {
|
||||
peopleLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true;
|
||||
error.value = '';
|
||||
try {
|
||||
const [campRes, peopleRes] = await Promise.all([
|
||||
const [campRes] = await Promise.all([
|
||||
api.get<SmsCampaignListResponse>('/sms-campaigns'),
|
||||
api.get<PaginatedResponse<PersonDto>>('/people', {
|
||||
params: { page: 1, limit: 200 },
|
||||
}),
|
||||
loadPeople(peopleQ.value),
|
||||
]);
|
||||
campaigns.value = campRes.data.items;
|
||||
people.value = peopleRes.data.items;
|
||||
} catch (e) {
|
||||
if (axios.isAxiosError(e) && e.response?.status === 403) {
|
||||
error.value = 'ماژول پیامک گروهی برای این محیط فعال نیست.';
|
||||
@@ -74,6 +77,16 @@ async function load() {
|
||||
}
|
||||
}
|
||||
|
||||
let peopleSearchTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
watch(peopleQ, (q) => {
|
||||
if (peopleSearchTimer) clearTimeout(peopleSearchTimer);
|
||||
peopleSearchTimer = setTimeout(() => {
|
||||
void loadPeople(q).catch(() => {
|
||||
error.value = 'جستجوی مخاطب ناموفق بود.';
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
||||
function togglePerson(id: string) {
|
||||
if (selectedIds.value.includes(id)) {
|
||||
selectedIds.value = selectedIds.value.filter((x) => x !== id);
|
||||
@@ -83,7 +96,7 @@ function togglePerson(id: string) {
|
||||
}
|
||||
|
||||
function selectVisible() {
|
||||
const ids = filteredPeople.value.map((p) => p.id);
|
||||
const ids = people.value.map((p) => p.id);
|
||||
selectedIds.value = [...new Set([...selectedIds.value, ...ids])];
|
||||
}
|
||||
|
||||
@@ -194,8 +207,9 @@ onMounted(() => {
|
||||
<p class="muted">
|
||||
انتخابشده: {{ toFaDigits(selectedIds.length) }} نفر
|
||||
</p>
|
||||
<p v-if="peopleLoading" class="muted">در حال بارگذاری مخاطبان…</p>
|
||||
<div class="people-list">
|
||||
<label v-for="p in filteredPeople" :key="p.id" class="person">
|
||||
<label v-for="p in people" :key="p.id" class="person">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="selectedIds.includes(p.id)"
|
||||
|
||||
Reference in New Issue
Block a user