diff --git a/cookbook/serializer.py b/cookbook/serializer.py
index 62f18526..98c88df6 100644
--- a/cookbook/serializer.py
+++ b/cookbook/serializer.py
@@ -146,21 +146,20 @@ class UserPreferenceSerializer(serializers.ModelSerializer):
class UserFileSerializer(serializers.ModelSerializer):
def check_file_limit(self, validated_data):
- if self.context['request'].space.max_file_storage_mb == -1:
- raise ValidationError(_('File uploads are not enabled for this Space.'))
+ if 'file' in validated_data:
+ if self.context['request'].space.max_file_storage_mb == -1:
+ raise ValidationError(_('File uploads are not enabled for this Space.'))
- try:
- current_file_size_mb = \
- UserFile.objects.filter(space=self.context['request'].space).aggregate(Sum('file_size_kb'))[
- 'file_size_kb__sum'] / 1000
- except TypeError:
- current_file_size_mb = 0
+ try:
+ current_file_size_mb = \
+ UserFile.objects.filter(space=self.context['request'].space).aggregate(Sum('file_size_kb'))[
+ 'file_size_kb__sum'] / 1000
+ except TypeError:
+ current_file_size_mb = 0
- if (
- (validated_data['file'].size / 1000 / 1000 + current_file_size_mb - 5)
- > self.context['request'].space.max_file_storage_mb != 0
- ):
- raise ValidationError(_('You have reached your file upload limit.'))
+ if ((validated_data['file'].size / 1000 / 1000 + current_file_size_mb - 5)
+ > self.context['request'].space.max_file_storage_mb != 0):
+ raise ValidationError(_('You have reached your file upload limit.'))
def create(self, validated_data):
self.check_file_limit(validated_data)
diff --git a/cookbook/urls.py b/cookbook/urls.py
index 87fea1ce..f66d487d 100644
--- a/cookbook/urls.py
+++ b/cookbook/urls.py
@@ -10,7 +10,7 @@ from cookbook.helper import dal
from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe,
RecipeBook, RecipeBookEntry, RecipeImport, ShoppingList,
- Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, get_model_name, Automation)
+ Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, get_model_name, Automation, UserFile)
from .views import api, data, delete, edit, import_export, lists, new, views, telegram
router = routers.DefaultRouter()
@@ -179,7 +179,7 @@ for m in generic_models:
)
)
-vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory, Automation]
+vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory, Automation, UserFile]
for m in vue_models:
py_name = get_model_name(m)
url_name = py_name.replace('_', '-')
diff --git a/cookbook/views/lists.py b/cookbook/views/lists.py
index 212d6e42..4fd547d7 100644
--- a/cookbook/views/lists.py
+++ b/cookbook/views/lists.py
@@ -200,6 +200,20 @@ def automation(request):
)
+@group_required('user')
+def user_file(request):
+ return render(
+ request,
+ 'generic/model_template.html',
+ {
+ "title": _("Files"),
+ "config": {
+ 'model': "USERFILE", # *REQUIRED* name of the model in models.js
+ }
+ }
+ )
+
+
@group_required('user')
def shopping_list_new(request):
# recipe-param is the name of the parameters used when filtering recipes by this attribute
@@ -213,4 +227,4 @@ def shopping_list_new(request):
'model': "SHOPPING_LIST", # *REQUIRED* name of the model in models.js
}
}
- )
\ No newline at end of file
+ )
diff --git a/vue/src/apps/ChecklistView/ChecklistView.vue b/vue/src/apps/ChecklistView/ChecklistView.vue
index bf1bfbd9..afbc241a 100644
--- a/vue/src/apps/ChecklistView/ChecklistView.vue
+++ b/vue/src/apps/ChecklistView/ChecklistView.vue
@@ -121,7 +121,6 @@ export default {
case this.Actions.UPDATE:
update = e.form_data
update.id = this.this_item.id
- console.log('form', update)
this.saveThis(update)
break;
case this.Actions.MERGE:
diff --git a/vue/src/apps/ModelListView/ModelListView.vue b/vue/src/apps/ModelListView/ModelListView.vue
index a470e24c..865a2905 100644
--- a/vue/src/apps/ModelListView/ModelListView.vue
+++ b/vue/src/apps/ModelListView/ModelListView.vue
@@ -237,7 +237,6 @@ export default {
case this.Actions.UPDATE:
update = e.form_data
update.id = this.this_item.id
- console.log('form', update)
this.saveThis(update)
break;
case this.Actions.MERGE:
diff --git a/vue/src/components/FileViewer.vue b/vue/src/components/FileViewer.vue
new file mode 100644
index 00000000..9643d807
--- /dev/null
+++ b/vue/src/components/FileViewer.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/vue/src/components/Modals/FileInput.vue b/vue/src/components/Modals/FileInput.vue
new file mode 100644
index 00000000..14315cb3
--- /dev/null
+++ b/vue/src/components/Modals/FileInput.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vue/src/components/Modals/GenericModalForm.vue b/vue/src/components/Modals/GenericModalForm.vue
index e03d3224..20571bc1 100644
--- a/vue/src/components/Modals/GenericModalForm.vue
+++ b/vue/src/components/Modals/GenericModalForm.vue
@@ -1,49 +1,55 @@
-
-
- {{form.title}}
-
-
{{f.label}}
-
-
-
-
-
-
-
-
-
-
- {{$t('Cancel')}}
- {{form.ok_label}}
-
-
-
+
+
+ {{ form.title }}
+
+
{{ f.label }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('Cancel') }}
+ {{ form.ok_label }}
+
+
+
\ No newline at end of file
diff --git a/vue/src/locales/en.json b/vue/src/locales/en.json
index 4f051651..c7c6bea1 100644
--- a/vue/src/locales/en.json
+++ b/vue/src/locales/en.json
@@ -30,6 +30,7 @@
"Manage_Books": "Manage Books",
"Meal_Plan": "Meal Plan",
"Select_Book": "Select Book",
+ "Select_File": "Select File",
"Recipe_Image": "Recipe Image",
"Import_finished": "Import finished",
"View_Recipes": "View Recipes",
@@ -92,6 +93,7 @@
"Files": "Files",
"File": "File",
"Edit": "Edit",
+ "Image": "Image",
"Delete": "Delete",
"Open": "Open",
"Ok": "Open",
diff --git a/vue/src/utils/models.js b/vue/src/utils/models.js
index da2a1dd2..b03b5c82 100644
--- a/vue/src/utils/models.js
+++ b/vue/src/utils/models.js
@@ -113,6 +113,7 @@ export class Models {
},
}
+
static KEYWORD = {
'name': i18n.t('Keyword'), // *OPTIONAL: parameters will be built model -> model_type -> default
'apiName': 'Keyword',
@@ -150,6 +151,7 @@ export class Models {
}
},
}
+
static UNIT = {
'name': i18n.t('Unit'),
'apiName': 'Unit',
@@ -175,10 +177,12 @@ export class Models {
},
'merge': true
}
+
static SHOPPING_LIST = {
'name': i18n.t('Shopping_list'),
'apiName': 'ShoppingListEntry',
}
+
static RECIPE_BOOK = {
'name': i18n.t('Recipe_Book'),
'apiName': 'RecipeBook',
@@ -208,6 +212,7 @@ export class Models {
}
},
}
+
static SHOPPING_CATEGORY = {
'name': i18n.t('Shopping_Category'),
'apiName': 'SupermarketCategory',
@@ -231,6 +236,7 @@ export class Models {
}
},
}
+
static SHOPPING_CATEGORY_RELATION = {
'name': i18n.t('Shopping_Category_Relation'),
'apiName': 'SupermarketCategoryRelation',
@@ -254,6 +260,7 @@ export class Models {
}
},
}
+
static SUPERMARKET = {
'name': i18n.t('Supermarket'),
'apiName': 'Supermarket',
@@ -395,6 +402,31 @@ export class Models {
},
}
+
+ static USERFILE = {
+ 'name': i18n.t('File'),
+ 'apiName': 'UserFile',
+ 'paginated': false,
+ 'create': {
+ 'params': ['name', 'file',],
+ 'form': {
+ 'name': {
+ 'form_field': true,
+ 'type': 'text',
+ 'field': 'name',
+ 'label': i18n.t('Name'),
+ 'placeholder': ''
+ },
+ 'file': {
+ 'form_field': true,
+ 'type': 'file',
+ 'field': 'file',
+ 'label': i18n.t('File'),
+ 'placeholder': ''
+ },
+ }
+ },
+ }
}
diff --git a/vue/src/utils/utils.js b/vue/src/utils/utils.js
index 26b41f79..389da0b8 100644
--- a/vue/src/utils/utils.js
+++ b/vue/src/utils/utils.js
@@ -165,6 +165,7 @@ import axios from "axios";
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
import { Actions, Models } from './models';
+import {RequestArgs} from "@/utils/openapi/base";
export const ApiMixin = {
data() {