Files
2026-03-20 15:47:17 +05:00

203 lines
5.2 KiB
JavaScript

import './bootstrap';
const dashboardCharts = window.__dashboardCharts ?? {
initialized: false,
status: null,
priority: null,
};
window.__dashboardCharts = dashboardCharts;
const destroyDashboardCharts = () => {
if (dashboardCharts.status) {
dashboardCharts.status.destroy();
dashboardCharts.status = null;
}
if (dashboardCharts.priority) {
dashboardCharts.priority.destroy();
dashboardCharts.priority = null;
}
};
const getDashboardPayloadFromDom = () => {
const node = document.getElementById('dashboard-chart-data');
if (!node) {
return null;
}
try {
return {
status: JSON.parse(node.dataset.status ?? '[]'),
priority: JSON.parse(node.dataset.priority ?? '[]'),
};
} catch (_) {
return { status: [], priority: [] };
}
};
const chartOptionsByType = (type) => {
const common = {
responsive: true,
maintainAspectRatio: true,
animation: false,
};
if (type === 'bar') {
return {
...common,
aspectRatio: 2.2,
scales: {
y: {
beginAtZero: true,
ticks: {
precision: 0,
},
},
},
plugins: {
legend: { display: false },
},
};
}
return {
...common,
aspectRatio: 1.7,
};
};
const upsertChart = (canvasId, type, data) => {
const canvas = document.getElementById(canvasId);
if (!canvas || !window.Chart) {
return null;
}
const existing = window.Chart.getChart(canvas);
const labels = data.map((item) => item.label);
const values = data.map((item) => item.value);
const colors = data.map((item) => item.color);
if (existing) {
existing.data.labels = labels;
existing.data.datasets[0].data = values;
existing.data.datasets[0].backgroundColor = colors;
existing.update('none');
return existing;
}
return new window.Chart(canvas.getContext('2d'), {
type,
data: {
labels,
datasets: [{
data: values,
backgroundColor: colors,
borderWidth: 0,
}],
},
options: chartOptionsByType(type),
});
};
const renderDashboardCharts = (payload) => {
const data = payload ?? getDashboardPayloadFromDom();
if (!data) {
destroyDashboardCharts();
return;
}
if (!window.Chart) {
window.setTimeout(() => renderDashboardCharts(data), 120);
return;
}
dashboardCharts.status = upsertChart('statusChart', 'doughnut', data.status ?? []);
dashboardCharts.priority = upsertChart('priorityChart', 'bar', data.priority ?? []);
};
const generalReportChart = window.__generalReportChart ?? {
initialized: false,
};
window.__generalReportChart = generalReportChart;
const destroyGeneralReportChart = () => {
const canvas = document.getElementById('generalStatusChart');
if (!canvas || !window.Chart) {
return;
}
const chart = window.Chart.getChart(canvas);
if (chart) {
chart.destroy();
}
};
const getGeneralReportPayloadFromDom = () => {
const node = document.getElementById('general-report-chart-data');
if (!node) {
return null;
}
try {
return JSON.parse(node.dataset.chart ?? '[]');
} catch (_) {
return [];
}
};
const normalizeGeneralReportPayload = (payload) => {
return (payload ?? []).map((item) => ({
label: item.status ?? item.label ?? 'Неизвестно',
value: Number(item.total ?? item.value ?? 0),
color: item.color ?? '#2563eb',
}));
};
const renderGeneralReportChart = (payload) => {
const node = document.getElementById('general-report-chart-data');
if (!node) {
destroyGeneralReportChart();
return;
}
const data = normalizeGeneralReportPayload(payload ?? getGeneralReportPayloadFromDom());
if (!window.Chart) {
window.setTimeout(() => renderGeneralReportChart(data), 120);
return;
}
upsertChart('generalStatusChart', 'bar', data);
};
if (!dashboardCharts.initialized) {
dashboardCharts.initialized = true;
window.addEventListener('dashboard-charts-updated', (event) => {
const detail = event.detail ?? {};
renderDashboardCharts({
status: detail.status ?? detail[0]?.status ?? [],
priority: detail.priority ?? detail[0]?.priority ?? [],
});
});
document.addEventListener('DOMContentLoaded', () => renderDashboardCharts());
document.addEventListener('livewire:navigated', () => renderDashboardCharts());
}
if (!generalReportChart.initialized) {
generalReportChart.initialized = true;
window.addEventListener('general-report-chart-updated', (event) => {
const detail = event.detail ?? {};
renderGeneralReportChart(detail.chart ?? detail[0]?.chart ?? []);
});
document.addEventListener('DOMContentLoaded', () => renderGeneralReportChart());
document.addEventListener('livewire:navigated', () => renderGeneralReportChart());
}