Skip to content

Commit

Permalink
started work on supermarket edit view
Browse files Browse the repository at this point in the history
  • Loading branch information
vabene1111 committed May 31, 2021
1 parent 040af33 commit 6fc0c02
Show file tree
Hide file tree
Showing 20 changed files with 715 additions and 51 deletions.
79 changes: 43 additions & 36 deletions cookbook/static/vue/js/chunk-vendors.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cookbook/static/vue/js/import_response_view.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cookbook/static/vue/js/offline_view.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cookbook/static/vue/js/recipe_search_view.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cookbook/static/vue/js/recipe_view.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cookbook/static/vue/js/supermarket_view.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cookbook/static/vue/supermarket_view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Vue App</title><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="js/supermarket_view.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="Recipes"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><div id="app"></div><script src="js/chunk-vendors.js"></script></body></html>
36 changes: 36 additions & 0 deletions cookbook/templates/supermarket.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% extends "base.html" %}
{% load render_bundle from webpack_loader %}
{% load static %}
{% load i18n %}
{% load l10n %}

{% block title %}{% trans 'Supermarket' %}{% endblock %}

{% block extra_head %}
<link rel="stylesheet" href="{% static 'css/vue-multiselect-bs4.min.css' %}">
{% endblock %}

{% block content %}

<div id="app" >
<supermarket-view></supermarket-view>
</div>


{% endblock %}


{% block script %}
{% if debug %}
<script src="{% url 'js_reverse' %}"></script>
{% else %}
<script src="{% static 'django_js_reverse/reverse.js' %}"></script>
{% endif %}

<script type="application/javascript">

window.CUSTOM_LOCALE = '{{ request.LANGUAGE_CODE }}'
</script>

{% render_bundle 'supermarket_view' %}
{% endblock %}
2 changes: 1 addition & 1 deletion cookbook/templates/sw.js

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions cookbook/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@
router.register(r'recipe-book', api.RecipeBookViewSet)
router.register(r'recipe-book-entry', api.RecipeBookEntryViewSet)
router.register(r'supermarket', api.SupermarketViewSet)
router.register(r'supermarket-category', api.SupermarketCategoryViewSet)
router.register(r'import-log', api.ImportLogViewSet)
router.register(r'bookmarklet-import', api.BookmarkletImportViewSet)

urlpatterns = [
path('', views.index, name='index'),
path('setup/', views.setup, name='view_setup'),
path('space/', views.space, name='view_space'),
path('space/member/<int:user_id>/<int:space_id>/<slug:group>', views.space_change_member, name='change_space_member'),
path('space/member/<int:user_id>/<int:space_id>/<slug:group>', views.space_change_member,
name='change_space_member'),
path('no-group', views.no_groups, name='view_no_group'),
path('no-space', views.no_space, name='view_no_space'),
path('no-perm', views.no_perm, name='view_no_perm'),
Expand All @@ -58,6 +60,7 @@
path('shopping/latest/', views.latest_shopping_list, name='view_shopping_latest'),
path('settings/', views.user_settings, name='view_settings'),
path('history/', views.history, name='view_history'),
path('supermarket/', views.supermarket, name='view_supermarket'),
path('test/', views.test, name='view_test'),
path('test2/', views.test2, name='view_test2'),

Expand Down Expand Up @@ -111,15 +114,18 @@
path('docs/markdown/', views.markdown_info, name='docs_markdown'),
path('docs/api/', views.api_info, name='docs_api'),

path('openapi/', get_schema_view(title="Django Recipes", version=VERSION_NUMBER, public=True, permission_classes=(permissions.AllowAny,)), name='openapi-schema'),
path('openapi/', get_schema_view(title="Django Recipes", version=VERSION_NUMBER, public=True,
permission_classes=(permissions.AllowAny,)), name='openapi-schema'),

path('api/', include((router.urls, 'api'))),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),

path('offline/', views.offline, name='view_offline'),

