R: Move update-constituenta to RSForm

This commit is contained in:
Ivan 2024-07-31 14:01:39 +03:00
parent 2e19c6fa69
commit 6a21125e87
17 changed files with 266 additions and 304 deletions

View File

@ -95,10 +95,6 @@ class Constituenta(Model):
verbose_name = 'Конституента'
verbose_name_plural = 'Конституенты'
def get_absolute_url(self):
''' URL access. '''
return reverse('constituenta-detail', kwargs={'pk': self.pk})
def __str__(self) -> str:
return f'{self.alias}'

View File

@ -31,7 +31,7 @@ class CstSerializer(serializers.ModelSerializer):
''' serializer metadata. '''
model = Constituenta
fields = '__all__'
read_only_fields = ('id', 'order', 'alias', 'cst_type', 'definition_resolved', 'term_resolved')
read_only_fields = ('id', 'schema', 'order', 'alias', 'cst_type', 'definition_resolved', 'term_resolved')
def update(self, instance: Constituenta, validated_data) -> Constituenta:
data = validated_data # Note: use alias for better code readability

View File

@ -20,12 +20,6 @@ class TestConstituenta(TestCase):
self.assertEqual(str(cst), testStr)
def test_url(self):
testStr = 'X1'
cst = Constituenta.objects.create(alias=testStr, schema=self.schema1.model, order=1, convention='Test')
self.assertEqual(cst.get_absolute_url(), f'/api/constituents/{cst.pk}')
def test_order_not_null(self):
with self.assertRaises(IntegrityError):
Constituenta.objects.create(alias='X1', schema=self.schema1.model)

View File

@ -208,11 +208,11 @@ class TestRSForm(TestCase):
definition_formal=x1.alias
)
self.schema.substitute(x1, x2, True)
self.schema.substitute(x1, x2)
x2.refresh_from_db()
d1.refresh_from_db()
self.assertEqual(self.schema.constituents().count(), 2)
self.assertEqual(x2.term_raw, 'Test')
self.assertEqual(x2.term_raw, 'Test2')
self.assertEqual(d1.definition_formal, x2.alias)

View File

@ -1,6 +1,4 @@
''' Tests for REST API. '''
from .t_cctext import *
from .t_constituents import *
from .t_operations import *
from .t_rsforms import *
from .t_rslang import *

View File

@ -1,102 +0,0 @@
''' Testing API: Constituents. '''
from apps.rsform.models import Constituenta, CstType, RSForm
from shared.EndpointTester import EndpointTester, decl_endpoint
class TestConstituentaAPI(EndpointTester):
''' Testing Constituenta view. '''
def setUp(self):
super().setUp()
self.rsform_owned = RSForm.create(title='Test', alias='T1', owner=self.user)
self.rsform_unowned = RSForm.create(title='Test2', alias='T2')
self.cst1 = Constituenta.objects.create(
alias='X1',
cst_type=CstType.BASE,
schema=self.rsform_owned.model,
order=1,
convention='Test',
term_raw='Test1',
term_resolved='Test1R',
term_forms=[{'text': 'form1', 'tags': 'sing,datv'}])
self.cst2 = Constituenta.objects.create(
alias='X2',
cst_type=CstType.BASE,
schema=self.rsform_unowned.model,
order=1,
convention='Test1',
term_raw='Test2',
term_resolved='Test2R'
)
self.cst3 = Constituenta.objects.create(
alias='X3',
schema=self.rsform_owned.model,
order=2,
term_raw='Test3',
term_resolved='Test3',
definition_raw='Test1',
definition_resolved='Test2'
)
self.invalid_cst = self.cst3.pk + 1337
@decl_endpoint('/api/constituents/{item}', method='get')
def test_retrieve(self):
self.executeNotFound(item=self.invalid_cst)
response = self.executeOK(item=self.cst1.pk)
self.assertEqual(response.data['alias'], self.cst1.alias)
self.assertEqual(response.data['convention'], self.cst1.convention)
@decl_endpoint('/api/constituents/{item}', method='patch')
def test_partial_update(self):
data = {'convention': 'tt'}
self.executeForbidden(data=data, item=self.cst2.pk)
self.logout()
self.executeForbidden(data=data, item=self.cst1.pk)
self.login()
response = self.executeOK(data=data, item=self.cst1.pk)
self.cst1.refresh_from_db()
self.assertEqual(response.data['convention'], 'tt')
self.assertEqual(self.cst1.convention, 'tt')
self.executeOK(data=data, item=self.cst1.pk)
@decl_endpoint('/api/constituents/{item}', method='patch')
def test_update_resolved_no_refs(self):
data = {
'term_raw': 'New term',
'definition_raw': 'New def'
}
response = self.executeOK(data=data, item=self.cst3.pk)
self.cst3.refresh_from_db()
self.assertEqual(response.data['term_resolved'], 'New term')
self.assertEqual(self.cst3.term_resolved, 'New term')
self.assertEqual(response.data['definition_resolved'], 'New def')
self.assertEqual(self.cst3.definition_resolved, 'New def')
@decl_endpoint('/api/constituents/{item}', method='patch')
def test_update_resolved_refs(self):
data = {
'term_raw': '@{X1|nomn,sing}',
'definition_raw': '@{X1|nomn,sing} @{X1|sing,datv}'
}
response = self.executeOK(data=data, item=self.cst3.pk)
self.cst3.refresh_from_db()
self.assertEqual(self.cst3.term_resolved, self.cst1.term_resolved)
self.assertEqual(response.data['term_resolved'], self.cst1.term_resolved)
self.assertEqual(self.cst3.definition_resolved, f'{self.cst1.term_resolved} form1')
self.assertEqual(response.data['definition_resolved'], f'{self.cst1.term_resolved} form1')
@decl_endpoint('/api/constituents/{item}', method='patch')
def test_readonly_cst_fields(self):
data = {'alias': 'X33', 'order': 10}
response = self.executeOK(data=data, item=self.cst1.pk)
self.assertEqual(response.data['alias'], 'X1')
self.assertEqual(response.data['alias'], self.cst1.alias)
self.assertEqual(response.data['order'], self.cst1.order)

