yinshouping commited on
Commit
34f7734
·
verified ·
1 Parent(s): 15a7bf0

### 周报内容结构 (report_content 解析后的JSON结构)

Browse files

```json
{
"projectId": "项目ID",
"reportPeriod": {
"startDate": "2024-01-01",
"endDate": "2024-01-07"
},
"thisWeek": {
"statistics": {
"plannedTasks": {
"count": 10,
"totalBaselineHours": 80.5,
"totalValuePoints": 150
},
"completedTasks": {
"count": 8,
"totalBaselineHours": 64.0,
"totalActualHours": 72.5,
"totalValuePoints": 120
},
"inProgressTasks": {
"count": 5,
"totalBaselineHours": 40.0,
"totalValuePoints": 75
},
"newDefects": {
"count": 3
},
"fixedDefects": {
"count": 2,
"avgFixDays": 1.5
},
"unfixedDefects": {
"count": 4
},
"newEvents": {
"count": 2,
"totalValuePoints": 30
},
"projectMembers": {
"totalCount": 8,
"activeCount": 6
}
},
"taskList": [
{
"id": "任务ID",
"taskNo": "TASK-001",
"content": "任务描述",
"assigneeName": "张三",
"planCompletionDate": "2024-01-05T00:00:00",
"actualCompletionDate": "2024-01-04T00:00:00",
"statusName": "已完成",
"baselineHours": 8.0,
"actualHours": 9.5,
"complexityName": "中等",
"valuePoints": 15
}
],
"defectList": [
{
"id": "缺陷ID",
"defectNo": "BUG-001",
"title": "缺陷标题",
"description": "缺陷描述",
"reporterName": "李四",
"assigneeName": "王五",
"levelName": "严重",
"statusName": "已修复",
"reportTime": "2024-01-02T10:00:00",
"fixTime": "2024-01-03T15:30:00",
"fixDays": 1
}
],
"eventList": [
{
"id": "事件ID",
"eventTypeName": "技术分享",
"eventDate": "2024-01-03T00:00:00",
"content": "事件描述",
"memberName": "赵六",
"valuePoints": 20,
"hoursSpent": 2.0
}
]
},
"nextWeek": {
"statistics": {
"plannedTasks": {
"count": 12,
"totalBaselineHours": 96.0,
"totalValuePoints": 180
},
"inProgressTasks": {
"count": 3,
"totalBaselineHours": 24.0,
"totalValuePoints": 45
}
},
"taskList": [
{
"id": "任务ID",
"taskNo": "TASK-002",
"content": "下周任务描述",
"assigneeName": "张三",
"planCompletionDate": "2024-01-12T00:00:00",
"statusName": "进行中",
"baselineHours": 16.0,
"complexityName": "复杂",
"valuePoints": 25
}
]
},
"generateTime": "2024-01-08T10:00:00"
}
```

## 字段说明

### 统计数据字段说明
- **plannedTasks**: 计划完成任务统计
- **completedTasks**: 实际完成任务统计
- **inProgressTasks**: 进行中任务统计
- **newDefects**: 新增缺陷统计
- **fixedDefects**: 修复缺陷统计(包含平均修复天数)
- **unfixedDefects**: 未修复缺陷统计
- **newEvents**: 新增定性事件统计
- **projectMembers**: 项目成员统计(总数和活跃数)

### 任务列表字段说明
- **taskNo**: 任务编号
- **content**: 任务内容描述
- **assigneeName**: 任务负责人姓名
- **planCompletionDate**: 计划完成日期
- **actualCompletionDate**: 实际完成日期
- **statusName**: 任务状态名称
- **baselineHours**: 基线工时
- **actualHours**: 实际工时
- **complexityName**: 复杂度名称
- **valuePoints**: 价值点数

### 缺陷列表字段说明
- **defectNo**: 缺陷编号
- **title**: 缺陷标题
- **description**: 缺陷描述
- **reporterName**: 报告人姓名
- **assigneeName**: 处理人姓名
- **levelName**: 缺陷等级名称
- **statusName**: 缺陷状态名称
- **reportTime**: 报告时间
- **fixTime**: 修复时间
- **fixDays**: 修复天数

