4.16.3: Добавлен normalized_total_score в прогресс недель
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m32s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m32s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "play-life-web",
|
||||
"version": "4.16.2",
|
||||
"version": "4.16.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -81,7 +81,10 @@ function WeekProgressChart({ data, allProjectsSorted, currentWeekData, selectedP
|
||||
|
||||
weeksMap[weekKey].push({
|
||||
projectName: item.project_name,
|
||||
score: parseFloat(item.total_score) || 0
|
||||
score: parseFloat(item.total_score) || 0,
|
||||
minGoalScore: parseFloat(item.min_goal_score) || 0,
|
||||
maxGoalScore: parseFloat(item.max_goal_score) || 0,
|
||||
normalizedTotalScore: parseFloat(item.normalized_total_score) || 0
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -94,7 +97,8 @@ function WeekProgressChart({ data, allProjectsSorted, currentWeekData, selectedP
|
||||
|
||||
weeksMap[currentWeekKey] = projects.map(project => ({
|
||||
projectName: project.project_name || project.name,
|
||||
score: parseFloat(project.total_score || project.score || 0)
|
||||
score: parseFloat(project.total_score || project.score || 0),
|
||||
normalizedTotalScore: parseFloat(project.normalized_total_score) || 0
|
||||
})).filter(p => {
|
||||
// Фильтруем по выбранному проекту, если он указан
|
||||
if (selectedProject && p.projectName !== selectedProject) {
|
||||
@@ -147,6 +151,7 @@ function WeekProgressChart({ data, allProjectsSorted, currentWeekData, selectedP
|
||||
|
||||
// Функция для обработки данных недели
|
||||
const processWeekData = (weekKey) => {
|
||||
const { year, week } = parseWeekKey(weekKey)
|
||||
const weekProjects = weeksMap[weekKey] || []
|
||||
const totalScore = weekProjects.reduce((sum, p) => sum + p.score, 0)
|
||||
|
||||
@@ -154,15 +159,20 @@ function WeekProgressChart({ data, allProjectsSorted, currentWeekData, selectedP
|
||||
// Сортируем проекты так же, как в полной статистике (по priority и min_goal_score)
|
||||
// Получаем цвет проекта из данных full-statistics, если доступен
|
||||
const projectsWithData = weekProjects.map(project => {
|
||||
// Ищем цвет проекта в данных full-statistics
|
||||
const projectData = data?.find(item => item.project_name === project.projectName)
|
||||
// Ищем данные проекта в full-statistics для получения цвета и calculated_score
|
||||
const projectData = data?.find(item =>
|
||||
item.project_name === project.projectName &&
|
||||
item.report_year === year &&
|
||||
item.report_week === week
|
||||
)
|
||||
const projectColor = projectData?.color
|
||||
? getProjectColor(project.projectName, allProjects, projectData.color)
|
||||
: getProjectColor(project.projectName, allProjects)
|
||||
|
||||
return {
|
||||
...project,
|
||||
color: projectColor
|
||||
color: projectColor,
|
||||
normalizedTotalScore: projectData?.normalized_total_score !== undefined ? parseFloat(projectData.normalized_total_score) || 0 : project.normalizedTotalScore || 0
|
||||
}
|
||||
})
|
||||
|
||||
@@ -176,8 +186,6 @@ function WeekProgressChart({ data, allProjectsSorted, currentWeekData, selectedP
|
||||
const sortedProjectsWithData = sortedProjectNames.map(name => {
|
||||
return projectsWithData.find(p => p.projectName === name)
|
||||
}).filter(Boolean)
|
||||
|
||||
const { year, week } = parseWeekKey(weekKey)
|
||||
|
||||
return {
|
||||
weekKey,
|
||||
@@ -212,49 +220,75 @@ function WeekProgressChart({ data, allProjectsSorted, currentWeekData, selectedP
|
||||
}
|
||||
|
||||
// Компонент для отображения прогрессбара недели
|
||||
const WeekProgressBar = ({ weekData }) => (
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="min-w-[100px] text-sm font-medium text-gray-700">
|
||||
Неделя {weekData.week}
|
||||
const WeekProgressBar = ({ weekData }) => {
|
||||
// Находим выбранный проект в данных недели для отображения normalized значения
|
||||
const selectedProjectData = selectedProject
|
||||
? weekData.projects.find(p => p.projectName === selectedProject)
|
||||
: null
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="min-w-[85px] text-sm font-medium text-gray-700">
|
||||
Неделя {weekData.week}
|
||||
</div>
|
||||
<div className="flex-1 relative h-6 bg-gray-200 rounded-full overflow-hidden shadow-inner">
|
||||
{weekData.totalScore === 0 ? (
|
||||
<div className="absolute inset-0 flex items-center justify-center text-gray-400 text-xs">
|
||||
Нет данных
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{weekData.projects.map((project, index) => {
|
||||
// Вычисляем позицию и ширину для каждого сегмента на основе абсолютных значений
|
||||
let left = 0
|
||||
for (let i = 0; i < index; i++) {
|
||||
left += weekData.projects[i].score
|
||||
}
|
||||
|
||||
const widthPercent = (project.score / maxTotalScore) * 100
|
||||
const leftPercent = (left / maxTotalScore) * 100
|
||||
|
||||
return (
|
||||
<div
|
||||
key={project.projectName}
|
||||
className="absolute h-full transition-all duration-300 hover:opacity-90"
|
||||
style={{
|
||||
left: `${leftPercent}%`,
|
||||
width: `${widthPercent}%`,
|
||||
backgroundColor: project.color,
|
||||
}}
|
||||
title={`${project.projectName}: ${project.score.toFixed(1)} баллов`}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="min-w-[85px] text-right text-sm text-gray-600 font-medium">
|
||||
{weekData.totalScore > 0 ? (
|
||||
<>
|
||||
{selectedProjectData &&
|
||||
selectedProjectData.normalizedTotalScore !== undefined &&
|
||||
selectedProjectData.normalizedTotalScore !== null &&
|
||||
selectedProjectData.normalizedTotalScore > 0 &&
|
||||
Math.abs(selectedProjectData.normalizedTotalScore - selectedProjectData.score) > 0.01 ? (
|
||||
<>
|
||||
<span className="text-gray-400">
|
||||
({selectedProjectData.normalizedTotalScore.toFixed(1)})
|
||||
</span>
|
||||
<span className="ml-1">
|
||||
{selectedProjectData.score.toFixed(1)}
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
weekData.totalScore.toFixed(1)
|
||||
)}
|
||||
</>
|
||||
) : '-'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 relative h-6 bg-gray-200 rounded-full overflow-hidden shadow-inner">
|
||||
{weekData.totalScore === 0 ? (
|
||||
<div className="absolute inset-0 flex items-center justify-center text-gray-400 text-xs">
|
||||
Нет данных
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{weekData.projects.map((project, index) => {
|
||||
// Вычисляем позицию и ширину для каждого сегмента на основе абсолютных значений
|
||||
let left = 0
|
||||
for (let i = 0; i < index; i++) {
|
||||
left += weekData.projects[i].score
|
||||
}
|
||||
|
||||
const widthPercent = (project.score / maxTotalScore) * 100
|
||||
const leftPercent = (left / maxTotalScore) * 100
|
||||
|
||||
return (
|
||||
<div
|
||||
key={project.projectName}
|
||||
className="absolute h-full transition-all duration-300 hover:opacity-90"
|
||||
style={{
|
||||
left: `${leftPercent}%`,
|
||||
width: `${widthPercent}%`,
|
||||
backgroundColor: project.color,
|
||||
}}
|
||||
title={`${project.projectName}: ${project.score.toFixed(1)} баллов`}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="min-w-[60px] text-right text-sm text-gray-600 font-medium">
|
||||
{weekData.totalScore > 0 ? `${weekData.totalScore.toFixed(1)}` : '-'}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user