View File

@ -1,80 +0,0 @@
''' Testing API: Operations. '''
from apps.rsform.models import Constituenta, CstType, RSForm
from shared.EndpointTester import EndpointTester, decl_endpoint
class TestInlineSynthesis(EndpointTester):
''' Testing Operations endpoints. '''
@decl_endpoint('/api/operations/inline-synthesis', method='patch')
def setUp(self):
super().setUp()
self.schema1 = RSForm.create(title='Test1', alias='T1', owner=self.user)
self.schema2 = RSForm.create(title='Test2', alias='T2', owner=self.user)
self.unowned = RSForm.create(title='Test3', alias='T3')
def test_inline_synthesis_inputs(self):
invalid_id = 1338
data = {
'receiver': self.unowned.model.pk,
'source': self.schema1.model.pk,
'items': [],
'substitutions': []
}
self.executeForbidden(data=data)
data['receiver'] = invalid_id
self.executeBadData(data=data)
data['receiver'] = self.schema1.model.pk
data['source'] = invalid_id
self.executeBadData(data=data)
data['source'] = self.schema1.model.pk
self.executeOK(data=data)
data['items'] = [invalid_id]
self.executeBadData(data=data)
def test_inline_synthesis(self):
ks1_x1 = self.schema1.insert_new('X1', term_raw='KS1X1') # -> delete
ks1_x2 = self.schema1.insert_new('X2', term_raw='KS1X2') # -> X2
ks1_s1 = self.schema1.insert_new('S1', definition_formal='X2', term_raw='KS1S1') # -> S1
ks1_d1 = self.schema1.insert_new('D1', definition_formal=r'S1\X1\X2') # -> D1
ks2_x1 = self.schema2.insert_new('X1', term_raw='KS2X1') # -> delete
ks2_x2 = self.schema2.insert_new('X2', term_raw='KS2X2') # -> X4
ks2_s1 = self.schema2.insert_new('S1', definition_formal='X2×X2', term_raw='KS2S1') # -> S2
ks2_d1 = self.schema2.insert_new('D1', definition_formal=r'S1\X1\X2') # -> D2
ks2_a1 = self.schema2.insert_new('A1', definition_formal='1=1') # -> not included in items
data = {
'receiver': self.schema1.model.pk,
'source': self.schema2.model.pk,
'items': [ks2_x1.pk, ks2_x2.pk, ks2_s1.pk, ks2_d1.pk],
'substitutions': [
{
'original': ks1_x1.pk,
'substitution': ks2_s1.pk
},
{
'original': ks2_x1.pk,
'substitution': ks1_s1.pk
}
]
}
response = self.executeOK(data=data)
result = {item['alias']: item for item in response.data['items']}
self.assertEqual(len(result), 6)
self.assertEqual(result['X2']['term_raw'], ks1_x2.term_raw)
self.assertEqual(result['X2']['order'], 1)
self.assertEqual(result['X4']['term_raw'], ks2_x2.term_raw)
self.assertEqual(result['X4']['order'], 2)
self.assertEqual(result['S1']['term_raw'], ks2_x1.term_raw)
self.assertEqual(result['S2']['term_raw'], ks2_s1.term_raw)
self.assertEqual(result['S1']['definition_formal'], 'X2')
self.assertEqual(result['S2']['definition_formal'], 'X4×X4')
self.assertEqual(result['D1']['definition_formal'], r'S1\S2\X2')
self.assertEqual(result['D2']['definition_formal'], r'S2\S1\X4')