### 事件列表字段说明
- **eventTypeName**: 事件类型名称
- **eventDate**: 事件日期
- **content**: 事件内容描述
- **memberName**: 相关成员姓名
- **valuePoints**: 价值点数
- **hoursSpent**: 花费工时

## 项目周报内容的结构初步构想

### 本周工作完成情况
#### 统计数字
- 计划完成任务数、基准工时合计、价值点合计(计划完成时间位于起始至结束日期的)【plan_completion_date BETWEEN {startDate} AND {endDate}】
- 实际完成任务数、基准工时合计、实际工时合计、价值点合计(状态为已完成且实际完成时间位于起始至结束日期的)【status_code='09' AND actual_completion_date BETWEEN {startDate} AND {endDate}】
- 进行中的任务数、基准工时合计、价值点合计(状态为 进行中 的任务数)【status_code='02'】
- 新增缺陷数(创建时间位于起始至结束日期的)【report_time BETWEEN {startDate} AND {endDate}】
- 修复缺陷数、平均修复所用时长(天)(状态为已修复且修复时间位于起始至结束日期的)【status_code='09' AND fix_time BETWEEN {startDate} AND {endDate}】
- 未修复缺陷数(状态不为已修复的缺陷数量)【status_code!='09'】
- 新增定性事件数、价值点合计(事件日期位于起始至结束日期的)【event_date BETWEEN {startDate} AND {endDate}】
- 项目成员数 project_team
- 活跃成员数(活动日志日涉及到的成员数量)activity_log
#### 任务列表
计划完成任务、实际完成任务、进行中的任务 的 列表 的 并集(根据任务ID去重、编号倒序排列)
#### 缺陷列表
新增缺陷、修复缺陷、未修复缺陷 的 列表 的 并集(根据缺陷ID去重、编号倒序排列)
#### 事件列表
新增定性事件 的 列表
### 下周工作计划
#### 统计数字
- 计划完成任务数、基准工时合计、价值点合计(状态不等于‘已完成’ 且 计划完成日期位于起始至结束日期的)【status_code!='09' AND plan_completion_date BETWEEN {下周的周一} AND {下周的周日}】
- 进行中的任务数、基准工时合计、价值点合计(任务状态为 进行中 且 计划完成日期大于下周最后一天的)【status_code='02' AND plan_completion_date > {下周的周日}】
#### 任务列表
计划完成任务、进行中的任务 的 列表 的 并集(根据任务ID去重、编号倒序排列)


根据以上内容重新设计项目周报的详情页面

Files changed (3) hide show
  1. index.html +10 -4
  2. report.html +4 -0
  3. weekly_report.html +520 -0
index.html CHANGED
@@ -69,10 +69,16 @@
69
  <input type="text" placeholder="Search projects..." class="pl-10 pr-4 py-2 rounded-lg border border-primary-200 focus:outline-none focus:ring-2 focus:ring-secondary-500">
70
  <i data-feather="search" class="absolute left-3 top-2.5 text-primary-400"></i>
71
  </div>
72
- <a href="/report.html" class="bg-secondary-500 hover:bg-secondary-600 text-white px-4 py-2 rounded-lg flex items-center transition">
73
- <i data-feather="plus" class="mr-2"></i>
74
- New Report
75
- </a>
 
 
 
 
 
 
76
  </div>
77
  </header>
78
 
 
69
  <input type="text" placeholder="Search projects..." class="pl-10 pr-4 py-2 rounded-lg border border-primary-200 focus:outline-none focus:ring-2 focus:ring-secondary-500">
70
  <i data-feather="search" class="absolute left-3 top-2.5 text-primary-400"></i>
71
  </div>
