mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Implement special data loading for admins
This commit is contained in:
parent
dcaf930570
commit
dc1024dce1
|
@ -29,7 +29,7 @@ class EndpointTester(APITestCase):
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.client.force_authenticate(user=self.user)
|
self.client.force_authenticate(user=self.user)
|
||||||
|
|
||||||
def toggle_staff(self, value: bool = True):
|
def toggle_admin(self, value: bool = True):
|
||||||
self.user.is_staff = value
|
self.user.is_staff = value
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ class TestLibraryViewset(EndpointTester):
|
||||||
self.assertTrue(response.status_code in [status.HTTP_202_ACCEPTED, status.HTTP_204_NO_CONTENT])
|
self.assertTrue(response.status_code in [status.HTTP_202_ACCEPTED, status.HTTP_204_NO_CONTENT])
|
||||||
|
|
||||||
self.assertForbidden(item=self.unowned.id)
|
self.assertForbidden(item=self.unowned.id)
|
||||||
self.toggle_staff(True)
|
self.toggle_admin(True)
|
||||||
response = self.execute(item=self.unowned.id)
|
response = self.execute(item=self.unowned.id)
|
||||||
self.assertTrue(response.status_code in [status.HTTP_202_ACCEPTED, status.HTTP_204_NO_CONTENT])
|
self.assertTrue(response.status_code in [status.HTTP_202_ACCEPTED, status.HTTP_204_NO_CONTENT])
|
||||||
|
|
||||||
|
@ -111,6 +111,21 @@ class TestLibraryViewset(EndpointTester):
|
||||||
self.assertFalse(response_contains(response, self.owned))
|
self.assertFalse(response_contains(response, self.owned))
|
||||||
|
|
||||||
|
|
||||||
|
@decl_endpoint('/api/library/all', method='get')
|
||||||
|
def test_retrieve_all(self):
|
||||||
|
self.toggle_admin(False)
|
||||||
|
self.assertForbidden()
|
||||||
|
self.toggle_admin(True)
|
||||||
|
response = self.execute()
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertTrue(response_contains(response, self.common))
|
||||||
|
self.assertTrue(response_contains(response, self.unowned))
|
||||||
|
self.assertTrue(response_contains(response, self.owned))
|
||||||
|
|
||||||
|
self.logout()
|
||||||
|
self.assertForbidden()
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/active', method='get')
|
@decl_endpoint('/api/library/active', method='get')
|
||||||
def test_retrieve_subscribed(self):
|
def test_retrieve_subscribed(self):
|
||||||
response = self.execute()
|
response = self.execute()
|
||||||
|
|
|
@ -8,7 +8,8 @@ library_router.register('library', views.LibraryViewSet, 'Library')
|
||||||
library_router.register('rsforms', views.RSFormViewSet, 'RSForm')
|
library_router.register('rsforms', views.RSFormViewSet, 'RSForm')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('library/active', views.LibraryActiveView.as_view(), name='library'),
|
path('library/active', views.LibraryActiveView.as_view()),
|
||||||
|
path('library/all', views.LibraryAdminView.as_view()),
|
||||||
path('library/templates', views.LibraryTemplatesView.as_view(), name='templates'),
|
path('library/templates', views.LibraryTemplatesView.as_view(), name='templates'),
|
||||||
path('constituents/<int:pk>', views.ConstituentAPIView.as_view(), name='constituenta-detail'),
|
path('constituents/<int:pk>', views.ConstituentAPIView.as_view(), name='constituenta-detail'),
|
||||||
path('rsforms/import-trs', views.TrsImportView.as_view()),
|
path('rsforms/import-trs', views.TrsImportView.as_view()),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
''' REST API: Endpoint processors. '''
|
''' REST API: Endpoint processors. '''
|
||||||
from .library import (
|
from .library import (
|
||||||
LibraryActiveView,
|
LibraryActiveView,
|
||||||
|
LibraryAdminView,
|
||||||
LibraryTemplatesView,
|
LibraryTemplatesView,
|
||||||
LibraryViewSet
|
LibraryViewSet
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,6 +34,17 @@ class LibraryActiveView(generics.ListAPIView):
|
||||||
).distinct().order_by('-time_update')
|
).distinct().order_by('-time_update')
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=['Library'])
|
||||||
|
@extend_schema_view()
|
||||||
|
class LibraryAdminView(generics.ListAPIView):
|
||||||
|
''' Endpoint: Get list of all library items. Admin only '''
|
||||||
|
permission_classes = (permissions.IsAdminUser,)
|
||||||
|
serializer_class = s.LibraryItemSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return m.LibraryItem.objects.all().order_by('-time_update')
|
||||||
|
|
||||||
|
|
||||||
@extend_schema(tags=['Library'])
|
@extend_schema(tags=['Library'])
|
||||||
@extend_schema_view()
|
@extend_schema_view()
|
||||||
class LibraryTemplatesView(generics.ListAPIView):
|
class LibraryTemplatesView(generics.ListAPIView):
|
||||||
|
|
|
@ -192,6 +192,14 @@ export function getLibrary(request: FrontPull<ILibraryItem[]>) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAdminLibrary(request: FrontPull<ILibraryItem[]>) {
|
||||||
|
AxiosGet({
|
||||||
|
title: 'All LibraryItems list',
|
||||||
|
endpoint: '/api/library/all',
|
||||||
|
request: request
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function getTemplates(request: FrontPull<ILibraryItem[]>) {
|
export function getTemplates(request: FrontPull<ILibraryItem[]>) {
|
||||||
AxiosGet({
|
AxiosGet({
|
||||||
title: 'Available LibraryItems list',
|
title: 'Available LibraryItems list',
|
||||||
|
|
|
@ -2,23 +2,25 @@
|
||||||
|
|
||||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { ErrorData } from '@/components/info/InfoError';
|
|
||||||
import { ILibraryItem } from '@/models/library';
|
|
||||||
import { matchLibraryItem } from '@/models/libraryAPI';
|
|
||||||
import { ILibraryFilter } from '@/models/miscellaneous';
|
|
||||||
import { IRSForm, IRSFormCloneData, IRSFormCreateData, IRSFormData } from '@/models/rsform';
|
|
||||||
import { RSFormLoader } from '@/models/RSFormLoader';
|
|
||||||
import {
|
import {
|
||||||
DataCallback,
|
DataCallback,
|
||||||
deleteLibraryItem,
|
deleteLibraryItem,
|
||||||
|
getAdminLibrary,
|
||||||
getLibrary,
|
getLibrary,
|
||||||
getRSFormDetails,
|
getRSFormDetails,
|
||||||
getTemplates,
|
getTemplates,
|
||||||
postCloneLibraryItem,
|
postCloneLibraryItem,
|
||||||
postNewRSForm
|
postNewRSForm
|
||||||
} from '@/app/backendAPI';
|
} from '@/app/backendAPI';
|
||||||
|
import { ErrorData } from '@/components/info/InfoError';
|
||||||
|
import { ILibraryItem } from '@/models/library';
|
||||||
|
import { matchLibraryItem } from '@/models/libraryAPI';
|
||||||
|
import { ILibraryFilter } from '@/models/miscellaneous';
|
||||||
|
import { IRSForm, IRSFormCloneData, IRSFormCreateData, IRSFormData } from '@/models/rsform';
|
||||||
|
import { RSFormLoader } from '@/models/RSFormLoader';
|
||||||
|
|
||||||
import { useAuth } from './AuthContext';
|
import { useAuth } from './AuthContext';
|
||||||
|
import { useConceptOptions } from './OptionsContext';
|
||||||
|
|
||||||
interface ILibraryContext {
|
interface ILibraryContext {
|
||||||
items: ILibraryItem[];
|
items: ILibraryItem[];
|
||||||
|
@ -53,6 +55,7 @@ interface LibraryStateProps {
|
||||||
|
|
||||||
export const LibraryState = ({ children }: LibraryStateProps) => {
|
export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
const { adminMode } = useConceptOptions();
|
||||||
|
|
||||||
const [items, setItems] = useState<ILibraryItem[]>([]);
|
const [items, setItems] = useState<ILibraryItem[]>([]);
|
||||||
const [templates, setTemplates] = useState<ILibraryItem[]>([]);
|
const [templates, setTemplates] = useState<ILibraryItem[]>([]);
|
||||||
|
@ -109,19 +112,36 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
[cachedTemplates]
|
[cachedTemplates]
|
||||||
);
|
);
|
||||||
|
|
||||||
const reload = useCallback((callback?: () => void) => {
|
const reloadItems = useCallback(
|
||||||
setItems([]);
|
(callback?: () => void) => {
|
||||||
setError(undefined);
|
setItems([]);
|
||||||
getLibrary({
|
setError(undefined);
|
||||||
setLoading: setLoading,
|
if (user?.is_staff && adminMode) {
|
||||||
showError: true,
|
getAdminLibrary({
|
||||||
onError: setError,
|
setLoading: setLoading,
|
||||||
onSuccess: newData => {
|
showError: true,
|
||||||
setItems(newData);
|
onError: setError,
|
||||||
if (callback) callback();
|
onSuccess: newData => {
|
||||||
|
setItems(newData);
|
||||||
|
if (callback) callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
getLibrary({
|
||||||
|
setLoading: setLoading,
|
||||||
|
showError: true,
|
||||||
|
onError: setError,
|
||||||
|
onSuccess: newData => {
|
||||||
|
setItems(newData);
|
||||||
|
if (callback) callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
[user, adminMode]
|
||||||
|
);
|
||||||
|
|
||||||
|
const reloadTemplates = useCallback(() => {
|
||||||
setTemplates([]);
|
setTemplates([]);
|
||||||
getTemplates({
|
getTemplates({
|
||||||
showError: true,
|
showError: true,
|
||||||
|
@ -130,8 +150,12 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reload();
|
reloadItems();
|
||||||
}, [reload, user]);
|
}, [reloadItems]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
reloadTemplates();
|
||||||
|
}, [reloadTemplates]);
|
||||||
|
|
||||||
const localUpdateItem = useCallback(
|
const localUpdateItem = useCallback(
|
||||||
(data: ILibraryItem) => {
|
(data: ILibraryItem) => {
|
||||||
|
@ -160,7 +184,7 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
setLoading: setProcessing,
|
setLoading: setProcessing,
|
||||||
onError: setError,
|
onError: setError,
|
||||||
onSuccess: newSchema =>
|
onSuccess: newSchema =>
|
||||||
reload(() => {
|
reloadItems(() => {
|
||||||
if (user && !user.subscriptions.includes(newSchema.id)) {
|
if (user && !user.subscriptions.includes(newSchema.id)) {
|
||||||
user.subscriptions.push(newSchema.id);
|
user.subscriptions.push(newSchema.id);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +192,7 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[reload, user]
|
[reloadItems, user]
|
||||||
);
|
);
|
||||||
|
|
||||||
const destroyItem = useCallback(
|
const destroyItem = useCallback(
|
||||||
|
@ -179,7 +203,7 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
setLoading: setProcessing,
|
setLoading: setProcessing,
|
||||||
onError: setError,
|
onError: setError,
|
||||||
onSuccess: () =>
|
onSuccess: () =>
|
||||||
reload(() => {
|
reloadItems(() => {
|
||||||
if (user && user.subscriptions.includes(target)) {
|
if (user && user.subscriptions.includes(target)) {
|
||||||
user.subscriptions.splice(
|
user.subscriptions.splice(
|
||||||
user.subscriptions.findIndex(item => item === target),
|
user.subscriptions.findIndex(item => item === target),
|
||||||
|
@ -190,7 +214,7 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[setError, reload, user]
|
[setError, reloadItems, user]
|
||||||
);
|
);
|
||||||
|
|
||||||
const cloneItem = useCallback(
|
const cloneItem = useCallback(
|
||||||
|
@ -205,7 +229,7 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
setLoading: setProcessing,
|
setLoading: setProcessing,
|
||||||
onError: setError,
|
onError: setError,
|
||||||
onSuccess: newSchema =>
|
onSuccess: newSchema =>
|
||||||
reload(() => {
|
reloadItems(() => {
|
||||||
if (user && !user.subscriptions.includes(newSchema.id)) {
|
if (user && !user.subscriptions.includes(newSchema.id)) {
|
||||||
user.subscriptions.push(newSchema.id);
|
user.subscriptions.push(newSchema.id);
|
||||||
}
|
}
|
||||||
|
@ -213,7 +237,7 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[reload, setError, user]
|
[reloadItems, setError, user]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Reference in New Issue
Block a user