From 723b74509ff8d7253148f957e9965e515ba87d96 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Thu, 11 Sep 2025 21:44:40 +0200 Subject: [PATCH] moved space stuff to database and reworked invite link backend logic --- cookbook/helper/scope_middleware.py | 6 ++ cookbook/serializer.py | 5 ++ cookbook/urls.py | 7 +- cookbook/views/api.py | 9 ++- cookbook/views/views.py | 20 +++-- vue3/src/apps/tandoor/Tandoor.vue | 5 +- .../components/model_editors/SpaceEditor.vue | 76 +++++++++++++++++++ vue3/src/locales/ar.json | 1 + vue3/src/locales/bg.json | 1 + vue3/src/locales/ca.json | 1 + vue3/src/locales/cs.json | 1 + vue3/src/locales/da.json | 1 + vue3/src/locales/de.json | 1 + vue3/src/locales/el.json | 1 + vue3/src/locales/en.json | 1 + vue3/src/locales/es.json | 1 + vue3/src/locales/fi.json | 1 + vue3/src/locales/fr.json | 1 + vue3/src/locales/he.json | 1 + vue3/src/locales/hr.json | 1 + vue3/src/locales/hu.json | 1 + vue3/src/locales/hy.json | 1 + vue3/src/locales/id.json | 1 + vue3/src/locales/is.json | 1 + vue3/src/locales/it.json | 1 + vue3/src/locales/lt.json | 1 + vue3/src/locales/lv.json | 1 + vue3/src/locales/nb_NO.json | 1 + vue3/src/locales/nl.json | 1 + vue3/src/locales/pl.json | 1 + vue3/src/locales/pt.json | 1 + vue3/src/locales/pt_BR.json | 1 + vue3/src/locales/ro.json | 1 + vue3/src/locales/ru.json | 1 + vue3/src/locales/sl.json | 1 + vue3/src/locales/sv.json | 1 + vue3/src/locales/tr.json | 1 + vue3/src/locales/uk.json | 1 + vue3/src/locales/zh_Hans.json | 1 + vue3/src/locales/zh_Hant.json | 1 + vue3/src/pages/DatabasePage.vue | 11 +++ vue3/src/pages/ModelListPage.vue | 9 ++- vue3/src/pages/StartPage.vue | 6 -- vue3/src/pages/WelcomePage.vue | 2 +- vue3/src/stores/UserPreferenceStore.ts | 36 +++++---- vue3/src/types/Models.ts | 36 +++++++-- 46 files changed, 213 insertions(+), 48 deletions(-) create mode 100644 vue3/src/components/model_editors/SpaceEditor.vue diff --git a/cookbook/helper/scope_middleware.py b/cookbook/helper/scope_middleware.py index 11e59a130..b0efdfab4 100644 --- a/cookbook/helper/scope_middleware.py +++ b/cookbook/helper/scope_middleware.py @@ -40,6 +40,9 @@ class ScopeMiddleware: if request.path.startswith(prefix + '/switch-space/'): return self.get_response(request) + if request.path.startswith(prefix + '/invite/'): + return self.get_response(request) + # get active user space, if for some reason more than one space is active select first (group permission checks will fail, this is not intended at this point) user_space = request.user.userspace_set.filter(active=True).first() @@ -49,6 +52,9 @@ class ScopeMiddleware: user_space = request.user.userspace_set.filter(active=True).first() user_space.active = True user_space.save() + elif 'signup_token' in request.session: + # if user is authenticated, has no space but a signup token (InviteLink) is present, redirect to invite link logic + return HttpResponseRedirect(reverse('view_invite', args=[request.session.pop('signup_token', '')])) else: # if user does not yet have a space create one for him user_space = create_space_for_user(request.user) diff --git a/cookbook/serializer.py b/cookbook/serializer.py index c561f2186..f77b8a243 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -405,6 +405,11 @@ class SpaceSerializer(WritableNestedModelSerializer): return 0 def create(self, validated_data): + + if Space.objects.filter(created_by=self.context['request'].user).count() >= self.context['request'].user.userpreference.max_owned_spaces: + raise serializers.ValidationError( + _('You have the reached the maximum amount of spaces that can be owned by you.') + f' ({self.context['request'].user.userpreference.max_owned_spaces})') + name = None if 'name' in validated_data: name = validated_data['name'] diff --git a/cookbook/urls.py b/cookbook/urls.py index 4501eb04f..bdd28c3c1 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -78,10 +78,11 @@ urlpatterns = [ path('setup/', views.setup, name='view_setup'), path('no-group/', views.no_groups, name='view_no_group'), - path('space-overview/', views.space_overview, name='view_space_overview'), - path('switch-space/', views.switch_space, name='view_switch_space'), - path('no-perm/', views.no_perm, name='view_no_perm'), + #path('space-overview/', views.space_overview, name='view_space_overview'), + #path('switch-space/', views.switch_space, name='view_switch_space'), + #path('no-perm/', views.no_perm, name='view_no_perm'), path('invite/', views.invite_link, name='view_invite'), + path('invite//', views.invite_link, name='view_invite'), path('system/', views.system, name='view_system'), path('plugin/update/', views.plugin_update, name='view_plugin_update'), diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 097c120cd..befb4db8d 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -181,7 +181,10 @@ class StandardFilterModelViewSet(viewsets.ModelViewSet): queryset = self.queryset query = self.request.query_params.get('query', None) if query is not None: - queryset = queryset.filter(name__icontains=query) + try: + queryset = queryset.filter(name__icontains=query) + except FieldError: + pass updated_at = self.request.query_params.get('updated_at', None) if updated_at is not None: @@ -1892,8 +1895,8 @@ class InviteLinkViewSet(LoggingMixin, StandardFilterModelViewSet): if internal_note is not None: self.queryset = self.queryset.filter(internal_note=internal_note) - unused = self.request.query_params.get('unused', False) - if unused: + used = self.request.query_params.get('used', False) + if not used: self.queryset = self.queryset.filter(used_by=None) if is_space_owner(self.request.user, self.request.space): diff --git a/cookbook/views/views.py b/cookbook/views/views.py index 6d915ebff..89343e264 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -42,6 +42,9 @@ def index(request, path=None, resource=None): if User.objects.count() < 1 and 'django.contrib.auth.backends.RemoteUserBackend' not in settings.AUTHENTICATION_BACKENDS: return HttpResponseRedirect(reverse_lazy('view_setup')) + if 'signup_token' in request.session: + return HttpResponseRedirect(reverse('view_invite', args=[request.session.pop('signup_token', '')])) + if request.user.is_authenticated or re.search(r'/recipe/\d+/', request.path[:512]) and request.GET.get('share'): return render(request, 'frontend/tandoor.html', {}) else: @@ -98,7 +101,7 @@ def space_overview(request): max_users=settings.SPACE_DEFAULT_MAX_USERS, allow_sharing=settings.SPACE_DEFAULT_ALLOW_SHARING, ai_enabled=settings.SPACE_AI_ENABLED, - ai_credits_monthly=settings.SPACE_AI_CREDITS_MONTHLY,) + ai_credits_monthly=settings.SPACE_AI_CREDITS_MONTHLY, ) user_space = UserSpace.objects.create(space=created_space, user=request.user, active=False) user_space.groups.add(Group.objects.filter(name='admin').get()) @@ -322,7 +325,7 @@ def invite_link(request, token): try: token = UUID(token, version=4) except ValueError: - messages.add_message(request, messages.ERROR, _('Malformed Invite Link supplied!')) + print('Malformed Invite Link supplied!') return HttpResponseRedirect(reverse('index')) if link := InviteLink.objects.filter(valid_until__gte=datetime.today(), used_by=None, uuid=token).first(): @@ -331,22 +334,17 @@ def invite_link(request, token): link.used_by = request.user link.save() - user_space = UserSpace.objects.create(user=request.user, space=link.space, internal_note=link.internal_note, invite_link=link, active=False) - - if request.user.userspace_set.count() == 1: - user_space.active = True - user_space.save() + UserSpace.objects.filter(user=request.user).update(active=False) + user_space = UserSpace.objects.create(user=request.user, space=link.space, internal_note=link.internal_note, invite_link=link, active=True) user_space.groups.add(link.group) - messages.add_message(request, messages.SUCCESS, _('Successfully joined space.')) - return HttpResponseRedirect(reverse('view_space_overview')) + return HttpResponseRedirect(reverse('index')) else: request.session['signup_token'] = str(token) return HttpResponseRedirect(reverse('account_signup')) - messages.add_message(request, messages.ERROR, _('Invite Link not valid or already used!')) - return HttpResponseRedirect(reverse('view_space_overview')) + return HttpResponseRedirect(reverse('index')) def report_share_abuse(request, token): diff --git a/vue3/src/apps/tandoor/Tandoor.vue b/vue3/src/apps/tandoor/Tandoor.vue index 1dba5e162..541cdb6ed 100644 --- a/vue3/src/apps/tandoor/Tandoor.vue +++ b/vue3/src/apps/tandoor/Tandoor.vue @@ -156,13 +156,16 @@ const router = useRouter() const isPrintMode = useMediaQuery('print') onMounted(() => { - useUserPreferenceStore() + useUserPreferenceStore().init() }) /** * global title update handler, might be overridden by page specific handlers */ router.afterEach((to, from) => { + if(to.name != 'WelcomePage' && !useUserPreferenceStore().activeSpace.spaceSetupCompleted && useUserPreferenceStore().activeSpace.createdBy.id! == useUserPreferenceStore().userSettings.user.id!){ + router.push({name: 'WelcomePage'}) + } nextTick(() => { if (to.meta.title) { title.value = t(to.meta.title) diff --git a/vue3/src/components/model_editors/SpaceEditor.vue b/vue3/src/components/model_editors/SpaceEditor.vue new file mode 100644 index 000000000..8453bcdc2 --- /dev/null +++ b/vue3/src/components/model_editors/SpaceEditor.vue @@ -0,0 +1,76 @@ + + + + + \ No newline at end of file diff --git a/vue3/src/locales/ar.json b/vue3/src/locales/ar.json index a8a11bdc8..422881c89 100644 --- a/vue3/src/locales/ar.json +++ b/vue3/src/locales/ar.json @@ -120,6 +120,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "", "Hide_Food": "", "Hide_Keyword": "", diff --git a/vue3/src/locales/bg.json b/vue3/src/locales/bg.json index 15bb5ff7b..93e9aacc0 100644 --- a/vue3/src/locales/bg.json +++ b/vue3/src/locales/bg.json @@ -117,6 +117,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Групирай по", "Hide_Food": "Скриване на храна", "Hide_Keyword": "Скриване на ключови думи", diff --git a/vue3/src/locales/ca.json b/vue3/src/locales/ca.json index ae6344aa1..efd2b7156 100644 --- a/vue3/src/locales/ca.json +++ b/vue3/src/locales/ca.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Agrupat per", "Hide_Food": "Amagar Aliment", "Hide_Keyword": "Amaga les paraules clau", diff --git a/vue3/src/locales/cs.json b/vue3/src/locales/cs.json index c026cbc22..34cf2582f 100644 --- a/vue3/src/locales/cs.json +++ b/vue3/src/locales/cs.json @@ -160,6 +160,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Seskupit podle", "Hide_Food": "Skrýt potravinu", "Hide_Keyword": "Skrýt štítky", diff --git a/vue3/src/locales/da.json b/vue3/src/locales/da.json index 2b1af9aa7..62ab7f5dd 100644 --- a/vue3/src/locales/da.json +++ b/vue3/src/locales/da.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Grupper efter", "Hide_Food": "Skjul mad", "Hide_Keyword": "Skjul nøgleord", diff --git a/vue3/src/locales/de.json b/vue3/src/locales/de.json index 7ddec7e05..84f07ad71 100644 --- a/vue3/src/locales/de.json +++ b/vue3/src/locales/de.json @@ -224,6 +224,7 @@ "GettingStarted": "Erste Schritte", "Global": "Global", "GlobalHelp": "Globale AI Anbieter können von Nutzern aller Spaces verwendet werden. Sie können nur dich Instanz Admins (Superusers) erstellt und bearbeitet werden.", + "Group": "Gruppe", "GroupBy": "Gruppieren nach", "HeaderWarning": "Achtung: Durch ändern auf Überschrift werden Menge/Einheit/Lebensmittel gelöscht", "Headline": "Überschrift", diff --git a/vue3/src/locales/el.json b/vue3/src/locales/el.json index f124f3deb..7dba750d5 100644 --- a/vue3/src/locales/el.json +++ b/vue3/src/locales/el.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Ομαδοποίηση κατά", "Hide_Food": "Απόκρυψη φαγητού", "Hide_Keyword": "Απόκρυψη λέξεων-κλειδί", diff --git a/vue3/src/locales/en.json b/vue3/src/locales/en.json index 8f33c71e7..93f3dc9fd 100644 --- a/vue3/src/locales/en.json +++ b/vue3/src/locales/en.json @@ -222,6 +222,7 @@ "GettingStarted": "Getting Started", "Global": "Global", "GlobalHelp": "Global AI Providers can be used by users of all spaces. They can only be created and edited by superusers. ", + "Group": "Group", "GroupBy": "Group By", "HeaderWarning": "Warning: Changing to a Heading deletes the Amount/Unit/Food", "Headline": "Headline", diff --git a/vue3/src/locales/es.json b/vue3/src/locales/es.json index 1eaa7aced..915a1deea 100644 --- a/vue3/src/locales/es.json +++ b/vue3/src/locales/es.json @@ -215,6 +215,7 @@ "GettingStarted": "Primeros pasos", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Agrupar por", "HeaderWarning": "Advertencia: Cambiar a un encabezado eliminará la cantidad/unidad/alimento", "Headline": "Encabezado", diff --git a/vue3/src/locales/fi.json b/vue3/src/locales/fi.json index b58873a25..e8ec7ff3f 100644 --- a/vue3/src/locales/fi.json +++ b/vue3/src/locales/fi.json @@ -158,6 +158,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Ryhmittely peruste", "Hide_Food": "Piilota Ruoka", "Hide_Keyword": "Piilota avainsana", diff --git a/vue3/src/locales/fr.json b/vue3/src/locales/fr.json index 15e2348e9..bdfff3385 100644 --- a/vue3/src/locales/fr.json +++ b/vue3/src/locales/fr.json @@ -222,6 +222,7 @@ "GettingStarted": "Commencer", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Grouper par", "HeaderWarning": "Attention : Changer pour un En-tête supprimera la quantité / l'unité / l'aliment", "Headline": "En-tête", diff --git a/vue3/src/locales/he.json b/vue3/src/locales/he.json index 61195a747..66849f3d3 100644 --- a/vue3/src/locales/he.json +++ b/vue3/src/locales/he.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "אסוף לפי", "Hide_Food": "הסתר אוכל", "Hide_Keyword": "הסתר מילות מפתח", diff --git a/vue3/src/locales/hr.json b/vue3/src/locales/hr.json index 5125c639e..dd4cebadd 100644 --- a/vue3/src/locales/hr.json +++ b/vue3/src/locales/hr.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Grupiraj po", "Hide_Food": "Sakrij namirnicu", "Hide_Keyword": "Sakrij ključne riječi", diff --git a/vue3/src/locales/hu.json b/vue3/src/locales/hu.json index f3a012faf..3cdf80578 100644 --- a/vue3/src/locales/hu.json +++ b/vue3/src/locales/hu.json @@ -144,6 +144,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Csoportosítva", "Hide_Food": "Alapanyag elrejtése", "Hide_Keyword": "Kulcsszavak elrejtése", diff --git a/vue3/src/locales/hy.json b/vue3/src/locales/hy.json index 040d59297..5dcd4347e 100644 --- a/vue3/src/locales/hy.json +++ b/vue3/src/locales/hy.json @@ -69,6 +69,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "Hide_Food": "Թաքցնել սննդամթերքը", "Hide_Keywords": "Թաքցնել բանալի բառը", "Hide_Recipes": "Թաքցնել բաղադրատոմսերը", diff --git a/vue3/src/locales/id.json b/vue3/src/locales/id.json index 8ee79c284..692a48e56 100644 --- a/vue3/src/locales/id.json +++ b/vue3/src/locales/id.json @@ -132,6 +132,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "", "Hide_Food": "", "Hide_Keyword": "", diff --git a/vue3/src/locales/is.json b/vue3/src/locales/is.json index 58f501375..388b478d7 100644 --- a/vue3/src/locales/is.json +++ b/vue3/src/locales/is.json @@ -160,6 +160,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "", "Hide_Food": "", "Hide_Keyword": "", diff --git a/vue3/src/locales/it.json b/vue3/src/locales/it.json index 203a7caf1..ea8effa9a 100644 --- a/vue3/src/locales/it.json +++ b/vue3/src/locales/it.json @@ -222,6 +222,7 @@ "GettingStarted": "Iniziamo", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Raggruppa per", "HeaderWarning": "Attenzione: la modifica in un'intestazione elimina l'importo/unità/alimento", "Headline": "Intestazione", diff --git a/vue3/src/locales/lt.json b/vue3/src/locales/lt.json index 5e86d1478..c172b5f83 100644 --- a/vue3/src/locales/lt.json +++ b/vue3/src/locales/lt.json @@ -146,6 +146,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "", "Hide_Food": "", "Hide_Keyword": "", diff --git a/vue3/src/locales/lv.json b/vue3/src/locales/lv.json index e3f289c6f..01920028c 100644 --- a/vue3/src/locales/lv.json +++ b/vue3/src/locales/lv.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "", "Hide_Food": "", "Hide_Keyword": "", diff --git a/vue3/src/locales/nb_NO.json b/vue3/src/locales/nb_NO.json index b68827856..2abf68f9d 100644 --- a/vue3/src/locales/nb_NO.json +++ b/vue3/src/locales/nb_NO.json @@ -152,6 +152,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Grupér", "Hide_Food": "Skjul Matrett", "Hide_Keyword": "Skjul nøkkelord", diff --git a/vue3/src/locales/nl.json b/vue3/src/locales/nl.json index d867c5ca7..7c2fa1e62 100644 --- a/vue3/src/locales/nl.json +++ b/vue3/src/locales/nl.json @@ -223,6 +223,7 @@ "GettingStarted": "Aan de slag", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Groepeer per", "HeaderWarning": "Waarschuwing: Het wijzigen naar een kop verwijdert de hoeveelheid/eenheid/voedingsmiddel", "Headline": "Koptekst", diff --git a/vue3/src/locales/pl.json b/vue3/src/locales/pl.json index e1747ee02..9abdcd30b 100644 --- a/vue3/src/locales/pl.json +++ b/vue3/src/locales/pl.json @@ -187,6 +187,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Grupuj według", "Hide_Food": "Ukryj żywność", "Hide_Keyword": "Ukryj słowa kluczowe", diff --git a/vue3/src/locales/pt.json b/vue3/src/locales/pt.json index 9bf8eb951..ffc5b5384 100644 --- a/vue3/src/locales/pt.json +++ b/vue3/src/locales/pt.json @@ -132,6 +132,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Agrupar por", "Hide_Food": "Esconder comida", "Hide_Keyword": "", diff --git a/vue3/src/locales/pt_BR.json b/vue3/src/locales/pt_BR.json index 872bfa706..1abfec4ea 100644 --- a/vue3/src/locales/pt_BR.json +++ b/vue3/src/locales/pt_BR.json @@ -221,6 +221,7 @@ "GettingStarted": "Começando", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Agrupar Por", "HeaderWarning": "Alerta: Mudanças de Cabeçalho apagam a Quantidade/Unidade/Alimento", "Headline": "Título", diff --git a/vue3/src/locales/ro.json b/vue3/src/locales/ro.json index 4dd536817..f0466993b 100644 --- a/vue3/src/locales/ro.json +++ b/vue3/src/locales/ro.json @@ -139,6 +139,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Grupat de", "Hide_Food": "Ascunde mâncare", "Hide_Keyword": "Ascunde cuvintele cheie", diff --git a/vue3/src/locales/ru.json b/vue3/src/locales/ru.json index b3aadf0a0..bfc395cf8 100644 --- a/vue3/src/locales/ru.json +++ b/vue3/src/locales/ru.json @@ -222,6 +222,7 @@ "GettingStarted": "Начало работы", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Сгруппировать по", "HeaderWarning": "Внимание: при преобразовании в заголовок удаляются данные о количестве, единице/измерения/продукте.", "Headline": "Заголовок", diff --git a/vue3/src/locales/sl.json b/vue3/src/locales/sl.json index bfae24ca7..9780451a7 100644 --- a/vue3/src/locales/sl.json +++ b/vue3/src/locales/sl.json @@ -222,6 +222,7 @@ "GettingStarted": "Začetek", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Združi po", "HeaderWarning": "Opozorilo: Sprememba naslova izbriše količino/enoto/hrano", "Headline": "Glavni naslov", diff --git a/vue3/src/locales/sv.json b/vue3/src/locales/sv.json index 37ccaa1d1..dfb5bb6a6 100644 --- a/vue3/src/locales/sv.json +++ b/vue3/src/locales/sv.json @@ -198,6 +198,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Gruppera enligt", "Hide_Food": "Dölj livsmedel", "Hide_Keyword": "Dölj nyckelord", diff --git a/vue3/src/locales/tr.json b/vue3/src/locales/tr.json index 00efbef79..6d8fcf646 100644 --- a/vue3/src/locales/tr.json +++ b/vue3/src/locales/tr.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "Gruplandırma Ölçütü", "Hide_Food": "Yiyeceği Gizle", "Hide_Keyword": "Anahtar kelimeleri gizle", diff --git a/vue3/src/locales/uk.json b/vue3/src/locales/uk.json index 90dfa7b49..0d6775bad 100644 --- a/vue3/src/locales/uk.json +++ b/vue3/src/locales/uk.json @@ -142,6 +142,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "По Групі", "Hide_Food": "Сховати Їжу", "Hide_Keyword": "", diff --git a/vue3/src/locales/zh_Hans.json b/vue3/src/locales/zh_Hans.json index 79a631907..423c04a46 100644 --- a/vue3/src/locales/zh_Hans.json +++ b/vue3/src/locales/zh_Hans.json @@ -161,6 +161,7 @@ "FuzzySearchHelp": "", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "分组", "Hide_Food": "隐藏食物", "Hide_Keyword": "隐藏关键词", diff --git a/vue3/src/locales/zh_Hant.json b/vue3/src/locales/zh_Hant.json index 55fdfe159..e4c8e3c74 100644 --- a/vue3/src/locales/zh_Hant.json +++ b/vue3/src/locales/zh_Hant.json @@ -221,6 +221,7 @@ "GettingStarted": "開始使用", "Global": "", "GlobalHelp": "", + "Group": "", "GroupBy": "分組依據", "HeaderWarning": "警告:變更為標題會刪除數量/單位/食物", "Headline": "標題", diff --git a/vue3/src/pages/DatabasePage.vue b/vue3/src/pages/DatabasePage.vue index 68a71e2b3..76ce709e0 100644 --- a/vue3/src/pages/DatabasePage.vue +++ b/vue3/src/pages/DatabasePage.vue @@ -35,6 +35,17 @@ + + +

{{ $t('Space') }}

+
+
+ + + + + + +