Skip to content

Commit

Permalink
Add feature to download planning data per project (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimasciput authored Jan 4, 2024
1 parent 24a9427 commit 372459f
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 23 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

35 changes: 34 additions & 1 deletion dashboard/src/components/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ const DOWNLOAD_API_URL = (
'/api/download-report-data/?id='
)

const DOWNLOAD_PLANNING_API_URL = (
'/api/schedule/csv/'
)

const LIST_SUMMARY_API_URL = (
'/api/list-summary/'
)
Expand Down Expand Up @@ -127,6 +131,22 @@ export default function Summary(props: any) {
});
};

const downloadPlanningCSV = (projectId: string, projectLabel: string) => {
setIsDownloading(true)
fetch(`${DOWNLOAD_PLANNING_API_URL}${projectId}/`)
.then((response) => response.blob())
.then((blob) => {
const url = window.URL.createObjectURL(new Blob([blob]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `Planning ${projectLabel}.csv`);
document.body.appendChild(link);
link.click();
link.parentNode?.removeChild(link);
setIsDownloading(false)
});
};

const fetchReportData = (url: string) => {
setChartLoading(true)
fetch(url).then(
Expand Down Expand Up @@ -340,7 +360,20 @@ export default function Summary(props: any) {
disabled={isDownloading}
startIcon={isDownloading ? <CircularProgress size={12}/> : <DownloadIcon/>}
variant="outlined" size="large" color='primary'>
Download
Download Summary
</TButton>
<TButton
style={{
marginLeft: 10
}}
onClick={() => downloadPlanningCSV(
selectedProject ? selectedProject.id : props.selectedProjectId,
selectedProject ? selectedProject.label : summaryName)}
className="DownloadPlanning"
disabled={isDownloading}
startIcon={isDownloading ? <CircularProgress size={12}/> : <DownloadIcon/>}
variant="outlined" size="large" color='secondary'>
Download Planning
</TButton>
</div> : null }

Expand Down
28 changes: 14 additions & 14 deletions dashboard/webpack-stats.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
"name": "Space.44f2f4d6e7e91925f3ff.js",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/Space.44f2f4d6e7e91925f3ff.js"
},
"Summary.1d5de4efcefbf4fccaf4.js": {
"name": "Summary.1d5de4efcefbf4fccaf4.js",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/Summary.1d5de4efcefbf4fccaf4.js"
"Summary.7934e1f2debefbd93c76.js": {
"name": "Summary.7934e1f2debefbd93c76.js",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/Summary.7934e1f2debefbd93c76.js"
},
"PublicSummary.4b86fe25bffeea111241.js": {
"name": "PublicSummary.4b86fe25bffeea111241.js",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/PublicSummary.4b86fe25bffeea111241.js"
"PublicSummary.5cbe85b7eb7b4467623e.js": {
"name": "PublicSummary.5cbe85b7eb7b4467623e.js",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/PublicSummary.5cbe85b7eb7b4467623e.js"
},
"Planner.a4e0148d0d7b122496eb.js": {
"name": "Planner.a4e0148d0d7b122496eb.js",
Expand Down Expand Up @@ -181,17 +181,17 @@
"name": "Planner.a4e0148d0d7b122496eb.js.LICENSE.txt",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/Planner.a4e0148d0d7b122496eb.js.LICENSE.txt"
},
"PublicSummary.4b86fe25bffeea111241.js.LICENSE.txt": {
"name": "PublicSummary.4b86fe25bffeea111241.js.LICENSE.txt",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/PublicSummary.4b86fe25bffeea111241.js.LICENSE.txt"
"PublicSummary.5cbe85b7eb7b4467623e.js.LICENSE.txt": {
"name": "PublicSummary.5cbe85b7eb7b4467623e.js.LICENSE.txt",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/PublicSummary.5cbe85b7eb7b4467623e.js.LICENSE.txt"
},
"Space.44f2f4d6e7e91925f3ff.js.LICENSE.txt": {
"name": "Space.44f2f4d6e7e91925f3ff.js.LICENSE.txt",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/Space.44f2f4d6e7e91925f3ff.js.LICENSE.txt"
},
"Summary.1d5de4efcefbf4fccaf4.js.LICENSE.txt": {
"name": "Summary.1d5de4efcefbf4fccaf4.js.LICENSE.txt",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/Summary.1d5de4efcefbf4fccaf4.js.LICENSE.txt"
"Summary.7934e1f2debefbd93c76.js.LICENSE.txt": {
"name": "Summary.7934e1f2debefbd93c76.js.LICENSE.txt",
"path": "/Users/user/Documents/Kartoza/timesheet-project/dashboard/assets/webpack_bundles/Summary.7934e1f2debefbd93c76.js.LICENSE.txt"
}
},
"chunks": {
Expand All @@ -202,10 +202,10 @@
"Space.44f2f4d6e7e91925f3ff.js"
],
"Summary": [
"Summary.1d5de4efcefbf4fccaf4.js"
"Summary.7934e1f2debefbd93c76.js"
],
"PublicSummary": [
"PublicSummary.4b86fe25bffeea111241.js"
"PublicSummary.5cbe85b7eb7b4467623e.js"
],
"Planner": [
"Planner.a4e0148d0d7b122496eb.js"
Expand Down
45 changes: 42 additions & 3 deletions schedule/api_views/schedule.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import csv
import time

import pytz
from django.http import Http404
from django.http import Http404, HttpResponse
from rest_framework import serializers
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.response import Response
Expand Down Expand Up @@ -275,9 +276,9 @@ class ScheduleSerializer(serializers.ModelSerializer):

def get_user(self, obj: Schedule):
if obj.user:
return obj.user.first_name + obj.user.last_name
return obj.user.first_name + ' ' + obj.user.last_name
if obj.user_project and obj.user_project.user:
return obj.user_project.user.first_name + obj.user_project.user.last_name
return obj.user_project.user.first_name + ' ' + obj.user_project.user.last_name
return ''

def get_task_label(self, obj: Schedule):
Expand Down Expand Up @@ -654,3 +655,41 @@ def post(self, request):
'new': ScheduleSerializer(schedule, many=False).data,
'updated': ScheduleSerializer(schedules, many=True).data
})


class ScheduleCSVExport(APIView):
def get(self, request, project_id, user_id=None):
schedules = Schedule.objects.filter(
user_project__project_id=project_id,
)
if user_id:
schedules = schedules.filter(
user_project__user_id=user_id
)
schedules = schedules.distinct()
serializer = ScheduleSerializer(schedules, many=True)

response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="schedule.csv"'

writer = csv.writer(response)
writer.writerow([
'Project', 'User', 'Task', 'Start Time',
'End Time', 'Days', 'Notes', 'Hours Per Day'])

for schedule in serializer.data:
date1 = datetime.fromisoformat(schedule['start_time'].replace("Z", "+00:00"))
date2 = datetime.fromisoformat(schedule['end_time'].replace("Z", "+00:00"))
duration = (date2 - date1).days + 1
writer.writerow(
[
schedule['project_name'],
schedule['user'],
schedule['task_name'],
schedule['start_time'].split('T')[0],
schedule['end_time'].split('T')[0],
duration,
schedule['notes'],
schedule['hours_per_day'] if schedule['hours_per_day'] else '7'])

return response
8 changes: 7 additions & 1 deletion schedule/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
AddSchedule,
UpdateSchedule,
DeleteSchedule,
WeeklyScheduleList
WeeklyScheduleList, ScheduleCSVExport
)

urlpatterns = [
Expand Down Expand Up @@ -36,4 +36,10 @@
path('api/delete-schedule/',
DeleteSchedule.as_view(),
name='delete-schedule'),
path('api/schedule/csv/<int:project_id>/<int:user_id>/',
ScheduleCSVExport.as_view(),
name='schedule-csv-export-user'),
path('api/schedule/csv/<int:project_id>/',
ScheduleCSVExport.as_view(),
name='schedule-csv-export'),
]

0 comments on commit 372459f

Please sign in to comment.