Skip to content

Single page app front end conversion, diary and targets management #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a95d0be
Experimenting with a vue front end project
AustinGrey Dec 6, 2020
0212158
Continued work in converting from imperative js to declarative vue
AustinGrey Dec 7, 2020
03568c8
Allow ag-grid to work in vue, sync inputs and convert permissions for…
AustinGrey Dec 11, 2020
ddc71d9
Translate searching
AustinGrey Dec 11, 2020
7dd3100
Allow full ingredient CRUD
AustinGrey Dec 11, 2020
20a7289
Enable one page routing
AustinGrey Dec 11, 2020
f38fa49
Basic translation of the recipe manager
AustinGrey Dec 11, 2020
69de072
Getting recipe components set up as their own separate vue component
AustinGrey Dec 12, 2020
5f1fc1e
Set up synced data for components, fix float input selects
AustinGrey Dec 12, 2020
e17fdcc
Improve sync, use numbers where appropriate, fix button permissions
AustinGrey Dec 12, 2020
f9c92b4
Ensure unique key in v-for, handle decimals returned as strings
AustinGrey Dec 12, 2020
965598b
Use SCSS to simplify styling
AustinGrey Dec 12, 2020
523dff5
Improve diaryfood serializer to auto assign current user
AustinGrey Dec 12, 2020
4dd493f
Add target api
AustinGrey Aug 15, 2020
c231ec0
Setup masking
AustinGrey Dec 12, 2020
40329ea
Diaryfood and target api js connectors
AustinGrey Dec 12, 2020
c7378f3
Fix page title
AustinGrey Dec 13, 2020
341221c
Allow specifying diary date range in API
AustinGrey Dec 13, 2020
cbcdeef
Add mostly converted diary code
AustinGrey Dec 13, 2020
5a22159
Fix diary enough to compile
AustinGrey Dec 13, 2020
889f88e
Basic target manager, some cleanup
AustinGrey Dec 13, 2020
f9f4b30
Auto refactor of file for cleanliness
AustinGrey Dec 13, 2020
42048e4
Automatic refactor for cleanliness
AustinGrey Dec 13, 2020
72258cc
Create a checkbox element
AustinGrey Dec 15, 2020
013b6b4
Allow picking a target and filling the appropriate fields
AustinGrey Dec 15, 2020
814afb3
Get target creation up, with JS api namespacing
AustinGrey Dec 16, 2020
d811b3b
Complete CRUD operations for targets
AustinGrey Dec 16, 2020
43c574c
Fix bug where wrong key was specified
AustinGrey Dec 16, 2020
c0011a2
Cleanup diary imported code, setup time specificity properly, let use…
AustinGrey Dec 16, 2020
56d8719
Clear out tagify and chart js, add tables for known foods, and prep f…
AustinGrey Dec 16, 2020
b8f9abd
Setup oneoff food form
AustinGrey Dec 17, 2020
aa2dd1a
Create a target summary component
AustinGrey Dec 17, 2020
de831a7
Get daily target showing on diary page
AustinGrey Dec 17, 2020
0f702cd
Set server to UTC
AustinGrey Dec 18, 2020
5126bf9
Connect diary entries to front end, refactor js api
AustinGrey Dec 18, 2020
5c32bb8
Clean up time and amount form, fix input float select bug with value …
AustinGrey Dec 18, 2020
9311b74
Allow target summary to present a proposed change to the value to see…
AustinGrey Dec 18, 2020
182e49a
Better format target summary, scale proposed nutrients according to s…
AustinGrey Dec 19, 2020
688aeaa
Allow disabling float inputs, allow creating diary foods
AustinGrey Dec 20, 2020
e2fbbd8
Layout the diary to better show the different functions going on
AustinGrey Dec 20, 2020
10905c3
Fix some prop validation bugs, remove quick info section
AustinGrey Dec 20, 2020
9b0b79f
Allow target summary to accept an array of consituent parts for the v…
AustinGrey Dec 20, 2020
56b85fc
Allow highlighting previously recorded foods
AustinGrey Dec 21, 2020
5b1ce3e
Some auto cleanup
AustinGrey Dec 21, 2020
fc619f8
Properly setup diary to get time from input fields
AustinGrey Dec 22, 2020
6e4c508
Allow picking different time periods to view diary entries
AustinGrey Dec 26, 2020
781b6b6
Setup vue app to compile to the proper django directories to prepare …
AustinGrey Dec 26, 2020
c3e7f91
Support both token auth and basic auth as a manual fallback only.
AustinGrey Dec 26, 2020
963ff7c
Add a basic home app so the app doesn't look broken
AustinGrey Dec 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pants/diary/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
class DiaryFoodSerializer(serializers.HyperlinkedModelSerializer):
nutrition_data = serializers.ReadOnlyField()