path('service-worker.js', (TemplateView.as_view(template_name="sw.js", content_type='application/javascript', )), name='service_worker'),
path('manifest.json', (TemplateView.as_view(template_name="manifest.json", content_type='application/json', )), name='web_manifest'),
path('service-worker.js', (TemplateView.as_view(template_name="sw.js", content_type='application/javascript', )),
name='service_worker'),
path('manifest.json', (TemplateView.as_view(template_name="manifest.json", content_type='application/json', )),
name='web_manifest'),
]

generic_models = (
Expand Down
20 changes: 16 additions & 4 deletions cookbook/views/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
MealType, Recipe, RecipeBook, ShoppingList,
ShoppingListEntry, ShoppingListRecipe, Step,
Storage, Sync, SyncLog, Unit, UserPreference,
ViewLog, RecipeBookEntry, Supermarket, ImportLog, BookmarkletImport)
ViewLog, RecipeBookEntry, Supermarket, ImportLog, BookmarkletImport, SupermarketCategory)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
Expand All @@ -56,7 +56,7 @@
UserNameSerializer, UserPreferenceSerializer,
ViewLogSerializer, CookLogSerializer, RecipeBookEntrySerializer,
RecipeOverviewSerializer, SupermarketSerializer, ImportLogSerializer,
BookmarkletImportSerializer)
BookmarkletImportSerializer, SupermarketCategorySerializer)
from recipes.settings import DEMO


Expand Down Expand Up @@ -158,6 +158,16 @@ def get_queryset(self):
return super().get_queryset()


class SupermarketCategoryViewSet(viewsets.ModelViewSet, StandardFilterMixin):
queryset = SupermarketCategory.objects
serializer_class = SupermarketCategorySerializer
permission_classes = [CustomIsUser]

def get_queryset(self):
self.queryset = self.queryset.filter(space=self.request.space)
return super().get_queryset()


