diff --git a/api/funkwhale_api/manage/serializers.py b/api/funkwhale_api/manage/serializers.py index 67e0178e0e4688679463b308bf532f458fa51037..be67f5068a8722b4d440bf28dfef425937b4594f 100644 --- a/api/funkwhale_api/manage/serializers.py +++ b/api/funkwhale_api/manage/serializers.py @@ -500,6 +500,15 @@ class ManageLibrarySerializer(serializers.ModelSerializer): "followers_url", "actor", ] + read_only_fields = [ + "fid", + "uuid", + "id", + "url", + "domain", + "actor", + "creation_date", + ] def get_uploads_count(self, obj): return getattr(obj, "_uploads_count", obj.uploads_count) diff --git a/api/funkwhale_api/manage/views.py b/api/funkwhale_api/manage/views.py index c788dd96bcaf4582c2efb6446c83327b39d9214b..313cb681bff938f041624e8d88d0c534b3b342f2 100644 --- a/api/funkwhale_api/manage/views.py +++ b/api/funkwhale_api/manage/views.py @@ -200,6 +200,7 @@ follows_subquery = ( class ManageLibraryViewSet( mixins.ListModelMixin, mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet, ): diff --git a/api/tests/manage/test_views.py b/api/tests/manage/test_views.py index 72394052c9cc23132fa94f389e9c751c8d79ff70..c6571b04db463666b4bd0b20a6d2a1a3955e7e33 100644 --- a/api/tests/manage/test_views.py +++ b/api/tests/manage/test_views.py @@ -322,6 +322,18 @@ def test_library_detail(factories, superuser_api_client): assert response.data["id"] == library.id +def test_library_update(factories, superuser_api_client): + library = factories["music.Library"](privacy_level="public") + url = reverse( + "api:v1:manage:library:libraries-detail", kwargs={"uuid": library.uuid} + ) + response = superuser_api_client.patch(url, {"privacy_level": "me"}) + + assert response.status_code == 200 + library.refresh_from_db() + assert library.privacy_level == "me" + + def test_library_detail_stats(factories, superuser_api_client): library = factories["music.Library"]() url = reverse( diff --git a/changes/changelog.d/548.enhancement b/changes/changelog.d/548.enhancement new file mode 100644 index 0000000000000000000000000000000000000000..99cd04941f768888dc13a7f7315fdf2223c220d7 --- /dev/null +++ b/changes/changelog.d/548.enhancement @@ -0,0 +1 @@ +Mods can now change a library visibility through the admin UI (#548) diff --git a/front/src/views/admin/library/LibraryDetail.vue b/front/src/views/admin/library/LibraryDetail.vue index beec7e2b408cf6b032c5f0114c979d77f958a64c..db53bd2b522d5d3cbf65500cdc8c107995e1f659 100644 --- a/front/src/views/admin/library/LibraryDetail.vue +++ b/front/src/views/admin/library/LibraryDetail.vue @@ -96,7 +96,16 @@ </router-link> </td> <td> - {{ sharedLabels.fields.privacy_level.shortChoices[object.privacy_level] }} + <select + v-dropdown + v-if="object.is_local" + @change="updateObj('privacy_level')" + v-model="object.privacy_level" + + class="ui search selection dropdown"> + <option v-for="p in ['me', 'instance', 'everyone']" :value="p">{{ sharedLabels.fields.privacy_level.shortChoices[p] }}</option> + </select> + <template v-else>{{ sharedLabels.fields.privacy_level.shortChoices[object.privacy_level] }}</template> </td> </tr> <tr> @@ -308,7 +317,28 @@ export default { }, getQuery (field, value) { return `${field}:"${value}"` - } + }, + updateObj(attr, toNull) { + let newValue = this.object[attr] + if (toNull && !newValue) { + newValue = null + } + let params = {} + params[attr] = newValue + axios.patch(`manage/library/libraries/${this.id}/`, params).then( + response => { + logger.default.info( + `${attr} was updated succcessfully to ${newValue}` + ) + }, + error => { + logger.default.error( + `Error while setting ${attr} to ${newValue}`, + error + ) + } + ) + }, }, computed: { labels() {