58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
|
|
import { computed, ref } from 'vue';
|
|||
|
|
import { defineStore } from 'pinia';
|
|||
|
|
import { LEAD_STATUSES, type LeadStatus } from '../composables/leadStatuses';
|
|||
|
|
import { type ApiLeadStatus, listLeadStatuses } from '../api/leadStatuses';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Pinia store для статусов воронки. Заменяет static-снапшот `LEAD_STATUSES`
|
|||
|
|
* (composables/leadStatuses.ts) на live-данные из API при наличии auth.
|
|||
|
|
*
|
|||
|
|
* Initial state — snapshot (UI работает сразу без fetch'а). `load()` вызывается
|
|||
|
|
* из DealsView/KanbanView на mount и replace'ит snapshot реальными данными.
|
|||
|
|
* На fail — снапшот остаётся.
|
|||
|
|
*/
|
|||
|
|
export const useLeadStatusesStore = defineStore('leadStatuses', () => {
|
|||
|
|
const statuses = ref<LeadStatus[]>([...LEAD_STATUSES]);
|
|||
|
|
const loading = ref(false);
|
|||
|
|
const fetchError = ref(false);
|
|||
|
|
const loaded = ref(false);
|
|||
|
|
|
|||
|
|
const bySlug = computed(() => {
|
|||
|
|
const map = new Map<string, LeadStatus>();
|
|||
|
|
statuses.value.forEach((s) => map.set(s.slug, s));
|
|||
|
|
return map;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function findBySlug(slug: string): LeadStatus | null {
|
|||
|
|
return bySlug.value.get(slug) ?? null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function load(force = false): Promise<void> {
|
|||
|
|
if (loaded.value && !force) return;
|
|||
|
|
loading.value = true;
|
|||
|
|
fetchError.value = false;
|
|||
|
|
try {
|
|||
|
|
const apiList = await listLeadStatuses();
|
|||
|
|
statuses.value = apiList.map(mapApi);
|
|||
|
|
loaded.value = true;
|
|||
|
|
} catch {
|
|||
|
|
fetchError.value = true;
|
|||
|
|
// Snapshot остаётся как fallback.
|
|||
|
|
} finally {
|
|||
|
|
loading.value = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return { statuses, loading, fetchError, loaded, bySlug, findBySlug, load };
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function mapApi(api: ApiLeadStatus): LeadStatus {
|
|||
|
|
return {
|
|||
|
|
slug: api.slug,
|
|||
|
|
nameRu: api.name_ru,
|
|||
|
|
isSystem: api.is_system,
|
|||
|
|
sortOrder: api.sort_order,
|
|||
|
|
colorHex: api.color_hex,
|
|||
|
|
};
|
|||
|
|
}
|