class KeywordViewSet(viewsets.ModelViewSet, StandardFilterMixin):
"""
list:
Expand Down Expand Up @@ -288,7 +298,7 @@ class RecipeSchema(AutoSchema):

def get_path_parameters(self, path, method):
if not is_list_view(path, method, self.view):
return super(RecipeSchema, self).get_path_parameters(path,method)
return super(RecipeSchema, self).get_path_parameters(path, method)

parameters = super().get_path_parameters(path, method)
parameters.append({
Expand Down Expand Up @@ -655,7 +665,9 @@ def recipe_from_source(request):
return JsonResponse(
{
'error': True,
'msg': _('The requested site does not provide any recognized data format to import the recipe from.') # noqa: E501
'msg': _(
'The requested site does not provide any recognized data format to import the recipe from.')
# noqa: E501
},
status=400)
else:
Expand Down
5 changes: 5 additions & 0 deletions cookbook/views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ def meal_plan(request):
return render(request, 'meal_plan.html', {})


@group_required('user')
def supermarket(request):
return render(request, 'supermarket.html', {})


@group_required('user')
def meal_plan_entry(request, pk):
plan = MealPlan.objects.filter(space=request.space).get(pk=pk)
Expand Down
1 change: 1 addition & 0 deletions vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"vue-multiselect": "^2.1.6",
"vue-property-decorator": "^9.1.2",
"vue-template-compiler": "^2.6.12",
"vuedraggable": "^2.24.3",
"vuex": "^3.6.0",
"workbox-webpack-plugin": "^6.1.5"
},
Expand Down
160 changes: 160 additions & 0 deletions vue/src/apps/SupermarketView/SupermarketView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<template>

<div id="app">

<div class="row">

<div class="col col-md-12">
<h2>{{ $t('Supermarket') }}</h2>

<multiselect v-model="selected_supermarket" track-by="id" label="name"
:options="supermarkets">
</multiselect>

<b-button class="btn btn-primary btn-block" style="margin-top: 1vh" v-b-modal.modal-supermarket>
{{ $t('Edit') }}
</b-button>
<b-button class="btn btn-success btn-block" @click="selected_supermarket = {new:true, name:''}"
v-b-modal.modal-supermarket>{{ $t('New') }}
</b-button>
</div>
</div>

<hr>

<div class="row">
<div class="col col-md-6">
<h4>{{ $t('Categories') }}
<button class="btn btn-success btn-sm">{{ $t('New') }}</button>
</h4>

<draggable :list="categories" group="supermarket_categories"
:empty-insert-threshold="10">
<div v-for="c in categories" :key="c.id">
<button class="btn btn-block btn-sm btn-primary" style="margin-top: 0.5vh">{{ c.name }}</button>

</div>
</draggable>


</div>
<div class="col col-md-6">
<h4>{{ $t('Selected') }} {{ $t('Categories') }}</h4>

<draggable :list="selected_categories" group="supermarket_categories"
:empty-insert-threshold="10">
<div v-for="c in selected_categories" :key="c.id">
<button class="btn btn-block btn-sm btn-primary" style="margin-top: 0.5vh">{{ c.name }}</button>

</div>
</draggable>
</div>
</div>

<!-- EDIT MODALS -->
<b-modal id="modal-supermarket" v-bind:title="$t('Supermarket')" @ok="supermarketModalOk()">
<label v-if="selected_supermarket !== undefined">
{{ $t('Name') }}
<b-input v-model="selected_supermarket.name"></b-input>

</label>
</b-modal>

<b-modal id="modal-category" v-bind:title="$t('Category')" @ok="categoryModalOk()">
<label v-if="selected_supermarket !== undefined">
{{ $t('Name') }}
<b-input v-model="selected_supermarket.name"></b-input>

</label>
</b-modal>

</div>
</template>

<script>
import Vue from 'vue'
import {BootstrapVue} from 'bootstrap-vue'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import {ResolveUrlMixin, ToastMixin} from "@/utils/utils";
import {ApiApiFactory} from "@/utils/openapi/api.ts";
Vue.use(BootstrapVue)
import draggable from 'vuedraggable'
import axios from 'axios'
import Multiselect from "vue-multiselect";
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
axios.defaults.xsrfCookieName = 'csrftoken'
export default {
name: 'SupermarketView',
mixins: [
ResolveUrlMixin,
ToastMixin,
],
components: {
Multiselect,
draggable
},
data() {
return {
supermarkets: [],
categories: [],
selected_supermarket: {},
selected_categories: [],
}
},
mounted() {
this.$i18n.locale = window.CUSTOM_LOCALE
console.log('LOADED')
this.loadInitial()
},
methods: {
loadInitial: function () {
let apiClient = new ApiApiFactory()
apiClient.listSupermarkets().then(results => {
this.supermarkets = results.data
})
apiClient.listSupermarketCategorys().then(results => {
this.categories = results.data
})
},
supermarketModalOk: function () {
let apiClient = new ApiApiFactory()
if (this.selected_supermarket.new) {
apiClient.createSupermarket({name: this.selected_supermarket.name}).then(results => {
this.selected_supermarket = undefined
this.loadInitial()
})
} else {
apiClient.partialUpdateSupermarket(this.selected_supermarket.id, {name: this.selected_supermarket.name})
}
},
categoryModalOk: function () {
let apiClient = new ApiApiFactory()
if (this.selected_supermarket.new) {
apiClient.createSupermarket({name: this.selected_supermarket.name}).then(results => {
this.selected_supermarket = undefined
this.loadInitial()
})
} else {
apiClient.partialUpdateSupermarket(this.selected_supermarket.id, {name: this.selected_supermarket.name})
}
}
}
}
</script>

<style>
</style>
10 changes: 10 additions & 0 deletions vue/src/apps/SupermarketView/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Vue from 'vue'
import App from './SupermarketView.vue'
import i18n from '@/i18n'

Vue.config.productionTip = false

new Vue({
i18n,
render: h => h(App),
}).$mount('#app')
4 changes: 4 additions & 0 deletions vue/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
"Add": "Add",
"New": "New",
"Ingredients": "Ingredients",
"Supermarket": "Supermarket",
"Categories": "Categories",
"Category": "Category",
"Selected": "Selected",
"min": "min",
"Servings": "Servings",
"Waiting": "Waiting",
Expand Down
Loading

0 comments on commit 6fc0c02

Please sign in to comment.