From 1b1945d95468640a84872c791f07fea33733b7b4 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Wed, 13 Oct 2021 15:03:59 +0200 Subject: [PATCH] started migrating file editor page to generic model list --- cookbook/serializer.py | 25 ++- cookbook/urls.py | 4 +- cookbook/views/lists.py | 16 +- vue/src/apps/ChecklistView/ChecklistView.vue | 1 - vue/src/apps/ModelListView/ModelListView.vue | 1 - vue/src/components/FileViewer.vue | 39 +++++ vue/src/components/Modals/FileInput.vue | 60 +++++++ .../components/Modals/GenericModalForm.vue | 153 ++++++++++-------- vue/src/locales/en.json | 2 + vue/src/utils/models.js | 32 ++++ vue/src/utils/utils.js | 1 + 11 files changed, 247 insertions(+), 87 deletions(-) create mode 100644 vue/src/components/FileViewer.vue create mode 100644 vue/src/components/Modals/FileInput.vue 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 @@ \ 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() {