View File

@ -482,3 +482,172 @@ class TestRSFormViewset(EndpointTester):
self.assertEqual(len(items), 2)
self.assertEqual(items[0]['order'], f1.order + 1)
self.assertEqual(items[0]['definition_formal'], '[α∈X1, β∈X1] Pr1(F10[α,β])')
class TestConstituentaAPI(EndpointTester):
''' Testing Constituenta view. '''
def setUp(self):
super().setUp()
self.rsform_owned = RSForm.create(title='Test', alias='T1', owner=self.user)
self.rsform_unowned = RSForm.create(title='Test2', alias='T2')
self.cst1 = Constituenta.objects.create(
alias='X1',
cst_type=CstType.BASE,
schema=self.rsform_owned.model,
order=1,
convention='Test',
term_raw='Test1',
term_resolved='Test1R',
term_forms=[{'text': 'form1', 'tags': 'sing,datv'}])
self.cst2 = Constituenta.objects.create(
alias='X2',
cst_type=CstType.BASE,
schema=self.rsform_unowned.model,
order=1,
convention='Test1',
term_raw='Test2',
term_resolved='Test2R'
)
self.cst3 = Constituenta.objects.create(
alias='X3',
schema=self.rsform_owned.model,
order=2,
term_raw='Test3',
term_resolved='Test3',
definition_raw='Test1',
definition_resolved='Test2'
)
self.invalid_cst = self.cst3.pk + 1337
@decl_endpoint('/api/rsforms/{schema}/update-cst', method='patch')
def test_partial_update(self):
data = {'id': self.cst1.pk, 'convention': 'tt'}
self.executeForbidden(data=data, schema=self.rsform_unowned.model.pk)
self.logout()
self.executeForbidden(data=data, schema=self.rsform_owned.model.pk)
self.login()
response = self.executeOK(data=data, schema=self.rsform_owned.model.pk)
self.cst1.refresh_from_db()
self.assertEqual(response.data['convention'], 'tt')
self.assertEqual(self.cst1.convention, 'tt')
self.executeOK(data=data, schema=self.rsform_owned.model.pk)
@decl_endpoint('/api/rsforms/{schema}/update-cst', method='patch')
def test_update_resolved_no_refs(self):
data = {
'id': self.cst3.pk,
'term_raw': 'New term',
'definition_raw': 'New def'
}
response = self.executeOK(data=data, schema=self.rsform_owned.model.pk)
self.cst3.refresh_from_db()
self.assertEqual(response.data['term_resolved'], 'New term')
self.assertEqual(self.cst3.term_resolved, 'New term')
self.assertEqual(response.data['definition_resolved'], 'New def')
self.assertEqual(self.cst3.definition_resolved, 'New def')
@decl_endpoint('/api/rsforms/{schema}/update-cst', method='patch')
def test_update_resolved_refs(self):
data = {
'id': self.cst3.pk,
'term_raw': '@{X1|nomn,sing}',
'definition_raw': '@{X1|nomn,sing} @{X1|sing,datv}'
}
response = self.executeOK(data=data, schema=self.rsform_owned.model.pk)
self.cst3.refresh_from_db()
self.assertEqual(self.cst3.term_resolved, self.cst1.term_resolved)
self.assertEqual(response.data['term_resolved'], self.cst1.term_resolved)
self.assertEqual(self.cst3.definition_resolved, f'{self.cst1.term_resolved} form1')
self.assertEqual(response.data['definition_resolved'], f'{self.cst1.term_resolved} form1')
@decl_endpoint('/api/rsforms/{schema}/update-cst', method='patch')
def test_readonly_cst_fields(self):
data = {
'id': self.cst1.pk,
'alias': 'X33',
'order': 10
}
response = self.executeOK(data=data, schema=self.rsform_owned.model.pk)
self.assertEqual(response.data['alias'], 'X1')
self.assertEqual(response.data['alias'], self.cst1.alias)
self.assertEqual(response.data['order'], self.cst1.order)
class TestInlineSynthesis(EndpointTester):
''' Testing Operations endpoints. '''
@decl_endpoint('/api/rsforms/inline-synthesis', method='patch')
def setUp(self):
super().setUp()
self.schema1 = RSForm.create(title='Test1', alias='T1', owner=self.user)
self.schema2 = RSForm.create(title='Test2', alias='T2', owner=self.user)
self.unowned = RSForm.create(title='Test3', alias='T3')
def test_inline_synthesis_inputs(self):
invalid_id = 1338
data = {
'receiver': self.unowned.model.pk,
'source': self.schema1.model.pk,
'items': [],
'substitutions': []
}
self.executeForbidden(data=data)
data['receiver'] = invalid_id
self.executeBadData(data=data)
data['receiver'] = self.schema1.model.pk
data['source'] = invalid_id
self.executeBadData(data=data)
data['source'] = self.schema1.model.pk
self.executeOK(data=data)
data['items'] = [invalid_id]
self.executeBadData(data=data)
def test_inline_synthesis(self):
ks1_x1 = self.schema1.insert_new('X1', term_raw='KS1X1') # -> delete
ks1_x2 = self.schema1.insert_new('X2', term_raw='KS1X2') # -> X2
ks1_s1 = self.schema1.insert_new('S1', definition_formal='X2', term_raw='KS1S1') # -> S1
ks1_d1 = self.schema1.insert_new('D1', definition_formal=r'S1\X1\X2') # -> D1
ks2_x1 = self.schema2.insert_new('X1', term_raw='KS2X1') # -> delete
ks2_x2 = self.schema2.insert_new('X2', term_raw='KS2X2') # -> X4
ks2_s1 = self.schema2.insert_new('S1', definition_formal='X2×X2', term_raw='KS2S1') # -> S2
ks2_d1 = self.schema2.insert_new('D1', definition_formal=r'S1\X1\X2') # -> D2
ks2_a1 = self.schema2.insert_new('A1', definition_formal='1=1') # -> not included in items
data = {
'receiver': self.schema1.model.pk,
'source': self.schema2.model.pk,
'items': [ks2_x1.pk, ks2_x2.pk, ks2_s1.pk, ks2_d1.pk],
'substitutions': [
{
'original': ks1_x1.pk,
'substitution': ks2_s1.pk
},
{
'original': ks2_x1.pk,
'substitution': ks1_s1.pk
}
]
}
response = self.executeOK(data=data)
result = {item['alias']: item for item in response.data['items']}
self.assertEqual(len(result), 6)
self.assertEqual(result['X2']['order'], 1)
self.assertEqual(result['X4']['order'], 2)
self.assertEqual(result['S1']['definition_formal'], 'X2')
self.assertEqual(result['S2']['definition_formal'], 'X4×X4')
self.assertEqual(result['D1']['definition_formal'], r'S1\S2\X2')
self.assertEqual(result['D2']['definition_formal'], r'S2\S1\X4')

