Merge branch 'feature/deletemany' into develop
This commit is contained in:
@@ -1265,6 +1265,25 @@ class ForceCurveMultipleCompareForm(forms.Form):
|
|||||||
widget=forms.CheckboxSelectMultiple()
|
widget=forms.CheckboxSelectMultiple()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bulkactions = (
|
||||||
|
('remove','remove'),
|
||||||
|
('export','export'),
|
||||||
|
)
|
||||||
|
destinations = (
|
||||||
|
('C2','C2'),
|
||||||
|
('strava','strava'),
|
||||||
|
('sporttracks','sporttracks'),
|
||||||
|
('trainingpeaks','trainingpeaks')
|
||||||
|
)
|
||||||
|
|
||||||
|
class WorkoutBulkActions(forms.Form):
|
||||||
|
action = forms.ChoiceField(
|
||||||
|
choices=bulkactions, label='Action', required=True, initial='remove')
|
||||||
|
|
||||||
|
class ExportChoices(forms.Form):
|
||||||
|
destination = forms.ChoiceField(
|
||||||
|
choices=destinations, label='Destination', required=False, initial='strava'
|
||||||
|
)
|
||||||
|
|
||||||
class WorkoutMultipleCompareForm(forms.Form):
|
class WorkoutMultipleCompareForm(forms.Form):
|
||||||
workouts = forms.ModelMultipleChoiceField(
|
workouts = forms.ModelMultipleChoiceField(
|
||||||
|
|||||||
@@ -79,12 +79,35 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if not request.GET.selectworkouts %}
|
||||||
|
<span>
|
||||||
|
<a href="./?selectworkouts=true">Bulk Actions</a>
|
||||||
|
</span>
|
||||||
|
{% else %}
|
||||||
|
<span>
|
||||||
|
<a href="./">Close Bulk Actions</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% if workouts %}
|
{% if workouts %}
|
||||||
|
{% if request.GET.selectworkouts %}
|
||||||
|
<li class="grid_4">
|
||||||
|
<form enctype="multipart/form-data" method="post">
|
||||||
|
<h3>Bulk Operation</h3>
|
||||||
|
<p>Please select workouts from the list to do a bulk operation on.</p>
|
||||||
|
{{ actionform.as_p }}
|
||||||
|
{% csrf_token %}
|
||||||
|
<input name='selectworkouts' type="submit" value="Submit">
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% for workout in workouts %}
|
{% for workout in workouts %}
|
||||||
<li class="grid_4 divlines">
|
<li class="grid_4 divlines">
|
||||||
|
{% if request.GET.selectworkouts %}
|
||||||
|
<input type="checkbox" id="workoutid" value={{ workout.id|encode }} name="workoutid" />
|
||||||
|
{% endif %}
|
||||||
{{ workout.date|date:"Y-m-d" }} {{ workout.starttime|date:"H:i" }}
|
{{ workout.date|date:"Y-m-d" }} {{ workout.starttime|date:"H:i" }}
|
||||||
{% if workout.duplicate %}
|
{% if workout.duplicate %}
|
||||||
<span style="font-size: smaller"><i class="fal fa-angle-double-up"></i></span>
|
<span style="font-size: smaller"><i class="fal fa-angle-double-up"></i></span>
|
||||||
@@ -181,6 +204,9 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<li> No workouts found </li>
|
<li> No workouts found </li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if request.GET.selectworkouts %}
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
<li class="grid_4">
|
<li class="grid_4">
|
||||||
<p>Filter on date
|
<p>Filter on date
|
||||||
<form enctype="multipart/form-data" method="post">
|
<form enctype="multipart/form-data" method="post">
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{% extends "newbase.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block title %}Change Workout {% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<h1>Bulk Actions</h1>
|
||||||
|
<ul class="main-content">
|
||||||
|
<li class="grid_4">
|
||||||
|
<form action="" method="post">
|
||||||
|
<p>
|
||||||
|
Edit and confirm the action you want to perform on the following workouts:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{ form.as_p }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{ actionform.as_p }}
|
||||||
|
</p>
|
||||||
|
{% if action == 'export' %}
|
||||||
|
<p>
|
||||||
|
{{ exportchoice.as_p }}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
<li class="grid_2">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="submit" value="Confirm">
|
||||||
|
</li>
|
||||||
|
</form>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block sidebar %}
|
||||||
|
{% include 'menu_workout.html' %}
|
||||||
|
{% endblock %}
|
||||||
BIN
Binary file not shown.
@@ -292,6 +292,9 @@ urlpatterns = [
|
|||||||
views.agegrouprecordview, name='agegrouprecordview'),
|
views.agegrouprecordview, name='agegrouprecordview'),
|
||||||
re_path(r'^agegrouprecords/$',
|
re_path(r'^agegrouprecords/$',
|
||||||
views.agegrouprecordview, name='agegrouprecordview'),
|
views.agegrouprecordview, name='agegrouprecordview'),
|
||||||
|
re_path(r'^workouts/actions/$',
|
||||||
|
views.workouts_bulk_actions,
|
||||||
|
name='workouts_bulk_actions'),
|
||||||
re_path(r'^workouts/setrpe/$', views.workouts_setrpe_view,
|
re_path(r'^workouts/setrpe/$', views.workouts_setrpe_view,
|
||||||
name='workouts_setrpe_view'),
|
name='workouts_setrpe_view'),
|
||||||
re_path(r'^workouts/setrpe/user/(?P<userid>\d+)/$', views.workouts_setrpe_view,
|
re_path(r'^workouts/setrpe/user/(?P<userid>\d+)/$', views.workouts_setrpe_view,
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ from django.http import (
|
|||||||
)
|
)
|
||||||
from django.contrib.auth import authenticate, login, logout
|
from django.contrib.auth import authenticate, login, logout
|
||||||
from rowers.forms import (
|
from rowers.forms import (
|
||||||
|
WorkoutBulkActions, ExportChoices,
|
||||||
ForceCurveOptionsForm, HistoForm, TeamMessageForm,
|
ForceCurveOptionsForm, HistoForm, TeamMessageForm,
|
||||||
LoginForm, DocumentsForm, UploadOptionsForm, ImageForm, CourseForm,
|
LoginForm, DocumentsForm, UploadOptionsForm, ImageForm, CourseForm,
|
||||||
CourseConfirmForm, ResampleForm,
|
CourseConfirmForm, ResampleForm,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from shutil import copyfile
|
|||||||
from rowers.views.statements import *
|
from rowers.views.statements import *
|
||||||
|
|
||||||
import rowers.mytypes as mytypes
|
import rowers.mytypes as mytypes
|
||||||
|
from rowers.integrations import importsources
|
||||||
import numpy
|
import numpy
|
||||||
import rowers.uploads as uploads
|
import rowers.uploads as uploads
|
||||||
import rowers.utils as utils
|
import rowers.utils as utils
|
||||||
@@ -2031,6 +2032,63 @@ def workouts_setrpe_view(request,userid=0):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# Workout bulk actions
|
||||||
|
@login_required()
|
||||||
|
def workouts_bulk_actions(request):
|
||||||
|
r = getrower(request.user)
|
||||||
|
action = request.session['action']
|
||||||
|
workoutids = request.session['ids']
|
||||||
|
workouts = []
|
||||||
|
try:
|
||||||
|
for encid in workoutids:
|
||||||
|
w = get_workout_by_opaqueid(request, encid)
|
||||||
|
if w.user == r:
|
||||||
|
workouts.append(w)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
actionform = WorkoutBulkActions(request.POST)
|
||||||
|
form = WorkoutMultipleCompareForm(request.POST)
|
||||||
|
if form.is_valid() and actionform.is_valid():
|
||||||
|
workouts = form.cleaned_data['workouts']
|
||||||
|
action = actionform.cleaned_data['action']
|
||||||
|
if action == 'remove':
|
||||||
|
for w in workouts:
|
||||||
|
messages.info(request,'Removed workout '+str(encoder.encode_hex(w.id)))
|
||||||
|
w.delete()
|
||||||
|
elif action == 'export':
|
||||||
|
exportchoice = ExportChoices(request.POST)
|
||||||
|
if exportchoice.is_valid():
|
||||||
|
destination = exportchoice.cleaned_data['destination']
|
||||||
|
for w in workouts:
|
||||||
|
integration = importsources[destination](request.user)
|
||||||
|
try:
|
||||||
|
id = integration.workout_export(w)
|
||||||
|
messages.info(request,'Workout {id} exported to {destination}'.format(id=encoder.encode_hex(w.id),
|
||||||
|
destination=destination))
|
||||||
|
except NoTokenError:
|
||||||
|
messages.error(request,'Export to {destination} of workout {id} failed'.format(id=encoder.encode_hex(w.id),
|
||||||
|
destination=destination))
|
||||||
|
url = reverse('workouts_view')
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
else:
|
||||||
|
exportchoice = ExportChoices()
|
||||||
|
actionform = WorkoutBulkActions()
|
||||||
|
actionform.fields["action"].initial = action
|
||||||
|
form = WorkoutMultipleCompareForm()
|
||||||
|
form.fields["workouts"].queryset = Workout.objects.filter(id__in=[w.id for w in workouts])
|
||||||
|
form.fields["workouts"].initial = workouts
|
||||||
|
|
||||||
|
|
||||||
|
return render(request,'workout_bulk_actions.html',
|
||||||
|
{'action':action,
|
||||||
|
'exportchoice':exportchoice,
|
||||||
|
'actionform':actionform,
|
||||||
|
'form':form,
|
||||||
|
'workouts':workouts})
|
||||||
|
|
||||||
# List Workouts
|
# List Workouts
|
||||||
@login_required()
|
@login_required()
|
||||||
def workouts_view(request, message='', successmessage='',
|
def workouts_view(request, message='', successmessage='',
|
||||||
@@ -2047,7 +2105,13 @@ def workouts_view(request, message='', successmessage='',
|
|||||||
enddate = datetime.datetime.combine(enddate, datetime.time(23, 59, 59))
|
enddate = datetime.datetime.combine(enddate, datetime.time(23, 59, 59))
|
||||||
|
|
||||||
query = None
|
query = None
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
if 'selectworkouts' in request.POST:
|
||||||
|
request.session['action']=request.POST['action']
|
||||||
|
request.session['ids'] = request.POST.getlist('workoutid')
|
||||||
|
url = reverse('workouts_bulk_actions')
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
dateform = DateRangeForm(request.POST)
|
dateform = DateRangeForm(request.POST)
|
||||||
searchform = SearchForm(request.POST)
|
searchform = SearchForm(request.POST)
|
||||||
if dateform.is_valid(): # pragma: no cover
|
if dateform.is_valid(): # pragma: no cover
|
||||||
@@ -2227,10 +2291,13 @@ def workouts_view(request, message='', successmessage='',
|
|||||||
Click <a href="/rowers/workouts/setrpe">here</a> to update them. \
|
Click <a href="/rowers/workouts/setrpe">here</a> to update them. \
|
||||||
You can switch off this warning in <a href="/rowers/me/edit">settings</a>.')
|
You can switch off this warning in <a href="/rowers/me/edit">settings</a>.')
|
||||||
|
|
||||||
|
actionform = WorkoutBulkActions()
|
||||||
|
|
||||||
return render(request, 'list_workouts.html',
|
return render(request, 'list_workouts.html',
|
||||||
{'workouts': workouts,
|
{'workouts': workouts,
|
||||||
'active': 'nav-workouts',
|
'active': 'nav-workouts',
|
||||||
'rower': r,
|
'rower': r,
|
||||||
|
'actionform': actionform,
|
||||||
'searchform': searchform,
|
'searchform': searchform,
|
||||||
'breadcrumbs': breadcrumbs,
|
'breadcrumbs': breadcrumbs,
|
||||||
'dateform': dateform,
|
'dateform': dateform,
|
||||||
|
|||||||
Reference in New Issue
Block a user