def create(self, validated_data):
# Ensure the current user is specified
if 'user' not in validated_data:
validated_data['user'] = self.context['request'].user
return DiaryFood.objects.create(**validated_data)

class Meta:
model = DiaryFood

Expand Down
3 changes: 3 additions & 0 deletions pants/diary/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class DiaryFoodViewSet(viewsets.ModelViewSet):
serializer_class = DiaryFoodSerializer
permission_classes = [permissions.DjangoModelPermissions]
queryset = DiaryFood.objects.none() # Required for DjangoModelPermissions to get Model
filterset_fields = {
'start_time': ['gte', 'lte', 'exact', 'gt', 'lt'],
}

def get_queryset(self):
user = self.request.user
Expand Down
Binary file added pants/frontend/static/frontend/favicon.ico
Binary file not shown.
1,309 changes: 1,309 additions & 0 deletions pants/frontend/static/frontend/js/app.js

Large diffs are not rendered by default.

2,462 changes: 2,462 additions & 0 deletions pants/frontend/static/frontend/js/chunk-vendors.js

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions pants/frontend/templates/frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="/static/frontend/favicon.ico">
<title>Trouser - What goes over Pants</title>
<link href="/static/frontend/js/app.js" rel="preload" as="script"><link href="/static/frontend/js/chunk-vendors.js" rel="preload" as="script"></head>
<body>
<noscript>
<strong>We're sorry but Trouser - What goes over Pants doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="text/javascript" src="/static/frontend/js/chunk-vendors.js"></script><script type="text/javascript" src="/static/frontend/js/app.js"></script></body>
</html>
5 changes: 2 additions & 3 deletions pants/frontend/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django.conf.urls import url
from . import views
from django.views.generic import TemplateView

urlpatterns = [
url(r'^$', views.ingredient_manager, name='ingredient_manager'),
url(r'^recipe$', views.recipe_manager, name='recipe_manager')
url(r'^$', TemplateView.as_view(template_name="frontend/index.html"), name='frontend'),
]
21 changes: 0 additions & 21 deletions pants/frontend/views.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,2 @@
from django.shortcuts import render

def ingredient_manager(request):
context = {
#@todo austin Not sure how to handle this, the only way to define this template var is in python, but it will be executed in js, so it has to be a js string.
# Mask that ensures only 6 total digits, max 3 decimals
'nutrition_mask': r"{mask: /^(?=^[\d.]{0,7}$)\d{0,6}(\.\d{0,3})?$/}",
# Mask that ensures only lowercase letters, numbers and dashes
"slug_mask": r"{mask: /^[0-9a-z-]*$/}",
# Ensures only lowercase letters, numbers, dashes, and commas
"tag_mask": r"{mask: /^[0-9a-z,-]*$/}"
}
return render(request, 'frontend/ingredient_manager.html', context)

def recipe_manager(request):
context = {
# Mask that ensures only lowercase letters, numbers and dashes
"slug_mask": r"{mask: /^[0-9a-z-]*$/}",
# Ensures only lowercase letters, numbers, dashes, and commas
"tag_mask": r"{mask: /^[0-9a-z,-]*$/}"
}
return render(request, 'frontend/recipe_manager.html', context)

4 changes: 2 additions & 2 deletions pants/pants/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Australia/Melbourne'
#TIME_ZONE = 'UTC'
#TIME_ZONE = 'Australia/Melbourne'
TIME_ZONE = 'UTC'

USE_I18N = True

Expand Down
3 changes: 3 additions & 0 deletions pants/pants/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from django.contrib.auth import views as auth_views
from rest_framework import routers

from targets.views import TargetViewSet, DailyTargetViewSet
from website import views as website