View File

@ -9,11 +9,9 @@ library_router.register('rsforms', views.RSFormViewSet, 'RSForm')
urlpatterns = [
path('constituents/<int:pk>', views.ConstituentAPIView.as_view(), name='constituenta-detail'),
path('rsforms/import-trs', views.TrsImportView.as_view()),
path('rsforms/create-detailed', views.create_rsform),
path('operations/inline-synthesis', views.inline_synthesis),
path('rsforms/inline-synthesis', views.inline_synthesis),
path('rslang/parse-expression', views.parse_expression),
path('rslang/to-ascii', views.convert_to_ascii),

View File

@ -1,6 +1,4 @@
''' REST API: Endpoint processors. '''
from .cctext import generate_lexeme, inflect, parse_text
from .constituents import ConstituentAPIView
from .operations import inline_synthesis
from .rsforms import RSFormViewSet, TrsImportView, create_rsform
from .rsforms import RSFormViewSet, TrsImportView, create_rsform, inline_synthesis
from .rslang import convert_to_ascii, convert_to_math, parse_expression

View File

@ -1,16 +0,0 @@
''' Endpoints for Constituenta. '''
from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import generics
from shared import permissions
from .. import models as m
from .. import serializers as s
@extend_schema(tags=['Constituenta'])
@extend_schema_view()
class ConstituentAPIView(generics.RetrieveUpdateAPIView, permissions.EditorMixin):
''' Endpoint: Get / Update Constituenta. '''
queryset = m.Constituenta.objects.all()
serializer_class = s.CstSerializer

View File

@ -1,50 +0,0 @@
''' Endpoints for RSForm. '''
from typing import cast
from django.db import transaction
from drf_spectacular.utils import extend_schema
from rest_framework import status as c
from rest_framework.decorators import api_view
from rest_framework.request import Request
from rest_framework.response import Response
from .. import models as m
from .. import serializers as s
@extend_schema(
summary='Inline synthesis: merge one schema into another',
tags=['Operations'],
request=s.InlineSynthesisSerializer,
responses={c.HTTP_200_OK: s.RSFormParseSerializer}
)
@api_view(['PATCH'])
def inline_synthesis(request: Request):
''' Endpoint: Inline synthesis. '''
serializer = s.InlineSynthesisSerializer(
data=request.data,
context={'user': request.user}
)
serializer.is_valid(raise_exception=True)
receiver = m.RSForm(serializer.validated_data['receiver'])
items = cast(list[m.Constituenta], serializer.validated_data['items'])
with transaction.atomic():
new_items = receiver.insert_copy(items)
for substitution in serializer.validated_data['substitutions']:
original = cast(m.Constituenta, substitution['original'])
replacement = cast(m.Constituenta, substitution['substitution'])
if original in items:
index = next(i for (i, cst) in enumerate(items) if cst == original)
original = new_items[index]
else:
index = next(i for (i, cst) in enumerate(items) if cst == replacement)
replacement = new_items[index]
receiver.substitute(original, replacement)
receiver.restore_order()
return Response(
status=c.HTTP_200_OK,
data=s.RSFormParseSerializer(receiver.model).data
)

View File

@ -12,6 +12,7 @@ from rest_framework import views, viewsets
from rest_framework.decorators import action, api_view
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ValidationError
from apps.library.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead
from apps.library.serializers import LibraryItemSerializer
@ -45,7 +46,8 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
'substitute',
'restore_order',
'reset_aliases',
'produce_structure'
'produce_structure',
'update_cst'
]:
permission_list = [permissions.ItemEditor]
elif self.action in [
@ -88,15 +90,43 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
new_cst = m.RSForm(schema).create_cst(data, insert_after)
schema.refresh_from_db()
response = Response(
return Response(
status=c.HTTP_201_CREATED,
data={
'new_cst': s.CstSerializer(new_cst).data,
'schema': s.RSFormParseSerializer(schema).data
}
)
response['Location'] = new_cst.get_absolute_url()
return response
@extend_schema(
summary='update persistent attributes of a given constituenta',
tags=['RSForm'],
request=s.CstSerializer,
responses={
c.HTTP_200_OK: s.CstSerializer,
c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
)
@action(detail=True, methods=['patch'], url_path='update-cst')
def update_cst(self, request: Request, pk):
''' Update persistent attributes of a given constituenta. '''
schema = self._get_item()
serializer = s.CstSerializer(data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
cst = m.Constituenta.objects.get(pk=request.data['id'])
if cst.schema != schema:
raise ValidationError({
f'schema': msg.constituentaNotInRSform(schema.title)
})
serializer.update(instance=cst, validated_data=serializer.validated_data)
return Response(
status=c.HTTP_200_OK,
data=s.CstSerializer(cst).data
)
@extend_schema(
summary='produce the structure of a given constituenta',
@ -521,3 +551,41 @@ def _prepare_rsform_data(data: dict, request: Request, owner: Union[User, None])
data['access_policy'] = request.data.get('access_policy', AccessPolicy.PUBLIC)
data['location'] = request.data.get('location', LocationHead.USER)
@extend_schema(
summary='Inline synthesis: merge one schema into another',
tags=['Operations'],
request=s.InlineSynthesisSerializer,
responses={c.HTTP_200_OK: s.RSFormParseSerializer}
)
@api_view(['PATCH'])
def inline_synthesis(request: Request):
''' Endpoint: Inline synthesis. '''
serializer = s.InlineSynthesisSerializer(
data=request.data,
context={'user': request.user}
)
serializer.is_valid(raise_exception=True)
receiver = m.RSForm(serializer.validated_data['receiver'])
items = cast(list[m.Constituenta], serializer.validated_data['items'])
with transaction.atomic():
new_items = receiver.insert_copy(items)
for substitution in serializer.validated_data['substitutions']:
original = cast(m.Constituenta, substitution['original'])
replacement = cast(m.Constituenta, substitution['substitution'])
if original in items:
index = next(i for (i, cst) in enumerate(items) if cst == original)
original = new_items[index]
else:
index = next(i for (i, cst) in enumerate(items) if cst == replacement)
replacement = new_items[index]
receiver.substitute(original, replacement)
receiver.restore_order()
return Response(
status=c.HTTP_200_OK,
data=s.RSFormParseSerializer(receiver.model).data
)

View File

@ -1,14 +0,0 @@
/**
* Endpoints: constituents.
*/
import { IConstituentaMeta, ICstUpdateData } from '@/models/rsform';
import { AxiosPatch, FrontExchange } from './apiTransport';
export function patchConstituenta(target: string, request: FrontExchange<ICstUpdateData, IConstituentaMeta>) {
AxiosPatch({
endpoint: `/api/constituents/${target}`,
request: request
});
}

View File

@ -1,14 +0,0 @@
/**
* Endpoints: operations.
*/
import { IInlineSynthesisData, IRSFormData } from '@/models/rsform';
import { AxiosPatch, FrontExchange } from './apiTransport';
export function patchInlineSynthesis(request: FrontExchange<IInlineSynthesisData, IRSFormData>) {
AxiosPatch({
endpoint: `/api/operations/inline-synthesis`,
request: request
});
}

View File

@ -6,10 +6,13 @@ import { ILibraryCreateData, ILibraryItem } from '@/models/library';
import { ICstSubstituteData } from '@/models/oss';
import {
IConstituentaList,
IConstituentaMeta,
ICstCreateData,
ICstCreatedResponse,
ICstMovetoData,
ICstRenameData,
ICstUpdateData,
IInlineSynthesisData,
IProduceStructureResponse,
IRSFormData,
IRSFormUploadData,
@ -68,6 +71,13 @@ export function postCreateConstituenta(schema: string, request: FrontExchange<IC
});
}
export function patchUpdateConstituenta(schema: string, request: FrontExchange<ICstUpdateData, IConstituentaMeta>) {
AxiosPatch({
endpoint: `/api/rsforms/${schema}/update-cst`,
request: request
});
}
export function patchDeleteConstituenta(schema: string, request: FrontExchange<IConstituentaList, IRSFormData>) {
AxiosPatch({
endpoint: `/api/rsforms/${schema}/delete-multiple-cst`,
@ -135,3 +145,10 @@ export function patchUploadTRS(target: string, request: FrontExchange<IRSFormUpl
}
});
}
export function patchInlineSynthesis(request: FrontExchange<IInlineSynthesisData, IRSFormData>) {
AxiosPatch({
endpoint: `/api/rsforms/inline-synthesis`,
request: request
});
}

View File

@ -3,7 +3,6 @@
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
import { DataCallback } from '@/backend/apiTransport';
import { patchConstituenta } from '@/backend/constituents';
import {
deleteUnsubscribe,
patchLibraryItem,
@ -14,16 +13,17 @@ import {
postCreateVersion,
postSubscribe
} from '@/backend/library';
import { patchInlineSynthesis } from '@/backend/operations';
import {
getTRSFile,
patchDeleteConstituenta,
patchInlineSynthesis,
patchMoveConstituenta,
patchProduceStructure,
patchRenameConstituenta,
patchResetAliases,
patchRestoreOrder,
patchSubstituteConstituents,
patchUpdateConstituenta,
patchUploadTRS,
postCreateConstituenta
} from '@/backend/rsforms';
@ -439,7 +439,7 @@ export const RSFormState = ({ itemID, versionID, children }: RSFormStateProps) =
const cstUpdate = useCallback(
(data: ICstUpdateData, callback?: DataCallback<IConstituentaMeta>) => {
setProcessingError(undefined);
patchConstituenta(String(data.id), {
patchUpdateConstituenta(itemID, {
data: data,
showError: true,
setLoading: setProcessing,