72
+ <div class="flex space-x-4">
73
+ <a href="/report.html" class="bg-secondary-500 hover:bg-secondary-600 text-white px-4 py-2 rounded-lg flex items-center transition">
74
+ <i data-feather="plus" class="mr-2"></i>
75
+ New Report
76
+ </a>
77
+ <a href="/weekly_report.html" class="bg-white hover:bg-primary-50 border border-primary-200 px-4 py-2 rounded-lg flex items-center transition">
78
+ <i data-feather="file-text" class="mr-2"></i>
79
+ Weekly Report
80
+ </a>
81
+ </div>
82
  </div>
83
  </header>
84
 
report.html CHANGED
@@ -27,6 +27,10 @@
27
  <h1 class="text-3xl font-bold text-primary-800">Weekly Project Report</h1>
28
  </div>
29
  <div class="flex space-x-4">
 
 
 
 
30
  <button class="bg-white hover:bg-primary-50 border border-primary-200 px-4 py-2 rounded-lg flex items-center transition">
31
  <i data-feather="download" class="mr-2"></i>
32
  Export
 
27
  <h1 class="text-3xl font-bold text-primary-800">Weekly Project Report</h1>
28
  </div>
29
  <div class="flex space-x-4">
30
+ <a href="/weekly_report.html" class="bg-white hover:bg-primary-50 border border-primary-200 px-4 py-2 rounded-lg flex items-center transition">
31
+ <i data-feather="calendar" class="mr-2"></i>
32
+ Weekly Report
33
+ </a>
34
  <button class="bg-white hover:bg-primary-50 border border-primary-200 px-4 py-2 rounded-lg flex items-center transition">
35
  <i data-feather="download" class="mr-2"></i>
36
  Export
