[FR] Add API endpoint to activate plugins (#4186)

* make plugin urls def cleaner

* rename plugin managment endpoints

* [FR] Add API endpoint to activate plugins
Fixes #4182

* fix for api url change

* bump API version
This commit is contained in:
Matthias Mair 2023-01-25 21:05:09 +01:00 committed by GitHub
parent 3d5be5a5c7
commit 8df5649b6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 49 additions and 31 deletions

View File

@ -2,10 +2,12 @@
# InvenTree API version
INVENTREE_API_VERSION = 89
INVENTREE_API_VERSION = 90
"""
Increment this API version number whenever there is a significant change to the API that any clients need to know about
v90 -> 2023-01-25 : https://github.com/inventree/InvenTree/pull/4186/files
- Adds a dedicated endpoint to activate a plugin
v89 -> 2023-01-25 : https://github.com/inventree/InvenTree/pull/4214
- Adds updated field to SupplierPart API
- Adds API date orddering for supplier part list

View File

@ -10,7 +10,8 @@ from rest_framework.response import Response
import plugin.serializers as PluginSerializers
from common.api import GlobalSettingsPermissions
from InvenTree.mixins import (CreateAPI, ListAPI, RetrieveUpdateAPI,
RetrieveUpdateDestroyAPI)
RetrieveUpdateDestroyAPI, UpdateAPI)
from InvenTree.permissions import IsSuperuser
from plugin.base.action.api import ActionPluginView
from plugin.base.barcodes.api import barcode_api_urls
from plugin.base.locate.api import LocatePluginView
@ -122,6 +123,20 @@ class PluginInstall(CreateAPI):
return serializer.save()
class PluginActivate(UpdateAPI):
"""Endpoint for activating a plugin."""
queryset = PluginConfig.objects.all()
serializer_class = PluginSerializers.PluginConfigEmptySerializer
permission_classes = [IsSuperuser, ]
def perform_update(self, serializer):
"""Activate the plugin."""
instance = serializer.instance
instance.active = True
instance.save()
class PluginSettingList(ListAPI):
"""List endpoint for all plugin related settings.
@ -216,27 +231,24 @@ plugin_api_urls = [
re_path(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'),
re_path(r'^barcode/', include(barcode_api_urls)),
re_path(r'^locate/', LocatePluginView.as_view(), name='api-locate-plugin'),
re_path(r'^plugins/', include([
# Plugin settings URLs
re_path(r'^settings/', include([
re_path(r'^(?P<plugin>\w+)/(?P<key>\w+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'),
re_path(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'),
])),
# Detail views for a single PluginConfig item
re_path(r'^(?P<pk>\d+)/', include([
re_path(r'^activate/', PluginActivate.as_view(), name='api-plugin-detail-activate'),
re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'),
])),
# Plugin managment
re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'),
re_path(r'^activate/', PluginActivate.as_view(), name='api-plugin-activate'),
# Anything else
re_path(r'^.*$', PluginList.as_view(), name='api-plugin-list'),
]))
]
general_plugin_api_urls = [
# Plugin settings URLs
re_path(r'^settings/', include([
re_path(r'^(?P<plugin>\w+)/(?P<key>\w+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'),
re_path(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'),
])),
# Detail views for a single PluginConfig item
re_path(r'^(?P<pk>\d+)/', include([
re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'),
])),
re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'),
# Anything else
re_path(r'^.*$', PluginList.as_view(), name='api-plugin-list'),
]
plugin_api_urls.append(
re_path(r'^plugin/', include(general_plugin_api_urls))
)

View File

@ -159,6 +159,10 @@ class PluginConfigInstallSerializer(serializers.Serializer):
return ret
class PluginConfigEmptySerializer(serializers.Serializer):
"""Serializer for a PluginConfig."""
class PluginSettingSerializer(GenericReferencedSettingSerializer):
"""Serializer for the PluginSetting model."""

View File

@ -54,7 +54,7 @@ class PluginTagTests(TestCase):
def test_tag_safe_url(self):
"""Test that the safe url tag works expected."""
# right url
self.assertEqual(plugin_tags.safe_url('api-plugin-install'), '/api/plugin/install/')
self.assertEqual(plugin_tags.safe_url('api-plugin-install'), '/api/plugins/install/')
# wrong url
self.assertEqual(plugin_tags.safe_url('indexas'), None)

View File

@ -79,7 +79,7 @@ $('table').find('.boolean-setting').change(function() {
if (notification) {
url = `/api/settings/notification/${pk}/`;
} else if (plugin) {
url = `/api/plugin/settings/${plugin}/${setting}/`;
url = `/api/plugins/settings/${plugin}/${setting}/`;
} else if (user) {
url = `/api/settings/user/${setting}/`;
}

View File

@ -44,7 +44,7 @@ function editSetting(key, options={}) {
var url = '';
if (plugin) {
url = `/api/plugin/settings/${plugin}/${key}/`;
url = `/api/plugins/settings/${plugin}/${key}/`;
} else if (notification) {
url = `/api/settings/notification/${pk}/`;
} else if (global) {

View File

@ -235,7 +235,7 @@ function selectLabel(labels, items, options={}) {
// Request a list of available label printing plugins from the server
if (plugins_enabled) {
inventreeGet(
`/api/plugin/`,
`/api/plugins/`,
{
mixin: 'labels',
},

View File

@ -11,7 +11,7 @@
*/
function installPlugin() {
constructForm(`/api/plugin/install/`, {
constructForm(`/api/plugins/install/`, {
method: 'POST',
title: '{% trans "Install Plugin" %}',
fields: {
@ -50,7 +50,7 @@ function locateItemOrLocation(options={}) {
// Request the list of available 'locate' plugins
inventreeGet(
`/api/plugin/`,
`/api/plugins/`,
{
mixin: 'locate',
},