From 2afab2aec861297220e1cbc51eea9879877939b3 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Wed, 1 Jun 2022 17:42:07 +0200 Subject: [PATCH] invite link basics --- cookbook/serializer.py | 17 +- cookbook/urls.py | 1 + cookbook/views/api.py | 14 +- .../apps/SpaceManageView/SpaceManageView.vue | 80 ++- vue/src/components/Modals/DateInput.vue | 36 ++ .../components/Modals/GenericModalForm.vue | 4 +- vue/src/locales/en.json | 3 +- vue/src/utils/models.js | 35 ++ vue/src/utils/openapi/api.ts | 533 +++++++++++++++++- 9 files changed, 714 insertions(+), 9 deletions(-) create mode 100644 vue/src/components/Modals/DateInput.vue diff --git a/cookbook/serializer.py b/cookbook/serializer.py index f93529e51..0749c5a8a 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -20,7 +20,7 @@ from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, Cu RecipeBookEntry, RecipeImport, ShareLink, ShoppingList, ShoppingListEntry, ShoppingListRecipe, Step, Storage, Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog, Unit, - UserFile, UserPreference, ViewLog, Space, UserSpace) + UserFile, UserPreference, ViewLog, Space, UserSpace, InviteLink) from cookbook.templatetags.custom_tags import markdown from recipes.settings import MEDIA_URL, AWS_ENABLED @@ -1026,6 +1026,21 @@ class AutomationSerializer(serializers.ModelSerializer): read_only_fields = ('created_by',) +class InviteLinkSerializer(WritableNestedModelSerializer): + group = GroupSerializer() + + def create(self, validated_data): + validated_data['created_by'] = self.context['request'].user + validated_data['space'] = self.context['request'].space + return super().create(validated_data) + + class Meta: + model = InviteLink + fields = ( + 'id', 'uuid', 'email', 'group', 'valid_until', 'used_by', 'created_by', 'created_at',) + read_only_fields = ('id', 'uuid', 'email', 'created_by', 'created_at',) + + # CORS, REST and Scopes aren't currently working # Scopes are evaluating before REST has authenticated the user assigning a None space # I've made the change below to fix the bookmarklet, other serializers likely need a similar/better fix diff --git a/cookbook/urls.py b/cookbook/urls.py index 6a7a64857..ed98e3eab 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -27,6 +27,7 @@ router.register(r'import-log', api.ImportLogViewSet) router.register(r'export-log', api.ExportLogViewSet) router.register(r'group', api.GroupViewSet) router.register(r'ingredient', api.IngredientViewSet) +router.register(r'invite-link', api.InviteLinkViewSet) router.register(r'keyword', api.KeywordViewSet) router.register(r'meal-plan', api.MealPlanViewSet) router.register(r'meal-type', api.MealTypeViewSet) diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 3fd70f138..6903c5bd5 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -53,7 +53,7 @@ from cookbook.models import (Automation, BookmarkletImport, CookLog, CustomFilte Recipe, RecipeBook, RecipeBookEntry, ShareLink, ShoppingList, ShoppingListEntry, ShoppingListRecipe, Step, Storage, Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog, Unit, - UserFile, UserPreference, ViewLog, Space, UserSpace) + UserFile, UserPreference, ViewLog, Space, UserSpace, InviteLink) from cookbook.provider.dropbox import Dropbox from cookbook.provider.local import Local from cookbook.provider.nextcloud import Nextcloud @@ -74,7 +74,7 @@ from cookbook.serializer import (AutomationSerializer, BookmarkletImportSerializ SupermarketCategorySerializer, SupermarketSerializer, SyncLogSerializer, SyncSerializer, UnitSerializer, UserFileSerializer, UserNameSerializer, UserPreferenceSerializer, - ViewLogSerializer, IngredientSimpleSerializer, BookmarkletImportListSerializer, RecipeFromSourceSerializer, SpaceSerializer, UserSpaceSerializer, GroupSerializer) + ViewLogSerializer, IngredientSimpleSerializer, BookmarkletImportListSerializer, RecipeFromSourceSerializer, SpaceSerializer, UserSpaceSerializer, GroupSerializer, InviteLinkSerializer) from recipes import settings @@ -1044,6 +1044,16 @@ class AutomationViewSet(viewsets.ModelViewSet, StandardFilterMixin): return super().get_queryset() +class InviteLinkViewSet(viewsets.ModelViewSet, StandardFilterMixin): + queryset = InviteLink.objects + serializer_class = InviteLinkSerializer + permission_classes = [CustomIsSpaceOwner] + + def get_queryset(self): + self.queryset = self.queryset.filter(space=self.request.space).all() + return super().get_queryset() + + class CustomFilterViewSet(viewsets.ModelViewSet, StandardFilterMixin): queryset = CustomFilter.objects serializer_class = CustomFilterSerializer diff --git a/vue/src/apps/SpaceManageView/SpaceManageView.vue b/vue/src/apps/SpaceManageView/SpaceManageView.vue index db60f6a0e..84eebfb21 100644 --- a/vue/src/apps/SpaceManageView/SpaceManageView.vue +++ b/vue/src/apps/SpaceManageView/SpaceManageView.vue @@ -46,6 +46,72 @@ +
+
+ +
+ + + + + + + + + + + + + + + + + + +
#{{ $t('Email') }}{{ $t('Group') }}{{ $t('Token') }}
{{ il.id }}{{ il.email }} + + + + + + + + + + + + + + + + + + + {{ $t('Delete') }} + + + + + +
+
+
+
+ + + @@ -59,17 +125,20 @@ import {ApiMixin, ResolveUrlMixin, StandardToasts, ToastMixin} from "@/utils/uti import {ApiApiFactory} from "@/utils/openapi/api.ts" import GenericMultiselect from "@/components/GenericMultiselect"; +import GenericModalForm from "@/components/Modals/GenericModalForm"; Vue.use(BootstrapVue) export default { name: "SupermarketView", mixins: [ResolveUrlMixin, ToastMixin, ApiMixin], - components: {GenericMultiselect}, + components: {GenericMultiselect, GenericModalForm}, data() { return { space: undefined, - user_spaces: [] + user_spaces: [], + invite_links: [], + show_invite_create: false } }, mounted() { @@ -82,8 +151,15 @@ export default { apiFactory.listUserSpaces().then(r => { this.user_spaces = r.data }) + this.loadInviteLinks() }, methods: { + loadInviteLinks: function () { + let apiFactory = new ApiApiFactory() + apiFactory.listInviteLinks().then(r => { + this.invite_links = r.data + }) + }, updateUserSpace: function (userSpace) { let apiFactory = new ApiApiFactory() apiFactory.partialUpdateUserSpace(userSpace.id, userSpace).then(r => { diff --git a/vue/src/components/Modals/DateInput.vue b/vue/src/components/Modals/DateInput.vue new file mode 100644 index 000000000..be53c8d23 --- /dev/null +++ b/vue/src/components/Modals/DateInput.vue @@ -0,0 +1,36 @@ + + + diff --git a/vue/src/components/Modals/GenericModalForm.vue b/vue/src/components/Modals/GenericModalForm.vue index 6073ee707..00689746e 100644 --- a/vue/src/components/Modals/GenericModalForm.vue +++ b/vue/src/components/Modals/GenericModalForm.vue @@ -14,6 +14,7 @@ +