weekly_report.html ADDED
@@ -0,0 +1,520 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Weekly Project Report | SlateSync</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <style>
11
+ .progress-ring__circle {
12
+ transition: stroke-dashoffset 0.5s;
13
+ transform: rotate(-90deg);
14
+ transform-origin: 50% 50%;
15
+ }
16
+ .card-hover:hover {
17
+ transform: translateY(-5px);
18
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
19
+ }
20
+ .badge {
21
+ @apply px-2 py-1 text-xs rounded-full;
22
+ }
23
+ .status-completed {
24
+ @apply bg-green-100 text-green-800;
25
+ }
26
+ .status-inprogress {
27
+ @apply bg-blue-100 text-blue-800;
28
+ }
29
+ .level-critical {
30
+ @apply bg-red-100 text-red-800;
31
+ }
32
+ .level-high {
33
+ @apply bg-orange-100 text-orange-800;
34
+ }
35
+ .level-medium {
36
+ @apply bg-yellow-100 text-yellow-800;
37
+ }
38
+ .level-low {
39
+ @apply bg-gray-100 text-gray-800;
40
+ }
41
+ </style>
42
+ </head>
43
+ <body class="bg-primary-50 min-h-screen">
44
+ <div class="container mx-auto px-4 py-8">
45
+ <!-- Report Header -->
46
+ <header class="mb-10">
47
+ <div class="flex justify-between items-center mb-6">
48
+ <div class="flex items-center">
49
+ <div class="w-10 h-10 rounded-full bg-secondary-500 flex items-center justify-center mr-3">
50
+ <i data-feather="file-text" class="text-white"></i>
51
+ </div>
52
+ <h1 class="text-3xl font-bold text-primary-800">Weekly Project Report</h1>
53
+ </div>
54
+ <div class="flex space-x-4">
55
+ <button class="bg-white hover:bg-primary-50 border border-primary-200 px-4 py-2 rounded-lg flex items-center transition">
56
+ <i data-feather="download" class="mr-2"></i>
57
+ Export PDF
58
+ </button>
59
+ <button class="bg-secondary-500 hover:bg-secondary-600 text-white px-4 py-2 rounded-lg flex items-center transition">
60
+ <i data-feather="share-2" class="mr-2"></i>
61
+ Share Report
62
+ </button>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="bg-white rounded-xl shadow-md p-6">
67
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-6">
68
+ <div>
69
+ <h3 class="text-sm font-medium text-primary-400 mb-1">Report Period</h3>
70
+ <p class="text-primary-800 font-medium" id="report-period">Jun 5 - Jun 11, 2023</p>
71
+ </div>
72
+ <div>
73
+ <h3 class="text-sm font-medium text-primary-400 mb-1">Project</h3>
74
+ <p class="text-primary-800 font-medium" id="project-name">Website Redesign</p>
75
+ </div>
76
+ <div>
77
+ <h3 class="text-sm font-medium text-primary-400 mb-1">Team Members</h3>
78
+ <p class="text-primary-800 font-medium" id="team-members">8 (6 active)</p>
79
+ </div>
80
+ <div>
81
+ <h3 class="text-sm font-medium text-primary-400 mb-1">Generated On</h3>
82
+ <p class="text-primary-800 font-medium" id="generate-time">Jun 8, 2023 10:00 AM</p>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </header>
87
+
88
+ <!-- Main Content -->
89
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
90
+ <!-- Main Content -->
91
+ <div class="lg:col-span-2">
92
+ <!-- Summary Stats -->
93
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
94
+ <h2 class="text-xl font-bold text-primary-800 mb-6">Weekly Summary</h2>
95
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
96
+ <div class="bg-primary-50 rounded-lg p-4">
97
+ <h3 class="text-sm font-medium text-primary-500 mb-1">Tasks Completed</h3>
98
+ <div class="flex items-end justify-between">
99
+ <span class="text-2xl font-bold text-primary-800">8</span>
100
+ <span class="text-sm text-green-500">+2 from last week</span>
101
+ </div>
102
+ </div>
103
+ <div class="bg-primary-50 rounded-lg p-4">
104
+ <h3 class="text-sm font-medium text-primary-500 mb-1">Value Points</h3>
105
+ <div class="flex items-end justify-between">
106
+ <span class="text-2xl font-bold text-primary-800">120</span>
107
+ <span class="text-sm text-green-500">80% achieved</span>
108
+ </div>
109
+ </div>
110
+ <div class="bg-primary-50 rounded-lg p-4">
111
+ <h3 class="text-sm font-medium text-primary-500 mb-1">Defects Fixed</h3>
112
+ <div class="flex items-end justify-between">
113
+ <span class="text-2xl font-bold text-primary-800">2</span>
114
+ <span class="text-sm text-yellow-500">4 remaining</span>
115
+ </div>
116
+ </div>
117
+ <div class="bg-primary-50 rounded-lg p-4">
118
+ <h3 class="text-sm font-medium text-primary-500 mb-1">Avg Fix Time</h3>
119
+ <div class="flex items-end justify-between">
120
+ <span class="text-2xl font-bold text-primary-800">1.5d</span>
121
+ <span class="text-sm text-green-500">Improved 0.5d</span>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ </div>
126
+
127
+ <!-- Completed Tasks -->
128
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
129
+ <div class="flex justify-between items-center mb-6">
130
+ <h2 class="text-xl font-bold text-primary-800">Completed Tasks</h2>
131
+ <span class="text-sm text-primary-500">8 tasks completed (64h planned, 72.5h actual)</span>
132
+ </div>
133
+ <div class="overflow-x-auto">
134
+ <table class="w-full">
135
+ <thead class="text-left text-primary-500 border-b border-primary-100">
136
+ <tr>
137
+ <th class="pb-3 font-medium">Task</th>
138
+ <th class="pb-3 font-medium">Assignee</th>
139
+ <th class="pb-3 font-medium">Hours</th>
140
+ <th class="pb-3 font-medium">Value</th>
141
+ <th class="pb-3 font-medium">Status</th>
142
+ </tr>
143
+ </thead>
144
+ <tbody class="divide-y divide-primary-100" id="completed-tasks">
145
+ <!-- Will be populated by JavaScript -->
146
+ </tbody>
147
+ </table>
148
+ </div>
149
+ </div>
150
+
151
+ <!-- Defects -->
152
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
153
+ <div class="flex justify-between items-center mb-6">
154
+ <h2 class="text-xl font-bold text-primary-800">Defects Tracking</h2>
155
+ <div class="flex space-x-2">
156
+ <span class="text-sm text-green-500">2 fixed</span>
157
+ <span class="text-sm text-primary-400">|</span>
158
+ <span class="text-sm text-red-500">3 new</span>
159
+ <span class="text-sm text-primary-400">|</span>
160
+ <span class="text-sm text-yellow-500">4 open</span>
161
+ </div>
162
+ </div>
163
+ <div class="overflow-x-auto">
164
+ <table class="w-full">
165
+ <thead class="text-left text-primary-500 border-b border-primary-100">
166
+ <tr>
167
+ <th class="pb-3 font-medium">Defect</th>
168
+ <th class="pb-3 font-medium">Assignee</th>
169
+ <th class="pb-3 font-medium">Level</th>
170
+ <th class="pb-3 font-medium">Status</th>
171
+ <th class="pb-3 font-medium">Fix Time</th>
172
+ </tr>
173
+ </thead>
174
+ <tbody class="divide-y divide-primary-100" id="defects-list">
175
+ <!-- Will be populated by JavaScript -->
176
+ </tbody>
177
+ </table>
178
+ </div>
179
+ </div>
180
+
181
+ <!-- Events -->
182
+ <div class="bg-white rounded-xl shadow-md p-6">
183
+ <h2 class="text-xl font-bold text-primary-800 mb-6">Key Events</h2>
184
+ <div class="space-y-4" id="events-list">
185
+ <!-- Will be populated by JavaScript -->
186
+ </div>
187
+ </div>
188
+ </div>
189
+
190
+ <!-- Sidebar -->
191
+ <div>
192
+ <!-- Progress Overview -->
193
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
194
+ <h2 class="text-xl font-bold text-primary-800 mb-6">Progress Overview</h2>
195
+ <div class="flex flex-col items-center">
196
+ <div class="relative w-40 h-40 mb-4">
197
+ <svg class="w-full h-full" viewBox="0 0 100 100">
198
+ <circle class="text-primary-100" stroke-width="8" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" />
199
+ <circle class="text-secondary-500" stroke-width="8" stroke-dasharray="251.2" stroke-dashoffset="50.24" stroke-linecap="round" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" />
200
+ </svg>
201
+ <div class="absolute inset-0 flex items-center justify-center">
202
+ <span class="text-3xl font-bold text-primary-800">80%</span>
203
+ </div>
204
+ </div>
205
+ <div class="grid grid-cols-2 gap-4 w-full">
206
+ <div class="text-center">
207
+ <p class="text-sm text-primary-500">Planned</p>
208
+ <p class="font-bold text-primary-800">80.5h</p>
209
+ </div>
210
+ <div class="text-center">
211
+ <p class="text-sm text-primary-500">Actual</p>
212
+ <p class="font-bold text-primary-800">72.5h</p>
213
+ </div>
214
+ </div>
215
+ </div>
216
+ </div>
217
+
218
+ <!-- Team Contributions -->
219
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
220
+ <h2 class="text-xl font-bold text-primary-800 mb-6">Team Contributions</h2>
221
+ <div class="space-y-4" id="team-contributions">
222
+ <!-- Will be populated by JavaScript -->
223
+ </div>
224
+ </div>
225
+
226
+ <!-- Next Week Plan -->
227
+ <div class="bg-white rounded-xl shadow-md p-6">
228
+ <h2 class="text-xl font-bold text-primary-800 mb-6">Next Week Plan</h2>
229
+ <div class="mb-4">
230
+ <p class="text-sm text-primary-500 mb-1">Planned Tasks</p>
231
+ <p class="font-bold text-primary-800">12 tasks (96h, 180 points)</p>
232
+ </div>
233
+ <div class="space-y-3" id="next-week-tasks">
234
+ <!-- Will be populated by JavaScript -->
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </div>
239
+ </div>
240
+
241
+ <script>
242
+ feather.replace();
243
+
244
+ // Sample data - in a real app this would come from an API
245
+ const reportData = {
246
+ projectId: "PRJ-2023-001",
247
+ reportPeriod: {
248
+ startDate: "2024-01-01",
249
+ endDate: "2024-01-07"
250
+ },
251
+ thisWeek: {
252
+ statistics: {
253
+ plannedTasks: { count: 10, totalBaselineHours: 80.5, totalValuePoints: 150 },
254
+ completedTasks: { count: 8, totalBaselineHours: 64.0, totalActualHours: 72.5, totalValuePoints: 120 },
255
+ inProgressTasks: { count: 5, totalBaselineHours: 40.0, totalValuePoints: 75 },
256
+ newDefects: { count: 3 },
257
+ fixedDefects: { count: 2, avgFixDays: 1.5 },
258
+ unfixedDefects: { count: 4 },
259
+ newEvents: { count: 2, totalValuePoints: 30 },
260
+ projectMembers: { totalCount: 8, activeCount: 6 }
261
+ },
262
+ taskList: [
263
+ {
264
+ id: "TASK-001",
265
+ taskNo: "TASK-001",
266
+ content: "Implement user authentication",
267
+ assigneeName: "Sarah Johnson",
268
+ planCompletionDate: "2024-01-05T00:00:00",
269
+ actualCompletionDate: "2024-01-04T00:00:00",
270
+ statusName: "Completed",
271
+ baselineHours: 8.0,
272
+ actualHours: 9.5,
273
+ complexityName: "Medium",
274
+ valuePoints: 15
275
+ },
276
+ {
277
+ id: "TASK-002",
278
+ taskNo: "TASK-002",
279
+ content: "Design homepage mockups",
280
+ assigneeName: "Michael Chen",
281
+ planCompletionDate: "2024-01-03T00:00:00",
282
+ actualCompletionDate: "2024-01-03T00:00:00",
283
+ statusName: "Completed",
284
+ baselineHours: 12.0,
285
+ actualHours: 10.0,
286
+ complexityName: "High",
287
+ valuePoints: 25
288
+ }
289
+ ],
290
+ defectList: [
291
+ {
292
+ id: "BUG-001",
293
+ defectNo: "BUG-001",
294
+ title: "Login fails on mobile",
295
+ description: "Users unable to login on mobile devices",
296
+ reporterName: "Alex Rodriguez",
297
+ assigneeName: "Sarah Johnson",
298
+ levelName: "Critical",
299
+ statusName: "Fixed",
300
+ reportTime: "2024-01-02T10:00:00",
301
+ fixTime: "2024-01-03T15:30:00",
302
+ fixDays: 1
303
+ },
304
+ {
305
+ id: "BUG-002",
306
+ defectNo: "BUG-002",
307
+ title: "Dashboard loading slow",
308
+ description: "Dashboard takes >5s to load",
309
+ reporterName: "Emma Wilson",
310
+ assigneeName: "David Kim",
311
+ levelName: "High",
312
+ statusName: "Open",
313
+ reportTime: "2024-01-04T14:00:00",
314
+ fixTime: null,
315
+ fixDays: null
316
+ }
317
+ ],
318
+ eventList: [
319
+ {
320
+ id: "EVT-001",
321
+ eventTypeName: "Team Meeting",
322
+ eventDate: "2024-01-03T00:00:00",
323
+ content: "Weekly sprint planning",
324
+ memberName: "All",
325
+ valuePoints: 20,
326
+ hoursSpent: 2.0
327
+ }
328
+ ]
329
+ },
330
+ nextWeek: {
331
+ statistics: {
332
+ plannedTasks: { count: 12, totalBaselineHours: 96.0, totalValuePoints: 180 },
333
+ inProgressTasks: { count: 3, totalBaselineHours: 24.0, totalValuePoints: 45 }
334
+ },
335
+ taskList: [
336
+ {
337
+ id: "TASK-101",
338
+ taskNo: "TASK-101",
339
+ content: "Implement payment gateway",
340
+ assigneeName: "Sarah Johnson",
341
+ planCompletionDate: "2024-01-12T00:00:00",
342
+ statusName: "Planned",
343
+ baselineHours: 16.0,
344
+ complexityName: "High",
345
+ valuePoints: 30
346
+ }
347
+ ]
348
+ },
349
+ generateTime: "2024-01-08T10:00:00"
350
+ };
351
+
352
+ // Format dates
353
+ function formatDate(dateStr) {
354
+ if (!dateStr) return '';
355
+ const date = new Date(dateStr);
356
+ return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
357
+ }
358
+
359
+ function formatDateTime(dateStr) {
360
+ if (!dateStr) return '';
361
+ const date = new Date(dateStr);
362
+ return date.toLocaleString('en-US', {
363
+ month: 'short',
364
+ day: 'numeric',
365
+ hour: '2-digit',
366
+ minute: '2-digit'
367
+ });
368
+ }
369
+
370
+ // Populate the report with data
371
+ document.addEventListener('DOMContentLoaded', function() {
372
+ // Header information
373
+ document.getElementById('report-period').textContent =
374
+ `${formatDate(reportData.reportPeriod.startDate)} - ${formatDate(reportData.reportPeriod.endDate)}`;
375
+ document.getElementById('team-members').textContent =
376
+ `${reportData.thisWeek.statistics.projectMembers.totalCount} (${reportData.thisWeek.statistics.projectMembers.activeCount} active)`;
377
+ document.getElementById('generate-time').textContent =
378
+ formatDateTime(reportData.generateTime);
379
+
380
+ // Completed tasks
381
+ const completedTasksContainer = document.getElementById('completed-tasks');
382
+ reportData.thisWeek.taskList.forEach(task => {
383
+ const row = document.createElement('tr');
384
+ row.className = 'hover:bg-primary-50';
385
+ row.innerHTML = `
386
+ <td class="py-3">
387
+ <div class="font-medium text-primary-700">${task.taskNo}</div>
388
+ <div class="text-sm text-primary-500">${task.content}</div>
389
+ </td>
390
+ <td class="py-3">${task.assigneeName}</td>
391
+ <td class="py-3">
392
+ <div class="text-sm text-primary-500">${task.baselineHours}h planned</div>
393
+ <div class="font-medium">${task.actualHours}h actual</div>
394
+ </td>
395
+ <td class="py-3">${task.valuePoints}</td>
396
+ <td class="py-3">
397
+ <span class="badge status-completed">${task.statusName}</span>
398
+ </td>
399
+ `;
400
+ completedTasksContainer.appendChild(row);
401
+ });
402
+
403
+ // Defects
404
+ const defectsContainer = document.getElementById('defects-list');
405
+ reportData.thisWeek.defectList.forEach(defect => {
406
+ const row = document.createElement('tr');
407
+ row.className = 'hover:bg-primary-50';
408
+ row.innerHTML = `
409
+ <td class="py-3">
410
+ <div class="font-medium text-primary-700">${defect.defectNo}</div>
411
+ <div class="text-sm text-primary-500">${defect.title}</div>
412
+ </td>
413
+ <td class="py-3">${defect.assigneeName || 'Unassigned'}</td>
414
+ <td class="py-3">
415
+ <span class="badge level-${defect.levelName.toLowerCase()}">${defect.levelName}</span>
416
+ </td>
417
+ <td class="py-3">
418
+ <span class="badge ${defect.statusName === 'Fixed' ? 'status-completed' : 'status-inprogress'}">
419
+ ${defect.statusName}
420
+ </span>
421
+ </td>
422
+ <td class="py-3">
423
+ ${defect.fixTime ? `${defect.fixDays}d` : '-'}
424
+ </td>
425
+ `;
426
+ defectsContainer.appendChild(row);
427
+ });
428
+
429
+ // Events
430
+ const eventsContainer = document.getElementById('events-list');
431
+ reportData.thisWeek.eventList.forEach(event => {
432
+ const eventElement = document.createElement('div');
433
+ eventElement.className = 'flex items-start';
434
+ eventElement.innerHTML = `
435
+ <div class="mr-4 mt-1">
436
+ <div class="w-8 h-8 rounded-lg bg-secondary-100 flex items-center justify-center">
437
+ <i data-feather="calendar" class="text-secondary-500"></i>
438
+ </div>
439
+ </div>
440
+ <div>
441
+ <h4 class="font-medium text-primary-800">${event.eventTypeName}</h4>
442
+ <p class="text-sm text-primary-500 mt-1">${event.content}</p>
443
+ <div class="flex items-center mt-2 text-sm text-primary-400">
444
+ <i data-feather="user" class="w-3 h-3 mr-1"></i>
445
+ <span class="mr-3">${event.memberName}</span>
446
+ <i data-feather="clock" class="w-3 h-3 mr-1"></i>
447
+ <span>${event.hoursSpent}h (${event.valuePoints}pts)</span>
448
+ </div>
449
+ </div>
450
+ `;
451
+ eventsContainer.appendChild(eventElement);
452
+ });
453
+
454
+ // Team Contributions
455
+ const teamContainer = document.getElementById('team-contributions');
456
+ const teamMembers = [
457
+ { name: "Sarah Johnson", tasks: 8, value: 120 },
458
+ { name: "Michael Chen", tasks: 5, value: 85 },
459
+ { name: "Alex Rodriguez", tasks: 3, value: 45 }
460
+ ];
461
+ teamMembers.forEach(member => {
462
+ const memberElement = document.createElement('div');
463
+ memberElement.className = 'flex items-center';
464
+ memberElement.innerHTML = `
465
+ <div class="w-10 h-10 rounded-full bg-secondary-100 flex items-center justify-center mr-3">
466
+ <i data-feather="user" class="text-secondary-500"></i>
467
+ </div>
468
+ <div class="flex-1">
469
+ <h4 class="font-medium text-primary-800">${member.name}</h4>
470
+ <div class="flex justify-between text-sm text-primary-500">
471
+ <span>${member.tasks} tasks</span>
472
+ <span>${member.value} points</span>
473
+ </div>
474
+ </div>
475
+ `;
476
+ teamContainer.appendChild(memberElement);
477
+ });
478
+
479
+ // Next Week Tasks
480
+ const nextWeekContainer = document.getElementById('next-week-tasks');
481
+ reportData.nextWeek.taskList.forEach(task => {
482
+ const taskElement = document.createElement('div');
483
+ taskElement.className = 'flex items-start';
484
+ taskElement.innerHTML = `
485
+ <div class="mr-3 mt-1">
486
+ <div class="w-5 h-5 rounded-full bg-secondary-100 flex items-center justify-center">
487
+ <i data-feather="flag" class="text-secondary-500 w-3 h-3"></i>
488
+ </div>
489
+ </div>
490
+ <div>
491
+ <p class="text-primary-700">${task.content}</p>
492
+ <div class="text-xs text-primary-400 mt-1">
493
+ ${task.assigneeName} • ${task.baselineHours}h • ${task.valuePoints}pts
494
+ </div>
495
+ </div>
496
+ `;
497
+ nextWeekContainer.appendChild(taskElement);
498
+ });
499
+
500
+ // Replace feather icons
501
+ feather.replace();
502
+ });
503
+
504
+ // Animation for report sections
505
+ document.addEventListener('DOMContentLoaded', function() {
506
+ const sections = document.querySelectorAll('.bg-white');
507
+ sections.forEach((section, index) => {
508
+ section.style.opacity = '0';
509
+ section.style.transform = 'translateY(20px)';
510
+ section.style.transition = 'all 0.5s ease ' + (index * 0.1) + 's';
511
+
512
+ setTimeout(() => {
513
+ section.style.opacity = '1';
514
+ section.style.transform = 'translateY(0)';
515
+ }, 100);
516
+ });
517
+ });
518
+ </script>
519
+ </body>
520
+ </html>