From 0ee0e65ac5a133a5b43762d3a24f9fd0a1aa5520 Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Sat, 20 Jul 2024 13:12:28 +0300 Subject: [PATCH] Prepare merge into main --- ...ph_operationnode_synthesisedge_and_more.py | 69 ---- .../backend/apps/rsform/models/Synthesis.py | 149 -------- .../apps/rsform/serializers/__init__.py | 11 - .../apps/rsform/serializers/synthesis.py | 117 ------ rsconcept/backend/apps/rsform/urls.py | 5 +- rsconcept/backend/apps/rsform/utils.py | 13 - .../backend/apps/rsform/views/__init__.py | 6 - .../backend/apps/rsform/views/synthesis.py | 230 ------------ rsconcept/frontend/.vscode/launch.json | 15 - rsconcept/frontend/src/app/Router.tsx | 5 - rsconcept/frontend/src/app/urls.ts | 3 +- .../src/components/ui/Synthesis/InputNode.tsx | 61 --- .../components/ui/Synthesis/OperationNode.tsx | 80 ---- .../components/ui/Synthesis/OperationUI.tsx | 21 -- .../components/ui/Synthesis/SynthesisFlow.css | 18 - .../components/ui/Synthesis/SynthesisFlow.tsx | 43 --- .../DlgInlineSynthesis/TabSubstitutions.tsx | 3 +- .../DlgOssGraph/DlgSelectInputScheme.tsx | 79 ---- .../src/dialogs/DlgOssGraph/DlgSynthesis.tsx | 107 ------ rsconcept/frontend/src/models/OssLoader.ts | 2 +- rsconcept/frontend/src/models/oss.ts | 54 +-- .../src/pages/OssPage/SynthesisContext.tsx | 350 ------------------ .../src/pages/OssPage/SynthesisOperation.tsx | 5 - .../OssPage/SynthesisSubstitutionsTab.tsx | 41 -- .../src/pages/OssPage/SynthesisToolbar.tsx | 45 --- .../src/pages/SynthesisPage/SynthesisPage.tsx | 165 --------- .../src/pages/SynthesisPage/index.tsx | 1 - 27 files changed, 6 insertions(+), 1692 deletions(-) delete mode 100644 rsconcept/backend/apps/rsform/migrations/0008_inputnode_synthesisgraph_operationnode_synthesisedge_and_more.py delete mode 100644 rsconcept/backend/apps/rsform/models/Synthesis.py delete mode 100644 rsconcept/backend/apps/rsform/serializers/synthesis.py delete mode 100644 rsconcept/backend/apps/rsform/views/synthesis.py delete mode 100644 rsconcept/frontend/.vscode/launch.json delete mode 100644 rsconcept/frontend/src/components/ui/Synthesis/InputNode.tsx delete mode 100644 rsconcept/frontend/src/components/ui/Synthesis/OperationNode.tsx delete mode 100644 rsconcept/frontend/src/components/ui/Synthesis/OperationUI.tsx delete mode 100644 rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.css delete mode 100644 rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.tsx delete mode 100644 rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSelectInputScheme.tsx delete mode 100644 rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSynthesis.tsx delete mode 100644 rsconcept/frontend/src/pages/OssPage/SynthesisContext.tsx delete mode 100644 rsconcept/frontend/src/pages/OssPage/SynthesisOperation.tsx delete mode 100644 rsconcept/frontend/src/pages/OssPage/SynthesisSubstitutionsTab.tsx delete mode 100644 rsconcept/frontend/src/pages/OssPage/SynthesisToolbar.tsx delete mode 100644 rsconcept/frontend/src/pages/SynthesisPage/SynthesisPage.tsx delete mode 100644 rsconcept/frontend/src/pages/SynthesisPage/index.tsx diff --git a/rsconcept/backend/apps/rsform/migrations/0008_inputnode_synthesisgraph_operationnode_synthesisedge_and_more.py b/rsconcept/backend/apps/rsform/migrations/0008_inputnode_synthesisgraph_operationnode_synthesisedge_and_more.py deleted file mode 100644 index c2c381d4..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0008_inputnode_synthesisgraph_operationnode_synthesisedge_and_more.py +++ /dev/null @@ -1,69 +0,0 @@ -# Generated by Django 5.0.5 on 2024-06-21 15:47 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0007_location_and_flags'), - ] - - operations = [ - migrations.CreateModel( - name='InputNode', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('vertical_coordinate', models.IntegerField(verbose_name='Вертикальная координата звена')), - ('horizontal_coordinate', models.IntegerField(verbose_name='Горизонтальная координата звена')), - ('rsform_id', models.IntegerField(null=True, verbose_name='Схема')), - ], - ), - migrations.CreateModel( - name='SynthesisGraph', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('status', models.CharField(choices=[('Draft', 'Draft'), ('Completed', 'Completed'), ('Warning', 'Warning'), ('Failed', 'Failed')], max_length=20, verbose_name='Статус операции слияния')), - ], - ), - migrations.CreateModel( - name='OperationNode', - fields=[ - ('inputnode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='rsform.inputnode')), - ('name', models.CharField(max_length=20, verbose_name='Название')), - ('status', models.CharField(choices=[('Draft', 'Draft'), ('Completed', 'Completed'), ('Warning', 'Warning'), ('Failed', 'Failed')], max_length=20, verbose_name='Статус операции слияния')), - ('left_parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rsform_library_item_left', to='rsform.libraryitem', verbose_name='Левый предок')), - ('right_parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rsform_library_item_right', to='rsform.libraryitem', verbose_name='Правый предок')), - ], - bases=('rsform.inputnode',), - ), - migrations.CreateModel( - name='SynthesisEdge', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('decoded_id', models.CharField(max_length=30, verbose_name='Id ребра на фронте')), - ('source_handle', models.CharField(max_length=30, verbose_name='')), - ('node_from', models.IntegerField(verbose_name='Звено-предок')), - ('node_to', models.IntegerField(verbose_name='Звено-наследник')), - ('graph_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.synthesisgraph', verbose_name='Схема синтеза')), - ], - ), - migrations.AddField( - model_name='inputnode', - name='graph_id', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.synthesisgraph', verbose_name='Схема синтеза'), - ), - migrations.CreateModel( - name='SynthesisSubstitution', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('deleteRight', models.BooleanField(verbose_name='Удалить правую')), - ('takeLeftTerm', models.BooleanField(verbose_name='Использовать термин левой')), - ('graph_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.synthesisgraph', verbose_name='Схема синтеза')), - ('leftCst', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='constituenta_original', to='rsform.constituenta', verbose_name='Конституента')), - ('rightCst', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='constituenta_substitution', to='rsform.constituenta', verbose_name='Подстановка')), - ('operation_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.operationnode', verbose_name='Операция синтеза')), - ], - ), - ] diff --git a/rsconcept/backend/apps/rsform/models/Synthesis.py b/rsconcept/backend/apps/rsform/models/Synthesis.py deleted file mode 100644 index 8b1f0d9f..00000000 --- a/rsconcept/backend/apps/rsform/models/Synthesis.py +++ /dev/null @@ -1,149 +0,0 @@ -''' Models: Synthesis. ''' - -from django.db.models import ( - CASCADE, - SET_NULL, - BooleanField, - CharField, - ForeignKey, - IntegerField, - Model, - TextChoices -) - - -class OperationStatus(TextChoices): - ''' Operation status enumeration. ''' - DRAFT = 'Draft', - COMPLETED = 'Completed', - WARNING = 'Warning', - FAILED = 'Failed' - - -class GraphStatus(TextChoices): - ''' Graph status enumeration. ''' - DRAFT = 'Draft', - COMPLETED = 'Completed', - WARNING = 'Warning', - FAILED = 'Failed' - - -class SynthesisGraph(Model): - status: CharField = CharField( - verbose_name='Статус операции слияния', - max_length=20, - choices=GraphStatus - ) - - -class InputNode(Model): - graph_id: ForeignKey = ForeignKey( - verbose_name='Схема синтеза', - to=SynthesisGraph, - on_delete=CASCADE - ) - - vertical_coordinate: IntegerField = IntegerField( - verbose_name='Вертикальная координата звена', - ) - - horizontal_coordinate: IntegerField = IntegerField( - verbose_name='Горизонтальная координата звена', - ) - - rsform_id: IntegerField = IntegerField( - verbose_name='Схема', - null=True - ) - - -class OperationNode(InputNode): - name: CharField = CharField( - verbose_name='Название', - max_length=20 - ) - - status: CharField = CharField( - verbose_name='Статус операции слияния', - max_length=20, - choices=OperationStatus - ) - - left_parent: ForeignKey = ForeignKey( - verbose_name='Левый предок', - to='rsform.LibraryItem', - related_name='rsform_library_item_left', - on_delete=SET_NULL, - null=True - ) - - right_parent: ForeignKey = ForeignKey( - verbose_name='Правый предок', - to='rsform.LibraryItem', - related_name='rsform_library_item_right', - on_delete=SET_NULL, - null=True - ) - - -class SynthesisSubstitution(Model): - graph_id: ForeignKey = ForeignKey( - verbose_name='Схема синтеза', - to=SynthesisGraph, - on_delete=CASCADE - ) - - operation_id: ForeignKey = ForeignKey( - verbose_name='Операция синтеза', - to=OperationNode, - on_delete=CASCADE - ) - - leftCst: ForeignKey = ForeignKey( - verbose_name='Конституента', - to='Constituenta', - related_name='constituenta_original', - on_delete=SET_NULL, - null=True - ) - - rightCst: ForeignKey = ForeignKey( - verbose_name='Подстановка', - to='Constituenta', - related_name='constituenta_substitution', - on_delete=SET_NULL, - null=True - ) - - deleteRight: BooleanField = BooleanField( - verbose_name='Удалить правую' - ) - - takeLeftTerm: BooleanField = BooleanField( - verbose_name='Использовать термин левой' - ) - - -class SynthesisEdge(Model): - decoded_id: CharField = CharField( - verbose_name='Id ребра на фронте', - max_length=30, - ) - - source_handle: CharField = CharField( - verbose_name='', - max_length=30, - ) - graph_id: ForeignKey = ForeignKey( - verbose_name='Схема синтеза', - to=SynthesisGraph, - on_delete=CASCADE - ) - - node_from: IntegerField = IntegerField( - verbose_name='Звено-предок', - ) - - node_to: IntegerField = IntegerField( - verbose_name='Звено-наследник', - ) diff --git a/rsconcept/backend/apps/rsform/serializers/__init__.py b/rsconcept/backend/apps/rsform/serializers/__init__.py index 797fcaef..897a27c9 100644 --- a/rsconcept/backend/apps/rsform/serializers/__init__.py +++ b/rsconcept/backend/apps/rsform/serializers/__init__.py @@ -39,14 +39,3 @@ from .schema_typing import ( NewVersionResponse, ResultTextResponse ) - -from .io_pyconcept import PyConceptAdapter -from .io_files import ( - FileSerializer, - RSFormUploadSerializer, - RSFormTRSSerializer -) - -from .synthesis import ( - SynthesisGraphSerializer -) diff --git a/rsconcept/backend/apps/rsform/serializers/synthesis.py b/rsconcept/backend/apps/rsform/serializers/synthesis.py deleted file mode 100644 index 91df80bb..00000000 --- a/rsconcept/backend/apps/rsform/serializers/synthesis.py +++ /dev/null @@ -1,117 +0,0 @@ -''' Synthesis serializers. ''' - -from rest_framework import serializers - -from ..models.Synthesis import ( - InputNode, - OperationNode, - SynthesisEdge, - SynthesisGraph, - SynthesisSubstitution -) - - -class SynthesisGraphSerializer(serializers.ModelSerializer): - class Meta: - model = SynthesisGraph - fields = '__all__' - - def create(self, validated_data): - graph, created = SynthesisGraph.objects.update_or_create( - id=validated_data['id'], - defaults={'status': validated_data['status']} - ) - return graph - - -class InputNodeSerializer(serializers.ModelSerializer): - class Meta: - model = InputNode - fields = '__all__' - - def create(self, validated_data_list): - for validated_data in validated_data_list: - input_node, created = InputNode.objects.update_or_create( - id=validated_data['id'] if validated_data.get('id') else None, - defaults={ - 'graph_id': validated_data['graph_id'], - 'vertical_coordinate': validated_data['vertical_coordinate'], - 'horizontal_coordinate': validated_data['horizontal_coordinate'], - 'rsform_id': validated_data['rsform_id'], - } - ) - return - - -class OperationNodeSerializer(serializers.ModelSerializer): - class Meta: - model = OperationNode - fields = '__all__' - - def create(self, validated_data_list): - operations = [] - for validated_data in validated_data_list: - operation_node, created = OperationNode.objects.update_or_create( - id=validated_data['id'], - defaults={ - 'graph_id': validated_data['graph_id'], - 'vertical_coordinate': validated_data['vertical_coordinate'], - 'horizontal_coordinate': validated_data['horizontal_coordinate'], - 'rsform_id': validated_data['rsform_id'], - 'left_parent': validated_data.get('left_parent'), - 'right_parent': validated_data.get('right_parent'), - } - ) - operations.append(operation_node) - return operations - - -class SynthesisSubstitutionSerializer(serializers.ModelSerializer): - class Meta: - model = SynthesisSubstitution - fields = '__all__' - - def create(self, validated_data_list): - substitutions = [] - for validated_data in validated_data_list: - substitution, created = SynthesisSubstitution.objects.update_or_create( - id=validated_data['id'], - defaults={ - 'operation_id': validated_data['operation_id'], - 'graph_id': validated_data['graph_id'], - 'leftCst': validated_data['leftCst'], - 'rightCst': validated_data['rightCst'], - 'deleteRight': validated_data['deleteRight'], - 'takeLeftTerm': validated_data['takeLeftTerm'], - } - ) - substitutions.append(substitution) - return substitutions - - -class SynthesisEdgeSerializer(serializers.ModelSerializer): - class Meta: - model = SynthesisEdge - fields = '__all__' - - def create(self, validated_data_list): - for validated_data in validated_data_list: - substitution, created = SynthesisEdge.objects.update_or_create( - id=validated_data['id'], - defaults={ - 'graph_id': validated_data['graph_id'], - 'decoded_id': validated_data['decoded_id'], - 'source_handle': validated_data['source_handle'], - 'node_from': validated_data['node_from'], - 'node_to': validated_data['node_to'], - } - ) - return - - -class RunSingleSynthesis(serializers.Serializer): - operationId = serializers.IntegerField() - - -class RunSingleSynthesisResponse(serializers.Serializer): - rsformId = serializers.IntegerField() diff --git a/rsconcept/backend/apps/rsform/urls.py b/rsconcept/backend/apps/rsform/urls.py index fb4f258f..d4df9cb0 100644 --- a/rsconcept/backend/apps/rsform/urls.py +++ b/rsconcept/backend/apps/rsform/urls.py @@ -30,9 +30,6 @@ urlpatterns = [ path('cctext/inflect', views.inflect), path('cctext/generate-lexeme', views.generate_lexeme), path('cctext/parse', views.parse_text), - path('synthesis/run_single', views.run_synthesis_view), - path('synthesis/run_all', views.run_synthesis_graph_view), - path('synthesis/save', views.save_synthesis_graph), - path('synthesis/', views.get_synthesis_graph), + path('', include(library_router.urls)), ] diff --git a/rsconcept/backend/apps/rsform/utils.py b/rsconcept/backend/apps/rsform/utils.py index b096669d..5b3e1d80 100644 --- a/rsconcept/backend/apps/rsform/utils.py +++ b/rsconcept/backend/apps/rsform/utils.py @@ -1,5 +1,4 @@ ''' Utility functions ''' -import copy import json import re from io import BytesIO @@ -67,15 +66,3 @@ def filename_for_schema(alias: str) -> str: # are not supported by some browsers return 'Schema.trs' return alias + '.trs' - - -def clone_rsform(rsform): - rsform_copy = copy.deepcopy(rsform) - rsform_copy.item.pk = None - # rsform_copy.item.owner = "System" - rsform_copy.item.comment = "Temporary cloned rsform" - rsform_copy.item.save() - - rsform_copy.insert_copy(items=rsform.item.constituenta_set.all(), position=1) - rsform_copy.item.save() - return rsform_copy diff --git a/rsconcept/backend/apps/rsform/views/__init__.py b/rsconcept/backend/apps/rsform/views/__init__.py index 57cd8ca8..61c0a1d0 100644 --- a/rsconcept/backend/apps/rsform/views/__init__.py +++ b/rsconcept/backend/apps/rsform/views/__init__.py @@ -5,10 +5,4 @@ from .library import LibraryActiveView, LibraryAdminView, LibraryTemplatesView, from .operations import inline_synthesis from .rsforms import RSFormViewSet, TrsImportView, create_rsform from .rslang import convert_to_ascii, convert_to_math, parse_expression -from .synthesis import ( - get_synthesis_graph, - run_synthesis_graph_view, - run_synthesis_view, - save_synthesis_graph -) from .versions import VersionViewset, create_version, export_file, retrieve_version diff --git a/rsconcept/backend/apps/rsform/views/synthesis.py b/rsconcept/backend/apps/rsform/views/synthesis.py deleted file mode 100644 index 4ac74c04..00000000 --- a/rsconcept/backend/apps/rsform/views/synthesis.py +++ /dev/null @@ -1,230 +0,0 @@ -''' Endpoints for operations schema. ''' -from typing import cast - -from drf_spectacular.utils import extend_schema -from rest_framework import status -from rest_framework.decorators import api_view -from rest_framework.request import Request -from rest_framework.response import Response - -from ..models.api_RSForm import RSForm -from ..models.Constituenta import Constituenta -from ..models.LibraryItem import LibraryItem -from ..models.Synthesis import InputNode, OperationNode, SynthesisEdge, SynthesisSubstitution -from ..serializers import RSFormSerializer, SynthesisGraphSerializer -from ..serializers.data_access import CstSerializer -from ..serializers.synthesis import ( - InputNodeSerializer, - OperationNodeSerializer, - RunSingleSynthesis, - RunSingleSynthesisResponse, - SynthesisEdgeSerializer, - SynthesisSubstitutionSerializer -) -from ..utils import clone_rsform - - -@extend_schema( - summary='Get synthesis graph', - tags=['Synthesis'], - auth=None -) -@api_view(['GET']) -def get_synthesis_graph(request: Request, pk_item: int): - input_nodes = InputNode.objects.filter(graph_id=pk_item) - operation_nodes = OperationNode.objects.filter(graph_id=pk_item) - edges = SynthesisEdge.objects.filter(graph_id=pk_item) - substitutions = [] - for operation_node in operation_nodes: - substitution_batch = SynthesisSubstitution.objects.filter(operation_id=operation_node.id) - for substitution in substitution_batch: - substitutions.append(substitution) - - synthesis_graph = SynthesisGraphSerializer() - synthesis_graph.create(validated_data={'id': pk_item, 'status': 'Draft'}) - input_nodes = InputNodeSerializer(instance=input_nodes, many=True) - operation_nodes = (OperationNodeSerializer(instance=operation_nodes, many=True)) - edges = SynthesisEdgeSerializer(instance=edges, many=True) - substitutions = SynthesisSubstitutionSerializer(instance=substitutions, many=True) - for substitution in substitutions.data: - substitution['leftCst'] = CstSerializer( - instance=Constituenta.objects.get(id=substitution['leftCst']) - ).data - substitution['rightCst'] = CstSerializer( - instance=Constituenta.objects.get(id=substitution['rightCst']) - ).data - return Response(data={ - 'graph': synthesis_graph.data, - 'input_nodes': input_nodes.data, - 'operation_nodes': operation_nodes.data, - 'edges': edges.data, - 'substitutions': substitutions.data, - }) - - -@extend_schema( - summary='Save synthesis graph', - tags=['Synthesis'], - request=SynthesisGraphSerializer, - responses={status.HTTP_200_OK: RSFormSerializer}, - auth=None -) -@api_view(['POST']) -def save_synthesis_graph(request: Request): - graph_data = request.data.get('graph') - input_nodes_data = request.data.get('input_nodes') - operation_nodes_data = request.data.get('operation_nodes') - edges_data = request.data.get('edges') - substitutions_data = request.data.get('substitutions') - - synthesis_graph_serializer = SynthesisGraphSerializer() - graph = synthesis_graph_serializer.create(validated_data=graph_data) - - InputNode.objects.filter(graph_id=graph).delete() - OperationNode.objects.filter(graph_id=graph).delete() - SynthesisEdge.objects.filter(graph_id=graph).delete() - SynthesisSubstitution.objects.filter(graph_id=graph).delete() - - input_node_serializer = InputNodeSerializer() - for input_node in input_nodes_data: - input_node['graph_id'] = graph - input_node_serializer.create(validated_data_list=input_nodes_data) - - for operation_node in operation_nodes_data: - operation_node['graph_id'] = graph - operation_node['left_parent'] = LibraryItem.objects.get(id=operation_node['left_parent']) - operation_node['right_parent'] = LibraryItem.objects.get(id=operation_node['right_parent']) - operation_node_serializer = OperationNodeSerializer() - operations = operation_node_serializer.create(validated_data_list=operation_nodes_data) - - for edge in edges_data: - edge['graph_id'] = graph - - edge_serializer = SynthesisEdgeSerializer() - edge_serializer.create(validated_data_list=edges_data) - - operations_dict = {operation.id: operation for operation in operations} - for substitution_data in substitutions_data: - substitution_data['operation_id'] = operations_dict[substitution_data['operation_id']] - substitution_data['rightCst'] = Constituenta.objects.get(id=substitution_data['rightCst']['id']) - substitution_data['leftCst'] = Constituenta.objects.get(id=substitution_data['leftCst']['id']) - substitution_data['graph_id'] = graph - - substitution_serializer = SynthesisSubstitutionSerializer() - substitutions = substitution_serializer.create(validated_data_list=substitutions_data) - - return Response(synthesis_graph_serializer.data, status=status.HTTP_201_CREATED) - - -@extend_schema( - summary='Run synthesis graph', - tags=['Synthesis'], - request=RunSingleSynthesis, - responses={status.HTTP_200_OK: RunSingleSynthesisResponse}, - auth=None -) -@api_view(['POST']) -def run_synthesis_graph_view(request: Request): - serializer = RunSingleSynthesis(data=request.data) - serializer.is_valid(raise_exception=True) - for atomic_synthesis in serializer.validated_data: - run_synthesis(atomic_synthesis) - - -@extend_schema( - summary='Run synthesis operation', - tags=['Synthesis'], - request=RunSingleSynthesis, - responses={status.HTTP_200_OK: RunSingleSynthesisResponse}, - auth=None -) -@api_view(['POST']) -def run_synthesis_view(request: Request): - serializer = RunSingleSynthesis( - data=request.data - ) - serializer.is_valid(raise_exception=True) - return run_synthesis(serializer=serializer) - - -def run_synthesis(serializer: RunSingleSynthesis): - operation_id = serializer.data['operationId'] - operation = OperationNode.objects.get(id=operation_id) - - left_schema = RSForm(operation.left_parent) - right_schema = RSForm(operation.right_parent) - substitutions = SynthesisSubstitution.objects.filter(operation_id=operation_id) - - left_schema_copy = clone_rsform(left_schema) - right_constituents = right_schema.item.constituenta_set.filter() - left_schema_copy.insert_copy(right_constituents) - - for substitution in substitutions: - original = cast(Constituenta, substitution.leftCst) - replacement = cast(Constituenta, substitution.rightCst) - left_schema_copy.substitute(original, replacement, (not substitution.deleteRight) and substitution.takeLeftTerm) - - left_schema.restore_order() - return Response( - status=status.HTTP_200_OK, - data=RSFormSerializer(left_schema_copy.item).data - ) - - # right_rsform_copy = clone_rsform(right_schema) - - # serializer.is_valid(raise_exception=True) - - # try: - # mapping = serializer.validated_data['mapping'] - # left_cst_pks = [x.get("left_cst_pk") for x in mapping] - # right_cst_pks = [x.get("right_cst_pk") for x in mapping] - # directions = [x.get("mapping_direction") for x in mapping] - # left_csts = left_schema.item.constituenta_set.filter(pk__in=left_cst_pks) - # right_csts = right_schema.item.constituenta_set.filter(pk__in=right_cst_pks) - - # left_mapping_dict = {left.alias: right.alias for left, right, direction in - # zip(left_csts, right_csts, directions) if - # not direction} - # right_mapping_dict = {right.alias: left.alias for left, right, direction in - # zip(left_csts, right_csts, directions) - # if direction} - - # left_schema_copy.apply_mapping(mapping=left_mapping_dict) - # right_rsform_copy.apply_mapping(mapping=right_mapping_dict) - # left_schema_copy.resolve_all_text() - # right_rsform_copy.resolve_all_text() - # left_schema_copy.item.save() - # right_rsform_copy.item.save() - - # for left, right in zip(left_csts, right_csts): - # # left_rsform_copy.substitute(original=left, substitution=right, transfer_term=False) - # # right_rsform_copy.substitute(original=right, substitution=left, transfer_term=False) - # left_schema_copy.item.save() - # right_rsform_copy.item.save() - - # right_cst_pks = set(right_cst_pks) - # for cst in right_rsform_copy.item.constituenta_set.all(): - # if cst.pk not in right_cst_pks: - # max_idx = left_schema.get_max_index(cst.cst_type) - # left_schema_copy.insert_copy(items=[cst], position=max_idx + 1) - # left_schema_copy.item.save() - - # right_rsform_copy.item.delete() - - # serializer = RSFormParseSerializer(cast(LibraryItem, left_schema_copy.item)) - - # # TODO: remove next line - # left_schema_copy.item.delete() - - # return Response( - # status=status.HTTP_200_OK, - # data=serializer.data - # ) - # # TODO: rework 500 - # except Exception as e: - # left_schema_copy.item.delete() - # right_rsform_copy.item.delete() - # raise e - # return Response( - # status=status.HTTP_500_INTERNAL_SERVER_ERROR - # ) diff --git a/rsconcept/frontend/.vscode/launch.json b/rsconcept/frontend/.vscode/launch.json deleted file mode 100644 index 2ba986f6..00000000 --- a/rsconcept/frontend/.vscode/launch.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:8080", - "webRoot": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/rsconcept/frontend/src/app/Router.tsx b/rsconcept/frontend/src/app/Router.tsx index 6398de00..621bc3ee 100644 --- a/rsconcept/frontend/src/app/Router.tsx +++ b/rsconcept/frontend/src/app/Router.tsx @@ -16,7 +16,6 @@ import UserProfilePage from '@/pages/UserProfilePage'; import ApplicationLayout from './ApplicationLayout'; import { routes } from './urls'; -import SynthesisPage from "@/pages/SynthesisPage"; export const Router = createBrowserRouter([ { @@ -71,10 +70,6 @@ export const Router = createBrowserRouter([ { path: routes.manuals, element: - }, - { - path: routes.synthesis, - element: } ] } diff --git a/rsconcept/frontend/src/app/urls.ts b/rsconcept/frontend/src/app/urls.ts index 733c0bae..d7ff7432 100644 --- a/rsconcept/frontend/src/app/urls.ts +++ b/rsconcept/frontend/src/app/urls.ts @@ -19,8 +19,7 @@ export const routes = { help: 'manuals', rsforms: 'rsforms', oss: 'oss', - icons: 'icons', - synthesis: 'synthesis' + icons: 'icons' }; interface SchemaProps { diff --git a/rsconcept/frontend/src/components/ui/Synthesis/InputNode.tsx b/rsconcept/frontend/src/components/ui/Synthesis/InputNode.tsx deleted file mode 100644 index 94dae743..00000000 --- a/rsconcept/frontend/src/components/ui/Synthesis/InputNode.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { Handle, Position } from '@reactflow/core'; -import { type FC, memo } from 'react'; -import { CiSquareRemove } from 'react-icons/ci'; -import { PiPlugsConnected } from 'react-icons/pi'; - -import MiniButton from '@/components/ui/MiniButton.tsx'; -import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx'; - -interface InputNodeProps { - id: string; - data: { - label: string; - onDelete: (nodeId: string) => void; - }; -} - -const InputNode: FC = ({ id, data }) => { - const controller = useSynthesis(); - - const handleDelete = () => { - data.onDelete(id); - }; - - const handleClick = () => { - controller.selectNode(id); - controller.showSelectInput(); - }; - - return ( - <> - -
- } - title='Удалить' - onClick={handleDelete} - color={'red'} - /> -
- Тип: Ввод -
-
- Схема:{controller.getBind(id) === undefined ? '' : controller.getBind(id)} - - } - title='Привязать схему' - onClick={() => { - handleClick(); - }} - /> - -
-
- - ); -}; - -export default memo(InputNode); diff --git a/rsconcept/frontend/src/components/ui/Synthesis/OperationNode.tsx b/rsconcept/frontend/src/components/ui/Synthesis/OperationNode.tsx deleted file mode 100644 index b3ffc99e..00000000 --- a/rsconcept/frontend/src/components/ui/Synthesis/OperationNode.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { Handle, Position } from '@reactflow/core'; -import { type CSSProperties, type FC, memo } from 'react'; -import { CiSquareRemove } from 'react-icons/ci'; -import { IoGitNetworkSharp } from 'react-icons/io5'; -import { VscDebugStart } from 'react-icons/vsc'; - -import MiniButton from '@/components/ui/MiniButton.tsx'; -import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx'; - -const sourceHandleStyleA: CSSProperties = { left: 50 }; -const sourceHandleStyleB: CSSProperties = { - right: 50, - left: 'auto' -}; - -interface OperationNodeProps { - id: string; - data: { - label: string; - onDelete: (nodeId: string) => void; - }; - xPos: number; - yPos: number; -} - -const OperationNode: FC = ({ id, data, xPos, yPos }) => { - const controller = useSynthesis(); - const { label, onDelete } = data; - - const handleDelete = () => { - onDelete(id); - }; - - const handleSubstitution = () => { - controller.selectNode(id); - controller.showSynthesis(); - }; - - const handleSynthesis = () => { - controller.singleSynthesis(id); - }; - - return ( - <> - -
- } - title='Удалить' - onClick={handleDelete} - color={'red'} - /> -
- Тип: Отождествление -
-
- Схема: - } - title='Синтез' - onClick={() => handleSynthesis()} - /> - } - title='Отождествления' - onClick={() => handleSubstitution()} - /> -
-
- - - - - ); -}; - -export default memo(OperationNode); diff --git a/rsconcept/frontend/src/components/ui/Synthesis/OperationUI.tsx b/rsconcept/frontend/src/components/ui/Synthesis/OperationUI.tsx deleted file mode 100644 index 71eb33ec..00000000 --- a/rsconcept/frontend/src/components/ui/Synthesis/OperationUI.tsx +++ /dev/null @@ -1,21 +0,0 @@ -// Reexporting reaOperation types to wrap in 'use client'. -'use client'; - -import { GraphCanvas as OperationUI } from 'reagraph'; - -export { - type GraphEdge, - type GraphNode, - type GraphCanvasRef, - Sphere, - useSelection, - type CollapseProps -} from 'reagraph'; -export { type LayoutTypes as OperationLayout } from 'reagraph'; - -import { ThreeEvent } from '@react-three/fiber'; - -export type OperationMouseEvent = ThreeEvent; -export type OperationPointerEvent = ThreeEvent; - -export default OperationUI; diff --git a/rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.css b/rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.css deleted file mode 100644 index 72fdcd19..00000000 --- a/rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.css +++ /dev/null @@ -1,18 +0,0 @@ -.Flow { - flex-grow: 1; - font-size: 12px; -} - -.react-flow__node-input { - border: 1px solid #555; - padding: 10px; - width: 150px; - border-radius: 5px; -} - -.react-flow__node-custom { - border: 1px solid #555; - padding: 10px; - width: 250px; - border-radius: 5px; -} diff --git a/rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.tsx b/rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.tsx deleted file mode 100644 index 2d47cf55..00000000 --- a/rsconcept/frontend/src/components/ui/Synthesis/SynthesisFlow.tsx +++ /dev/null @@ -1,43 +0,0 @@ -// this is important! You need to import the styles from the lib to make it work -import '@reactflow/core/dist/style.css'; -import './SynthesisFlow.css'; - -import { NodeTypes, ReactFlow } from '@reactflow/core'; -import { useMemo } from 'react'; - -import { useConceptOptions } from '@/context/OptionsContext.tsx'; -import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx'; - -import InputNode from './InputNode'; -import OperationNode from './OperationNode'; - -const nodeTypes: NodeTypes = { - custom: OperationNode, - input: InputNode -}; - -function Flow() { - const controller = useSynthesis(); - const { calculateHeight } = useConceptOptions(); - const canvasWidth = useMemo(() => { - return 'calc(100vw - 1rem)'; - }, []); - - const canvasHeight = useMemo(() => calculateHeight('1.75rem + 4px'), [calculateHeight]); - return ( -
- -
- ); -} - -export default Flow; diff --git a/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/TabSubstitutions.tsx b/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/TabSubstitutions.tsx index f67f3771..9057a106 100644 --- a/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/TabSubstitutions.tsx +++ b/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/TabSubstitutions.tsx @@ -6,7 +6,6 @@ import { ConstituentaID, IRSForm, ISubstitution } from '@/models/rsform'; import { prefixes } from '@/utils/constants'; import PickSubstitutions from '../../components/select/PickSubstitutions'; -import { ISynthesisSubstitution } from '@/models/oss.ts'; interface TabSubstitutionsProps { receiver?: IRSForm; @@ -17,7 +16,7 @@ interface TabSubstitutionsProps { error?: ErrorData; substitutions: ISubstitution[]; - setSubstitutions: React.Dispatch>; + setSubstitutions: React.Dispatch>; } function TabSubstitutions({ diff --git a/rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSelectInputScheme.tsx b/rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSelectInputScheme.tsx deleted file mode 100644 index 437d76d0..00000000 --- a/rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSelectInputScheme.tsx +++ /dev/null @@ -1,79 +0,0 @@ -'use client'; - -import clsx from 'clsx'; -import { useMemo, useState } from 'react'; -import { TabList, TabPanel, Tabs } from 'react-tabs'; -import { toast } from 'react-toastify'; - -import Modal, { ModalProps } from '@/components/ui/Modal.tsx'; -import TabLabel from '@/components/ui/TabLabel.tsx'; -import SchemaTab from '@/dialogs/DlgInlineSynthesis/SchemaTab.tsx'; -import { LibraryItemID } from '@/models/library.ts'; -import { ISubstitution } from '@/models/rsform.ts'; -import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx'; - -interface DlgCreateSynthesisProps extends Pick { - nodeId: string; -} - -export enum SynthesisTabID { - SCHEMA = 0, - SUBSTITUTIONS = 1 -} - -function DlgSelectInputScheme({ nodeId, hideWindow }: DlgCreateSynthesisProps) { - const controller = useSynthesis(); - - const [activeTab, setActiveTab] = useState(SynthesisTabID.SCHEMA); - const [selected, setSelected] = useState([]); - const [substitutions, setSubstitutions] = useState([]); - const [donorID, setDonorID] = useState(undefined); - - const schemaPanel = useMemo( - () => ( - - - - ), - [donorID] - ); - - function handleSubmit() { - if (donorID !== undefined) { - controller.updateBounds(nodeId, donorID); - } - } - - function validate() { - if (donorID === undefined) { - toast.error('Выберите источник конституент'); - return false; - } - return true; - } - - return ( - - - - - - {schemaPanel} - - - ); -} - -export default DlgSelectInputScheme; diff --git a/rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSynthesis.tsx b/rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSynthesis.tsx deleted file mode 100644 index 7f773882..00000000 --- a/rsconcept/frontend/src/dialogs/DlgOssGraph/DlgSynthesis.tsx +++ /dev/null @@ -1,107 +0,0 @@ -'use client'; - -import clsx from 'clsx'; -import { useCallback, useMemo, useState } from 'react'; -import { TabList, TabPanel, Tabs } from 'react-tabs'; - -import Modal, { ModalProps } from '@/components/ui/Modal.tsx'; -import TabLabel from '@/components/ui/TabLabel.tsx'; -import useRSFormDetails from '@/hooks/useRSFormDetails.ts'; -import { ISynthesisSubstitution } from '@/models/oss.ts'; -import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx'; -import SynthesisSubstitutionsTab from '@/pages/OssPage/SynthesisSubstitutionsTab.tsx'; - -interface DlgCreateSynthesisProps extends Pick { - nodeId: string; - onSynthesis: (data: ISynthesisSubstitution[]) => void; -} - -export enum SynthesisTabID { - SCHEMA = 0, - SUBSTITUTIONS = 1 -} - -function DlgSynthesis({ hideWindow, nodeId, onSynthesis }: DlgCreateSynthesisProps) { - const controller = useSynthesis(); - - const [activeTab, setActiveTab] = useState(SynthesisTabID.SCHEMA); - - const sourceLeft = useRSFormDetails({ - target: controller.getNodeParentsRsform(nodeId)[0] ? String(controller.getNodeParentsRsform(nodeId)[0]) : undefined - }); - - const sourceRight = useRSFormDetails({ - target: controller.getNodeParentsRsform(nodeId)[1] ? String(controller.getNodeParentsRsform(nodeId)[1]) : undefined - }); - - const validated = useMemo(() => controller.getNodeParentsRsform(nodeId).length == 2, [controller, nodeId]); - - function handleSubmit() { - const parents = controller.getNodeParentsRsform(nodeId); - - if (parents.length != 2) { - return; - } - const data: ISynthesisSubstitution[] = controller.substitutions.map(item => ({ - id: null, - operation_id: nodeId, - leftCst: item.leftCst, - rightCst: item.rightCst, - deleteRight: item.deleteRight, - takeLeftTerm: item.takeLeftTerm - })); - controller.setSubstitutions(data); - } - - const schemaPanel = useMemo(() => , []); - - const selectedSubstitutions = useMemo(() => controller.getSubstitution(nodeId), [controller, nodeId]); - - const setSelectedSubstitutions = useCallback( - (newElement: ISynthesisSubstitution[]) => { - controller.updateSubstitution(nodeId, newElement); - }, - [controller, nodeId] - ); - - const substitutesPanel = useMemo( - () => ( - - - - ), - [sourceLeft.schema, sourceRight.schema, selectedSubstitutions, setSelectedSubstitutions] - ); - - return ( - - - - - - - {schemaPanel} - {substitutesPanel} - - - ); -} - -export default DlgSynthesis; diff --git a/rsconcept/frontend/src/models/OssLoader.ts b/rsconcept/frontend/src/models/OssLoader.ts index 23549640..2e3d0a09 100644 --- a/rsconcept/frontend/src/models/OssLoader.ts +++ b/rsconcept/frontend/src/models/OssLoader.ts @@ -17,7 +17,7 @@ export class OssLoader { produceOSS(): IOperationSchema { const result = this.schema as IOperationSchema; - // TODO: put data processing here + result.producedData = [1, 2, 3]; // TODO: put data processing here return result; } } diff --git a/rsconcept/frontend/src/models/oss.ts b/rsconcept/frontend/src/models/oss.ts index 8d763dfe..9c426f8b 100644 --- a/rsconcept/frontend/src/models/oss.ts +++ b/rsconcept/frontend/src/models/oss.ts @@ -2,68 +2,18 @@ * Module: Schema of Synthesis Operations. */ -import { ISubstitution } from '@/models/rsform.ts'; - import { ILibraryItemData } from './library'; -import { UserID } from './user'; /** * Represents backend data for Schema of Synthesis Operations. */ export interface IOperationSchemaData extends ILibraryItemData { - input_nodes: IInputNode[]; - operation_nodes: ISynthesisNode[]; - edges: ISynthesisEdge[]; - substitutions: ISynthesisSubstitution[]; - graph: ISynthesisGraph; -} - -interface ISynthesisGraph { - id: number; - status: string; -} - -interface IInputNode { - id: number | null; - graph_id: number; - vertical_coordinate: number; - horizontal_coordinate: number; - rsform_id: number; -} - -interface ISynthesisNode extends IInputNode { - id: number | null; - name: string; - status: string; -} - -interface ISynthesisEdge { - id: number | null; - decoded_id: string; - source_handle: string; - graph_id: number; - node_from: string; - node_to: string; -} - -export interface ISynthesisSubstitution extends ISubstitution { - id: number | null; - graph_id: number; - operation_id: string; -} - -export interface IRunSynthesis { - operationId: number; -} - -export interface IRunSynthesisResponse { - rsformId: number; + additional_data?: number[]; } /** * Represents Schema of Synthesis Operations. */ export interface IOperationSchema extends IOperationSchemaData { - subscribers: UserID[]; - editors: UserID[]; + producedData: number[]; // TODO: modify this to store calculated state on load } diff --git a/rsconcept/frontend/src/pages/OssPage/SynthesisContext.tsx b/rsconcept/frontend/src/pages/OssPage/SynthesisContext.tsx deleted file mode 100644 index 1ca5e0db..00000000 --- a/rsconcept/frontend/src/pages/OssPage/SynthesisContext.tsx +++ /dev/null @@ -1,350 +0,0 @@ -import { - addEdge, - type Connection, - Edge, - EdgeChange, - Node, - NodeChange, - useEdgesState, - useNodesState -} from '@reactflow/core'; -import { createContext, useCallback, useContext, useEffect, useState } from 'react'; -import { toast } from 'react-toastify'; - -import { postSynthesisGraph, runSingleSynthesis } from '@/app/backendAPI.ts'; -import { useOSS } from '@/context/OssContext.tsx'; -import DlgSelectInputScheme from '@/dialogs/DlgOssGraph/DlgSelectInputScheme.tsx'; -import DlgSynthesis from '@/dialogs/DlgOssGraph/DlgSynthesis.tsx'; -import { IOperationSchemaData, IRunSynthesis, ISynthesisSubstitution } from '@/models/oss.ts'; -import { ISubstitution } from '@/models/rsform.ts'; - -interface ISynthesisContext { - synthesisSchemaID: string; - singleSynthesis: (nodeId: number) => void; - showSynthesis: () => void; - showSelectInput: () => void; - selectNode: (nodeId: string) => void; - getSelectedNode: () => string | undefined; - - addLibrarySchema: () => void; - addSynthesisOperation: () => void; - removeItem: () => void; - runSynthesisLayer: () => void; - - getNodes: () => Node[]; - getEdges: () => Edge[]; - - setNodes: (nodes: Node[]) => void; - setEdges: (nodes: Edge[]) => void; - - onNodesChange: (changes: NodeChange[]) => void; - onEdgesChange: (changes: EdgeChange[]) => void; - onNodesDelete: (nodes: Node[]) => void; - onConnect: (connection: Connection) => void; - addBind: () => void; - - updateBounds: (nodeId: string, newRsform: number) => void; - getBind: (nodeId: string) => number | undefined; - getNodeParentsRsform: (nodeId: string) => number[]; - saveGraph: () => void; - - substitutions: ISynthesisSubstitution[]; - setSubstitutions: React.Dispatch>; - getSubstitution: (id: string) => ISynthesisSubstitution[]; - updateSubstitution: (id: string, substitution: ISubstitution[]) => void; -} - -interface IBoundMap { - nodeId: string; - rsformId: number; -} - -const SynthesisContext = createContext(null); - -interface SynthesisStateProps { - synthesisSchemaID: string; - children: React.ReactNode; -} - -export const useSynthesis = () => { - const context = useContext(SynthesisContext); - if (context === null) { - throw new Error('useSynthesis has to be used within '); - } - return context; -}; - -export const SynthesisState = ({ synthesisSchemaID, children }: SynthesisStateProps) => { - const [showSynthesisModal, setShowSynthesisModal] = useState(false); - const [showSelectInputModal, setShowSelectInputModal] = useState(false); - const [selectedNode, setSelectedNode] = useState(null); - - const [nodes, setNodes, onNodesChange] = useNodesState([]); - const [edges, setEdges, onEdgesChange] = useEdgesState([]); - - const [bounds, setBounds] = useState([]); - // const [substitutionBounds, setSubstitutionBounds] = useState([]); - const [substitutions, setSubstitutions] = useState([]); - - const ossSchema = useOSS(); - - const getSubstitution = (operation_id: string): ISynthesisSubstitution[] => { - return substitutions.filter(substitution => substitution.operation_id === operation_id); - }; - - const updateSubstitution = (operation_id: string, newElements: ISubstitution[]) => { - // TODO: Call backend API and reload OSS or use returned data for - console.log(operation_id); - console.log(newElements); - toast('Saving substitution table not supported'); - return; - - // if (!Array.isArray(newElements)) { - // console.error('newElements should be an array.'); - // return; - // } - - // setSubstitutions(prevSubstitutions => { - // // Обновление существующих элементов - // const updatedSubstitutions = prevSubstitutions.map(substitution => { - // const newElement = newElements.find(el => el.id === substitution.id); - // if (newElement) { - // // Обновляем только соответствующие элементы - // return { ...substitution, ...newElement, operation_id: substitution.operation_id }; - // } - // return substitution; - // }); - - // // Добавление новых элементов с присвоением operation_id - // const newSubstitutions = newElements - // .filter(newElement => !prevSubstitutions.some(sub => sub.id === newElement.id)) - // .map(newElement => ({ ...newElement, operation_id })); - - // return [...updatedSubstitutions, ...newSubstitutions]; - // }); - }; - - const extractEdgeId = (edgeId: string) => { - const matches = edgeId.match(/\d+/g); - const combined = matches ? matches.join('') : ''; - return Number(combined); - }; - - const getBind = useCallback( - (nodeId: string) => { - const bound = bounds.find(item => item.nodeId == nodeId); - return bound ? bound.rsformId : undefined; - }, - [bounds] - ); - - const getBounds = useCallback( - (nodeId: string[]) => { - const parentBounds = bounds.filter(item => item.nodeId in nodeId); - return parentBounds.map(item => item.rsformId); - }, - [bounds] - ); - - const getNodeParentsRsform = useCallback( - (nodeId: string) => { - const parentEdges = edges.filter(edge => edge.source === nodeId); - const parentNodeIds = parentEdges.map(edge => edge.target); - return getBounds(parentNodeIds); - }, - [getBounds, edges] - ); - - const saveGraph = useCallback(() => { - if (!ossSchema.schema) { - return; - } - const data: IOperationSchemaData = { - graph: { - id: ossSchema.schema?.id, - status: 'Draft' - }, - input_nodes: nodes - .filter(node => node.type == 'input') - .map(item => ({ - id: item.id, - vertical_coordinate: item.position.y, - horizontal_coordinate: item.position.x, - rsform_id: getBind(item.id) - })), - operation_nodes: nodes - .filter(node => node.type == 'custom') - .map(item => ({ - id: item.id, - vertical_coordinate: item.position.y, - horizontal_coordinate: item.position.x, - left_parent: getNodeParentsRsform(item.id)[0], - right_parent: getNodeParentsRsform(item.id)[1], - rsform_id: getBind(item.id), - name: 'name', - status: 'status' - })), - edges: edges.map(item => ({ - id: extractEdgeId(item.id), - decoded_id: item.id, - source_handle: item.sourceHandle, - node_from: item.source, - node_to: item.target - })), - substitutions: substitutions - }; - - postSynthesisGraph({ - data: data - }); - }, [ossSchema, edges, nodes, getBind, substitutions, getNodeParentsRsform]); - - useEffect(() => { - if (ossSchema.schema !== undefined) { - const initialNodes = [ - ...ossSchema.schema.input_nodes.map(node => ({ - id: node.id?.toString() || 'null', - data: { label: '123' }, - position: { x: node.horizontal_coordinate, y: node.vertical_coordinate }, - type: 'input' - })), - ...ossSchema.schema.operation_nodes.map(node => ({ - id: node.id?.toString() || 'null', - data: { label: '123' }, - position: { x: node.horizontal_coordinate, y: node.vertical_coordinate }, - type: 'custom' - })) - ]; - - const initialEdges = ossSchema.schema.edges.map(edge => ({ - id: edge.decoded_id, - source: String(edge.node_from), - sourceHandle: edge.source_handle, - target: String(edge.node_to) - })); - // const initialEdges = [ - // { id: 'reactflow__edge-2a-0', source: '2', target: '0' }, - // { id: 'reactflow__edge-2b-1', sourceHandle: 'b', source: '2', target: '1' } - // ]; - - setNodes(initialNodes); - setEdges(initialEdges); - setSubstitutions(ossSchema.schema.substitutions); - [...ossSchema.schema.input_nodes, ...ossSchema.schema.operation_nodes].forEach(node => { - const nodeId = node.id?.toString() || 'null'; - const rsformId = node.rsform_id; // Предполагаем, что rsform_id есть в данных нод - updateBounds(nodeId, rsformId); - }); - } - }, [ossSchema, setEdges, setNodes]); - - const updateBounds = (nodeId: string, newRsform: number) => { - setBounds(prevItems => { - const existingItem = prevItems.find(item => item.nodeId === nodeId); - - if (existingItem) { - return prevItems.map(item => (item.nodeId === nodeId ? { ...item, rsformId: newRsform } : item)); - } else { - return [...prevItems, { nodeId: nodeId, rsformId: newRsform }]; - } - }); - }; - - const onConnect = useCallback((params: Connection | Edge) => setEdges(eds => addEdge(params, eds)), [setEdges]); - - const onNodeDelete = useCallback( - (nodeId: string) => { - setNodes(nodes => nodes.filter(node => node.id !== nodeId)); - setEdges(edges => edges.filter(edge => edge.source !== nodeId && edge.target !== nodeId)); - }, - [setEdges, setNodes] - ); - - const singleSynthesis = useCallback((operationId: number) => { - const data: IRunSynthesis = { - operationId: Number(operationId) - }; - runSingleSynthesis({ data: data }); - }, []); - - const newLibrarySchema = { - id: String(nodes.length > 0 ? 1 + Math.max(...nodes.map(item => Number(item.id))) : 0), - type: 'input', - position: { x: 250, y: 5 }, - data: { - label: 'Node 1', - onDelete: onNodeDelete - } - }; - - const newOperation = { - id: String(nodes.length > 0 ? 1 + Math.max(...nodes.map(item => Number(item.id))) : 0), - type: 'custom', - position: { x: 350, y: 20 }, - data: { - label: 'Node 1', - onDelete: onNodeDelete - } - }; - - const selectNode = useCallback( - (nodeId: string) => { - for (const node of nodes) { - if (node.id === nodeId) { - setSelectedNode(node); - return; - } - } - }, - [nodes] - ); - return ( - setShowSynthesisModal(true), - showSelectInput: () => setShowSelectInputModal(true), - selectNode: nodeId => selectNode(nodeId), - getSelectedNode: () => selectedNode?.id, - addLibrarySchema: () => { - setNodes([...nodes, newLibrarySchema]); - }, - addSynthesisOperation: () => { - setNodes([...nodes, newOperation]); - }, - setNodes: (nodes: Node[]) => { - setNodes(nodes); - }, - setEdges: (edges: Edge[]) => { - setEdges(edges); - }, - getNodes: () => nodes, - getEdges: () => edges, - onNodesChange: onNodesChange, - onEdgesChange: onEdgesChange, - onConnect: onConnect, - updateBounds: updateBounds, - getNodeParentsRsform: getNodeParentsRsform, - getBind: getBind, - saveGraph: saveGraph, - setSubstitutions: setSubstitutions, - substitutions: substitutions, - updateSubstitution: updateSubstitution, - getSubstitution: getSubstitution - }} - > - {showSynthesisModal ? ( - setShowSynthesisModal(false)} - nodeId={selectedNode!.id} - onSynthesis={() => singleSynthesis} - /> - ) : null} - {showSelectInputModal ? ( - setShowSelectInputModal(false)} /> - ) : null} - {children} - - ); -}; diff --git a/rsconcept/frontend/src/pages/OssPage/SynthesisOperation.tsx b/rsconcept/frontend/src/pages/OssPage/SynthesisOperation.tsx deleted file mode 100644 index b9a8b9d3..00000000 --- a/rsconcept/frontend/src/pages/OssPage/SynthesisOperation.tsx +++ /dev/null @@ -1,5 +0,0 @@ -function SynthesisOperation() { - return
; -} - -export default SynthesisOperation; diff --git a/rsconcept/frontend/src/pages/OssPage/SynthesisSubstitutionsTab.tsx b/rsconcept/frontend/src/pages/OssPage/SynthesisSubstitutionsTab.tsx deleted file mode 100644 index eddf2c3c..00000000 --- a/rsconcept/frontend/src/pages/OssPage/SynthesisSubstitutionsTab.tsx +++ /dev/null @@ -1,41 +0,0 @@ -'use client'; - -import { ErrorData } from '@/components/info/InfoError.tsx'; -import DataLoader from '@/components/wrap/DataLoader.tsx'; -import { IRSForm, ISubstitution } from '@/models/rsform.ts'; -import { prefixes } from '@/utils/constants.ts'; - -import PickSubstitutions from '../../components/select/PickSubstitutions'; - -interface SynthesisSubstitutionsTabProps { - receiver?: IRSForm; - source?: IRSForm; - - error?: ErrorData; - - substitutions: ISubstitution[]; - setSubstitutions: React.Dispatch>; -} - -function SynthesisSubstitutionsTab({ - source, - receiver, - error, - substitutions, - setSubstitutions -}: SynthesisSubstitutionsTabProps) { - return ( - - - - ); -} - -export default SynthesisSubstitutionsTab; diff --git a/rsconcept/frontend/src/pages/OssPage/SynthesisToolbar.tsx b/rsconcept/frontend/src/pages/OssPage/SynthesisToolbar.tsx deleted file mode 100644 index 3ebb530f..00000000 --- a/rsconcept/frontend/src/pages/OssPage/SynthesisToolbar.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx'; -import Button from '@/components/ui/Button.tsx'; -import { IoMdAdd, IoMdRemove } from 'react-icons/io'; -import { MdCallMerge } from 'react-icons/md'; -import Overlay from '@/components/ui/Overlay.tsx'; -import { MdLibraryAdd } from 'react-icons/md'; - -import { VscRunAll, VscSave } from 'react-icons/vsc'; - -function SynthesisToolbar() { - const controller = useSynthesis(); - - return ( - -