fix(crm): mesghal by metal, jalali fit, scoped group filters
This commit is contained in:
@@ -24,6 +24,7 @@ import SavedFiltersBar from '@/components/SavedFiltersBar.vue';
|
||||
import TableColumnsMenu from '@/components/TableColumnsMenu.vue';
|
||||
import type {
|
||||
CompanyDto,
|
||||
CustomerGroupDto,
|
||||
ImportContactsResult,
|
||||
PaginatedResponse,
|
||||
PersonDto,
|
||||
@@ -82,6 +83,8 @@ const discFilter = computed(() => {
|
||||
const sourceFilters = computed(() => queryList('source'));
|
||||
const groupFilters = computed(() => queryList('group'));
|
||||
const { groups: customerGroups, load: loadCustomerGroups } = useCustomerGroups();
|
||||
/** گروههای فیلتر — با شمارش scoped بر اساس دسترسی کاربر */
|
||||
const filterGroups = ref<CustomerGroupDto[]>([]);
|
||||
const canManageGroups = computed(() => canManageSettings(auth.user?.role));
|
||||
const groupsManagerOpen = ref(false);
|
||||
|
||||
@@ -95,7 +98,9 @@ const filterValue = computed<ContactsFilterValue>(() => ({
|
||||
type FilterTag = { kind: 'group' | 'source' | 'mood' | 'disc'; value: string; label: string; color?: string };
|
||||
const activeTags = computed<FilterTag[]>(() => {
|
||||
const tags: FilterTag[] = groupFilters.value.map((id) => {
|
||||
const g = customerGroups.value.find((x) => x.id === id);
|
||||
const g =
|
||||
filterGroups.value.find((x) => x.id === id) ??
|
||||
customerGroups.value.find((x) => x.id === id);
|
||||
return { kind: 'group', value: id, label: g?.name ?? 'گروه حذفشده', color: g?.color };
|
||||
});
|
||||
if (tab.value !== 'people') return tags;
|
||||
@@ -303,7 +308,7 @@ async function load() {
|
||||
void loadCustomerGroups(true).catch(() => undefined);
|
||||
try {
|
||||
if (tab.value === 'people') {
|
||||
const [peopleRes, statsRes] = await Promise.all([
|
||||
const [peopleRes, statsRes, groupStatsRes] = await Promise.all([
|
||||
api.get<PaginatedResponse<PersonDto>>('/people', {
|
||||
params: {
|
||||
q: q.value || undefined,
|
||||
@@ -319,21 +324,31 @@ async function load() {
|
||||
api.get<PersonImportSourceStatDto[]>('/people/source-stats').catch(() => ({
|
||||
data: [] as PersonImportSourceStatDto[],
|
||||
})),
|
||||
api.get<CustomerGroupDto[]>('/people/group-stats').catch(() => ({
|
||||
data: [] as CustomerGroupDto[],
|
||||
})),
|
||||
]);
|
||||
people.value = peopleRes.data;
|
||||
sourceStats.value = statsRes.data;
|
||||
filterGroups.value = groupStatsRes.data;
|
||||
const visible = new Set(peopleRes.data.items.map((p) => p.id));
|
||||
selectedIds.value = selectedIds.value.filter((id) => visible.has(id));
|
||||
} else {
|
||||
const { data } = await api.get<PaginatedResponse<CompanyDto>>('/companies', {
|
||||
params: {
|
||||
q: q.value || undefined,
|
||||
page: page.value,
|
||||
limit: pageSize.value,
|
||||
groupId: csv(groupFilters.value),
|
||||
},
|
||||
});
|
||||
companies.value = data;
|
||||
const [companiesRes, groupStatsRes] = await Promise.all([
|
||||
api.get<PaginatedResponse<CompanyDto>>('/companies', {
|
||||
params: {
|
||||
q: q.value || undefined,
|
||||
page: page.value,
|
||||
limit: pageSize.value,
|
||||
groupId: csv(groupFilters.value),
|
||||
},
|
||||
}),
|
||||
api.get<CustomerGroupDto[]>('/companies/group-stats').catch(() => ({
|
||||
data: [] as CustomerGroupDto[],
|
||||
})),
|
||||
]);
|
||||
companies.value = companiesRes.data;
|
||||
filterGroups.value = groupStatsRes.data;
|
||||
}
|
||||
} catch (e) {
|
||||
if (axios.isAxiosError(e) && !e.response) {
|
||||
@@ -704,7 +719,7 @@ onMounted(load);
|
||||
:open="filterOpen"
|
||||
:tab="tab"
|
||||
:value="filterValue"
|
||||
:groups="customerGroups"
|
||||
:groups="filterGroups"
|
||||
:source-stats="sourceStats"
|
||||
:can-behavior="canBehavior"
|
||||
:sort="sort"
|
||||
@@ -739,7 +754,7 @@ onMounted(load);
|
||||
:open="filterOpen"
|
||||
:tab="tab"
|
||||
:value="filterValue"
|
||||
:groups="customerGroups"
|
||||
:groups="filterGroups"
|
||||
:source-stats="sourceStats"
|
||||
:can-behavior="canBehavior"
|
||||
@apply="applyFilters"
|
||||
|
||||
Reference in New Issue
Block a user