# Viewsets for API added here, not in included 'app.urls' links
Expand All @@ -35,6 +36,8 @@
router.register(r'recipe_tag', RecipeTagViewSet, 'recipe_tag')
router.register(r'recipe_flag', RecipeFlagViewSet, 'recipe_flag')
router.register(r'diaryfood', DiaryFoodViewSet, 'diaryfood')
router.register(r'target', TargetViewSet, 'target')
router.register(r'daily_target', DailyTargetViewSet, 'daily_target')
router.register(r'user', UserViewSet, 'user')

urlpatterns = [
Expand Down
66 changes: 66 additions & 0 deletions pants/targets/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from django.db import transaction
from rest_framework import serializers

from targets.models import Target, Minimums, Maximums


class MaximumsSerializer(serializers.ModelSerializer):
class Meta:
model = Maximums
exclude = ['of_target', 'id']


class MinimumsSerializer(serializers.ModelSerializer):
class Meta:
model = Minimums
exclude = ['of_target', 'id']


class TargetSerializer(serializers.HyperlinkedModelSerializer):
"""
Serialize a target
"""
minimum = MinimumsSerializer()
maximum = MaximumsSerializer()

class Meta:
model = Target
fields = '__all__'
read_only_fields = ['user']

@transaction.atomic
def create(self, validated_data):
user = self.context['request'].user # FIXME needs to be passed as extra context
# Take min and max data off, save remainder as target, then save min and max
min_data = validated_data.pop('minimum')
max_data = validated_data.pop('maximum')
target = Target.objects.create(
user=user,
**validated_data)
min_data["of_target_id"] = target.id
max_data["of_target_id"] = target.id
min = Minimums.objects.create(**min_data)
target.minimum = min
max = Maximums.objects.create(**max_data)
target.maximum = max
return target

@transaction.atomic
def update(self, target, validated_data):
# Get all the requested update fields except for the nested objects
update_fields = [key for key in validated_data.keys() if key not in ['minimum', 'maximum']]
for key in update_fields:
setattr(target, key, validated_data[key])
target.save(update_fields=update_fields)

if ('minimum' in validated_data):
for key in validated_data['minimum']:
setattr(target.minimum, key, validated_data['minimum'][key])
target.minimum.save()

if ('maximum' in validated_data):
for key in validated_data['maximum']:
setattr(target.maximum, key, validated_data['maximum'][key])
target.maximum.save()

return target
27 changes: 27 additions & 0 deletions pants/targets/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from rest_framework import viewsets, permissions

from .models import Target

# Basic class views. Targets are used more from other models to
# compare to.
# TODO templates
from .serializers import TargetSerializer


class TargetListView(LoginRequiredMixin, ListView):
model = Target
Expand All @@ -25,3 +28,27 @@ def get_context_data(self, **kwargs):
context = super(IngredientDetailView, self).get_context_data(**kwargs)
return context

class TargetViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows targets to be viewed and altered.
"""
serializer_class = TargetSerializer
permission_classes = [permissions.DjangoModelPermissions]
queryset = Target.objects.none() # Required for DjangoModelPermissions to get Model

def get_queryset(self):
user = self.request.user
return Target.objects.filter(user=user)

class DailyTargetViewSet(viewsets.ReadOnlyModelViewSet):
"""
API endpoint to get current daily target
"""
serializer_class = TargetSerializer
permission_classes = [permissions.DjangoModelPermissions]
queryset = Target.objects.none() # Required for DjangoModelPermissions to get Model

def get_queryset(self):
user = self.request.user
# @todo how to return just the exact daily target, or limit the results to 1
return Target.objects.filter(user=user, daily_target=True)
1 change: 1 addition & 0 deletions trouser/.env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VUE_APP_STATIC_URL=/static/frontend/
1 change: 1 addition & 0 deletions trouser/.env.staging
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VUE_APP_STATIC_URL=/static/frontend/
23 changes: 23 additions & 0 deletions trouser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
24 changes: 24 additions & 0 deletions trouser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# trouser

## Project setup
```
yarn install
```

### Compiles and hot-reloads for development
```
yarn serve
```

### Compiles and minifies for production
```
yarn build
```

### Lints and fixes files
```
yarn lint
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
5 changes: 5 additions & 0 deletions trouser/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
Loading