Start fixing type errors and basic linting
This commit is contained in:
parent
67bb69eccc
commit
000bfad0f8
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -120,6 +120,7 @@
|
||||||
"pymorphy",
|
"pymorphy",
|
||||||
"Quantor",
|
"Quantor",
|
||||||
"razdel",
|
"razdel",
|
||||||
|
"reactflow",
|
||||||
"reagraph",
|
"reagraph",
|
||||||
"redef",
|
"redef",
|
||||||
"REDOC",
|
"REDOC",
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
|
''' Models: Synthesis. '''
|
||||||
|
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
CASCADE, SET_NULL, ForeignKey, Model, PositiveIntegerField, QuerySet,
|
CASCADE,
|
||||||
TextChoices, TextField, BooleanField, CharField, DateTimeField, JSONField, IntegerField, AutoField
|
SET_NULL,
|
||||||
|
BooleanField,
|
||||||
|
CharField,
|
||||||
|
ForeignKey,
|
||||||
|
IntegerField,
|
||||||
|
Model,
|
||||||
|
TextChoices
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OperationStatus(TextChoices):
|
class OperationStatus(TextChoices):
|
||||||
|
''' Operation status enumeration. '''
|
||||||
DRAFT = 'Draft',
|
DRAFT = 'Draft',
|
||||||
COMPLETED = 'Completed',
|
COMPLETED = 'Completed',
|
||||||
WARNING = 'Warning',
|
WARNING = 'Warning',
|
||||||
|
@ -12,6 +21,7 @@ class OperationStatus(TextChoices):
|
||||||
|
|
||||||
|
|
||||||
class GraphStatus(TextChoices):
|
class GraphStatus(TextChoices):
|
||||||
|
''' Graph status enumeration. '''
|
||||||
DRAFT = 'Draft',
|
DRAFT = 'Draft',
|
||||||
COMPLETED = 'Completed',
|
COMPLETED = 'Completed',
|
||||||
WARNING = 'Warning',
|
WARNING = 'Warning',
|
||||||
|
|
|
@ -405,11 +405,11 @@ class InlineSynthesisSerializer(serializers.Serializer):
|
||||||
user = cast(User, self.context['user'])
|
user = cast(User, self.context['user'])
|
||||||
schema_in = cast(LibraryItem, attrs['source'])
|
schema_in = cast(LibraryItem, attrs['source'])
|
||||||
schema_out = cast(LibraryItem, attrs['receiver'])
|
schema_out = cast(LibraryItem, attrs['receiver'])
|
||||||
#if user.is_anonymous or (schema_out.owner != user and not user.is_staff):
|
if user.is_anonymous or (schema_out.owner != user and not user.is_staff):
|
||||||
# raise PermissionDenied({
|
raise PermissionDenied({
|
||||||
# 'message': msg.schemaNotOwned(),
|
'message': msg.schemaNotOwned(),
|
||||||
# 'object_id': schema_in.id
|
'object_id': schema_in.id
|
||||||
# })
|
})
|
||||||
constituents = cast(list[Constituenta], attrs['items'])
|
constituents = cast(list[Constituenta], attrs['items'])
|
||||||
for cst in constituents:
|
for cst in constituents:
|
||||||
if cst.schema != schema_in:
|
if cst.schema != schema_in:
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
from rest_framework import serializers
|
''' Synthesis serializers. '''
|
||||||
from .data_access import CstSubstituteSerializerBase
|
|
||||||
from rest_framework.serializers import PrimaryKeyRelatedField as PKField
|
|
||||||
|
|
||||||
from ..models import Constituenta, LibraryItem
|
from rest_framework import serializers
|
||||||
from ..models.Synthesis import SynthesisGraph, SynthesisEdge, InputNode, OperationNode, SynthesisSubstitution
|
|
||||||
|
from ..models.Synthesis import (
|
||||||
|
InputNode,
|
||||||
|
OperationNode,
|
||||||
|
SynthesisEdge,
|
||||||
|
SynthesisGraph,
|
||||||
|
SynthesisSubstitution
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SynthesisGraphSerializer(serializers.ModelSerializer):
|
class SynthesisGraphSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
@ -31,7 +31,7 @@ urlpatterns = [
|
||||||
path('cctext/generate-lexeme', views.generate_lexeme),
|
path('cctext/generate-lexeme', views.generate_lexeme),
|
||||||
path('cctext/parse', views.parse_text),
|
path('cctext/parse', views.parse_text),
|
||||||
path('synthesis/run_single', views.run_synthesis_view),
|
path('synthesis/run_single', views.run_synthesis_view),
|
||||||
path('synthesis/run_all', views.run_sythesis_graph_view),
|
path('synthesis/run_all', views.run_synthesis_graph_view),
|
||||||
path('synthesis/save', views.save_synthesis_graph),
|
path('synthesis/save', views.save_synthesis_graph),
|
||||||
path('synthesis/<int:pk_item>', views.get_synthesis_graph),
|
path('synthesis/<int:pk_item>', views.get_synthesis_graph),
|
||||||
path('', include(library_router.urls)),
|
path('', include(library_router.urls)),
|
||||||
|
|
|
@ -76,6 +76,6 @@ def clone_rsform(rsform):
|
||||||
rsform_copy.item.comment = "Temporary cloned rsform"
|
rsform_copy.item.comment = "Temporary cloned rsform"
|
||||||
rsform_copy.item.save()
|
rsform_copy.item.save()
|
||||||
|
|
||||||
rsform_copy.insert_copy(items=[cst for cst in rsform.item.constituenta_set.all()], position=1)
|
rsform_copy.insert_copy(items=rsform.item.constituenta_set.all(), position=1)
|
||||||
rsform_copy.item.save()
|
rsform_copy.item.save()
|
||||||
return rsform_copy
|
return rsform_copy
|
||||||
|
|
|
@ -5,11 +5,10 @@ from .library import LibraryActiveView, LibraryAdminView, LibraryTemplatesView,
|
||||||
from .operations import inline_synthesis
|
from .operations import inline_synthesis
|
||||||
from .rsforms import RSFormViewSet, TrsImportView, create_rsform
|
from .rsforms import RSFormViewSet, TrsImportView, create_rsform
|
||||||
from .rslang import convert_to_ascii, convert_to_math, parse_expression
|
from .rslang import convert_to_ascii, convert_to_math, parse_expression
|
||||||
from .versions import VersionViewset, create_version, export_file, retrieve_version
|
|
||||||
|
|
||||||
from .synthesis import (
|
from .synthesis import (
|
||||||
run_synthesis_view,
|
|
||||||
run_sythesis_graph_view,
|
|
||||||
save_synthesis_graph,
|
|
||||||
get_synthesis_graph,
|
get_synthesis_graph,
|
||||||
|
run_synthesis_graph_view,
|
||||||
|
run_synthesis_view,
|
||||||
|
save_synthesis_graph
|
||||||
)
|
)
|
||||||
|
from .versions import VersionViewset, create_version, export_file, retrieve_version
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
import copy
|
''' Endpoints for operations schema. '''
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
from drf_spectacular.utils import extend_schema
|
from drf_spectacular.utils import extend_schema
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.decorators import api_view
|
from rest_framework.decorators import api_view
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from django.db.models import Q
|
|
||||||
from rest_framework.views import APIView
|
|
||||||
|
|
||||||
|
from ..models.api_RSForm import RSForm
|
||||||
from ..models.Constituenta import Constituenta
|
from ..models.Constituenta import Constituenta
|
||||||
from ..models.LibraryItem import LibraryItem
|
from ..models.LibraryItem import LibraryItem
|
||||||
from ..models.api_RSForm import RSForm
|
from ..models.Synthesis import InputNode, OperationNode, SynthesisEdge, SynthesisSubstitution
|
||||||
from ..models.Synthesis import SynthesisGraph, InputNode, OperationNode, SynthesisSubstitution, SynthesisEdge
|
from ..serializers import RSFormSerializer, SynthesisGraphSerializer
|
||||||
from ..serializers import RSFormSerializer, SynthesisGraphSerializer, InlineSynthesisSerializer
|
from ..serializers.data_access import CstSerializer
|
||||||
from typing import cast
|
from ..serializers.synthesis import (
|
||||||
from django.contrib.auth.models import User
|
InputNodeSerializer,
|
||||||
|
OperationNodeSerializer,
|
||||||
from ..serializers.data_access import CstBaseSerializer, CstSerializer
|
RunSingleSynthesis,
|
||||||
from ..serializers.synthesis import OperationNodeSerializer, InputNodeSerializer, \
|
RunSingleSynthesisResponse,
|
||||||
SynthesisSubstitutionSerializer, SynthesisEdgeSerializer, RunSingleSynthesis, RunSingleSynthesisResponse
|
SynthesisEdgeSerializer,
|
||||||
|
SynthesisSubstitutionSerializer
|
||||||
|
)
|
||||||
from ..utils import clone_rsform
|
from ..utils import clone_rsform
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,8 +47,12 @@ def get_synthesis_graph(request: Request, pk_item: int):
|
||||||
edges = SynthesisEdgeSerializer(instance=edges, many=True)
|
edges = SynthesisEdgeSerializer(instance=edges, many=True)
|
||||||
substitutions = SynthesisSubstitutionSerializer(instance=substitutions, many=True)
|
substitutions = SynthesisSubstitutionSerializer(instance=substitutions, many=True)
|
||||||
for substitution in substitutions.data:
|
for substitution in substitutions.data:
|
||||||
substitution['leftCst'] = CstSerializer(instance=Constituenta.objects.get(id=substitution['leftCst'])).data
|
substitution['leftCst'] = CstSerializer(
|
||||||
substitution['rightCst'] = CstSerializer(instance=Constituenta.objects.get(id=substitution['rightCst'])).data
|
instance=Constituenta.objects.get(id=substitution['leftCst'])
|
||||||
|
).data
|
||||||
|
substitution['rightCst'] = CstSerializer(
|
||||||
|
instance=Constituenta.objects.get(id=substitution['rightCst'])
|
||||||
|
).data
|
||||||
return Response(data={
|
return Response(data={
|
||||||
'graph': synthesis_graph.data,
|
'graph': synthesis_graph.data,
|
||||||
'input_nodes': input_nodes.data,
|
'input_nodes': input_nodes.data,
|
||||||
|
@ -118,7 +124,7 @@ def save_synthesis_graph(request: Request):
|
||||||
auth=None
|
auth=None
|
||||||
)
|
)
|
||||||
@api_view(['POST'])
|
@api_view(['POST'])
|
||||||
def run_sythesis_graph_view(request: Request):
|
def run_synthesis_graph_view(request: Request):
|
||||||
serializer = RunSingleSynthesis(data=request.data)
|
serializer = RunSingleSynthesis(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
for atomic_synthesis in serializer.validated_data:
|
for atomic_synthesis in serializer.validated_data:
|
||||||
|
@ -164,61 +170,61 @@ def run_synthesis(serializer: RunSingleSynthesis):
|
||||||
data=RSFormSerializer(left_schema_copy.item).data
|
data=RSFormSerializer(left_schema_copy.item).data
|
||||||
)
|
)
|
||||||
|
|
||||||
right_rsform_copy = clone_rsform(right_schema)
|
# right_rsform_copy = clone_rsform(right_schema)
|
||||||
|
|
||||||
serializer.is_valid(raise_exception=True)
|
# serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
mapping = serializer.validated_data['mapping']
|
# mapping = serializer.validated_data['mapping']
|
||||||
left_cst_pks = [x.get("left_cst_pk") for x in 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]
|
# right_cst_pks = [x.get("right_cst_pk") for x in mapping]
|
||||||
directions = [x.get("mapping_direction") 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)
|
# 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)
|
# 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
|
# left_mapping_dict = {left.alias: right.alias for left, right, direction in
|
||||||
zip(left_csts, right_csts, directions) if
|
# zip(left_csts, right_csts, directions) if
|
||||||
not direction}
|
# not direction}
|
||||||
right_mapping_dict = {right.alias: left.alias for left, right, direction in
|
# right_mapping_dict = {right.alias: left.alias for left, right, direction in
|
||||||
zip(left_csts, right_csts, directions)
|
# zip(left_csts, right_csts, directions)
|
||||||
if direction}
|
# if direction}
|
||||||
|
|
||||||
left_schema_copy.apply_mapping(mapping=left_mapping_dict)
|
# left_schema_copy.apply_mapping(mapping=left_mapping_dict)
|
||||||
right_rsform_copy.apply_mapping(mapping=right_mapping_dict)
|
# right_rsform_copy.apply_mapping(mapping=right_mapping_dict)
|
||||||
left_schema_copy.resolve_all_text()
|
# left_schema_copy.resolve_all_text()
|
||||||
right_rsform_copy.resolve_all_text()
|
# right_rsform_copy.resolve_all_text()
|
||||||
left_schema_copy.item.save()
|
# left_schema_copy.item.save()
|
||||||
right_rsform_copy.item.save()
|
# right_rsform_copy.item.save()
|
||||||
|
|
||||||
for left, right in zip(left_csts, right_csts):
|
# for left, right in zip(left_csts, right_csts):
|
||||||
# left_rsform_copy.substitute(original=left, substitution=right, transfer_term=False)
|
# # left_rsform_copy.substitute(original=left, substitution=right, transfer_term=False)
|
||||||
# right_rsform_copy.substitute(original=right, substitution=left, transfer_term=False)
|
# # right_rsform_copy.substitute(original=right, substitution=left, transfer_term=False)
|
||||||
left_schema_copy.item.save()
|
# left_schema_copy.item.save()
|
||||||
right_rsform_copy.item.save()
|
# right_rsform_copy.item.save()
|
||||||
|
|
||||||
right_cst_pks = set(right_cst_pks)
|
# right_cst_pks = set(right_cst_pks)
|
||||||
for cst in right_rsform_copy.item.constituenta_set.all():
|
# for cst in right_rsform_copy.item.constituenta_set.all():
|
||||||
if cst.pk not in right_cst_pks:
|
# if cst.pk not in right_cst_pks:
|
||||||
max_idx = left_schema.get_max_index(cst.cst_type)
|
# max_idx = left_schema.get_max_index(cst.cst_type)
|
||||||
left_schema_copy.insert_copy(items=[cst], position=max_idx + 1)
|
# left_schema_copy.insert_copy(items=[cst], position=max_idx + 1)
|
||||||
left_schema_copy.item.save()
|
# left_schema_copy.item.save()
|
||||||
|
|
||||||
right_rsform_copy.item.delete()
|
# right_rsform_copy.item.delete()
|
||||||
|
|
||||||
serializer = RSFormParseSerializer(cast(LibraryItem, left_schema_copy.item))
|
# serializer = RSFormParseSerializer(cast(LibraryItem, left_schema_copy.item))
|
||||||
|
|
||||||
# TODO: remove next line
|
# # TODO: remove next line
|
||||||
left_schema_copy.item.delete()
|
# left_schema_copy.item.delete()
|
||||||
|
|
||||||
return Response(
|
# return Response(
|
||||||
status=status.HTTP_200_OK,
|
# status=status.HTTP_200_OK,
|
||||||
data=serializer.data
|
# data=serializer.data
|
||||||
)
|
# )
|
||||||
# TODO: rework 500
|
# # TODO: rework 500
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
left_schema_copy.item.delete()
|
# left_schema_copy.item.delete()
|
||||||
right_rsform_copy.item.delete()
|
# right_rsform_copy.item.delete()
|
||||||
raise e
|
# raise e
|
||||||
return Response(
|
# return Response(
|
||||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
# status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||||
)
|
# )
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
tzdata
|
tzdata
|
||||||
django
|
Django
|
||||||
djangorestframework
|
djangorestframework
|
||||||
django-cors-headers
|
django-cors-headers
|
||||||
django-filter
|
django-filter
|
||||||
drf-spectacular
|
drf-spectacular
|
||||||
drf-spectacular[sidecar]
|
drf-spectacular-sidecar
|
||||||
coreapi
|
coreapi
|
||||||
|
django-rest-passwordreset
|
||||||
cctext
|
cctext
|
||||||
pyconcept
|
pyconcept
|
||||||
|
|
||||||
|
psycopg2-binary
|
||||||
|
gunicorn
|
||||||
|
|
||||||
|
djangorestframework-stubs[compatible-mypy]
|
||||||
|
|
||||||
mypy
|
mypy
|
||||||
pylint
|
pylint
|
||||||
coverage
|
coverage
|
||||||
djangorestframework-stubs[compatible-mypy]
|
|
||||||
django-rest-passwordreset
|
|
||||||
|
|
||||||
psycopg2-binary
|
|
||||||
gunicorn
|
|
|
@ -7,17 +7,10 @@ import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { type ErrorData } from '@/components/info/InfoError';
|
import { type ErrorData } from '@/components/info/InfoError';
|
||||||
import { ILexemeData, IResolutionData, ITextRequest, ITextResult, IWordFormPlain } from '@/models/language';
|
import { ILexemeData, IResolutionData, ITextRequest, ITextResult, IWordFormPlain } from '@/models/language';
|
||||||
import {
|
import { ILibraryItem, ILibraryUpdateData, ITargetAccessPolicy, ITargetLocation, IVersionData } from '@/models/library';
|
||||||
AccessPolicy,
|
|
||||||
ILibraryItem,
|
|
||||||
ILibraryUpdateData,
|
|
||||||
ITargetAccessPolicy,
|
|
||||||
ITargetLocation,
|
|
||||||
IVersionData,
|
|
||||||
LibraryItemType
|
|
||||||
} from '@/models/library';
|
|
||||||
import { ILibraryCreateData } from '@/models/library';
|
import { ILibraryCreateData } from '@/models/library';
|
||||||
import { IOperationSchemaData, IRunSynthesis, IRunSynthesisResponse } from '@/models/oss';
|
import { IOperationSchemaData, IRunSynthesis, IRunSynthesisResponse } from '@/models/oss';
|
||||||
|
import { ISynthesisGraphData } from '@/models/oss.ts';
|
||||||
import {
|
import {
|
||||||
IConstituentaList,
|
IConstituentaList,
|
||||||
IConstituentaMeta,
|
IConstituentaMeta,
|
||||||
|
@ -51,7 +44,6 @@ import {
|
||||||
IUserUpdatePassword
|
IUserUpdatePassword
|
||||||
} from '@/models/user';
|
} from '@/models/user';
|
||||||
import { buildConstants } from '@/utils/buildConstants';
|
import { buildConstants } from '@/utils/buildConstants';
|
||||||
import { ISynthesisGraphData } from '@/models/oss.ts';
|
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
xsrfCookieName: 'csrftoken',
|
xsrfCookieName: 'csrftoken',
|
||||||
|
@ -96,8 +88,7 @@ export interface FrontExchange<RequestData, ResponseData> extends IFrontRequest<
|
||||||
onSuccess: DataCallback<ResponseData>;
|
onSuccess: DataCallback<ResponseData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FrontAction extends IFrontRequest<undefined, undefined> {
|
export interface FrontAction extends IFrontRequest<undefined, undefined> {}
|
||||||
}
|
|
||||||
|
|
||||||
interface IAxiosRequest<RequestData, ResponseData> {
|
interface IAxiosRequest<RequestData, ResponseData> {
|
||||||
endpoint: string;
|
endpoint: string;
|
||||||
|
@ -522,10 +513,10 @@ function AxiosGet<ResponseData>({ endpoint, request, options }: IAxiosRequest<un
|
||||||
}
|
}
|
||||||
|
|
||||||
function AxiosPost<RequestData, ResponseData>({
|
function AxiosPost<RequestData, ResponseData>({
|
||||||
endpoint,
|
endpoint,
|
||||||
request,
|
request,
|
||||||
options
|
options
|
||||||
}: IAxiosRequest<RequestData, ResponseData>) {
|
}: IAxiosRequest<RequestData, ResponseData>) {
|
||||||
if (request.setLoading) request.setLoading(true);
|
if (request.setLoading) request.setLoading(true);
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.post<ResponseData>(endpoint, request.data, options)
|
.post<ResponseData>(endpoint, request.data, options)
|
||||||
|
@ -541,10 +532,10 @@ function AxiosPost<RequestData, ResponseData>({
|
||||||
}
|
}
|
||||||
|
|
||||||
function AxiosDelete<RequestData, ResponseData>({
|
function AxiosDelete<RequestData, ResponseData>({
|
||||||
endpoint,
|
endpoint,
|
||||||
request,
|
request,
|
||||||
options
|
options
|
||||||
}: IAxiosRequest<RequestData, ResponseData>) {
|
}: IAxiosRequest<RequestData, ResponseData>) {
|
||||||
if (request.setLoading) request.setLoading(true);
|
if (request.setLoading) request.setLoading(true);
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.delete<ResponseData>(endpoint, options)
|
.delete<ResponseData>(endpoint, options)
|
||||||
|
@ -560,10 +551,10 @@ function AxiosDelete<RequestData, ResponseData>({
|
||||||
}
|
}
|
||||||
|
|
||||||
function AxiosPatch<RequestData, ResponseData>({
|
function AxiosPatch<RequestData, ResponseData>({
|
||||||
endpoint,
|
endpoint,
|
||||||
request,
|
request,
|
||||||
options
|
options
|
||||||
}: IAxiosRequest<RequestData, ResponseData>) {
|
}: IAxiosRequest<RequestData, ResponseData>) {
|
||||||
if (request.setLoading) request.setLoading(true);
|
if (request.setLoading) request.setLoading(true);
|
||||||
axiosInstance
|
axiosInstance
|
||||||
.patch<ResponseData>(endpoint, request.data, options)
|
.patch<ResponseData>(endpoint, request.data, options)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { memo, type FC } from 'react';
|
import { Handle, Position } from '@reactflow/core';
|
||||||
import { Handle, Position, type NodeProps } from '@reactflow/core';
|
import { type FC, memo } from 'react';
|
||||||
import Button from '@/components/ui/Button.tsx';
|
|
||||||
import { PiPlugsConnected } from 'react-icons/pi';
|
|
||||||
import { CiSquareRemove } from 'react-icons/ci';
|
import { CiSquareRemove } from 'react-icons/ci';
|
||||||
|
import { PiPlugsConnected } from 'react-icons/pi';
|
||||||
|
|
||||||
import MiniButton from '@/components/ui/MiniButton.tsx';
|
import MiniButton from '@/components/ui/MiniButton.tsx';
|
||||||
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
||||||
|
|
||||||
|
@ -12,48 +12,48 @@ interface InputNodeProps {
|
||||||
label: string;
|
label: string;
|
||||||
onDelete: (nodeId: string) => void;
|
onDelete: (nodeId: string) => void;
|
||||||
};
|
};
|
||||||
bound_rsform_id: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const InputNode: FC<InputNodeProps> = ({ id, data }) => {
|
||||||
const InputNode: FC<InputNodeProps> = ({ id, data,bound_rsform_id }) => {
|
|
||||||
const controller = useSynthesis();
|
const controller = useSynthesis();
|
||||||
const { label, onDelete } = data;
|
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
onDelete(id);
|
data.onDelete(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = () =>{
|
const handleClick = () => {
|
||||||
controller.selectNode(id);
|
controller.selectNode(id);
|
||||||
controller.showSelectInput();
|
controller.showSelectInput();
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Handle type="target" position={Position.Bottom} />
|
<Handle type='target' position={Position.Bottom} />
|
||||||
<div>
|
<div>
|
||||||
<MiniButton className="float-right"
|
<MiniButton
|
||||||
icon={<CiSquareRemove className="icon-red" />}
|
className='float-right'
|
||||||
title="Удалить"
|
icon={<CiSquareRemove className='icon-red' />}
|
||||||
onClick={handleDelete}
|
title='Удалить'
|
||||||
color={'red'}
|
onClick={handleDelete}
|
||||||
|
color={'red'}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
Тип: <strong>Ввод</strong>
|
Тип: <strong>Ввод</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Схема:{controller.getBind(id) === undefined? '': controller.getBind(id)}
|
Схема:{controller.getBind(id) === undefined ? '' : controller.getBind(id)}
|
||||||
<strong>
|
<strong>
|
||||||
<MiniButton className="float-right"
|
<MiniButton
|
||||||
icon={<PiPlugsConnected className="icon-green" />}
|
className='float-right'
|
||||||
title="Привязать схему"
|
icon={<PiPlugsConnected className='icon-green' />}
|
||||||
onClick={() => {handleClick()}}
|
title='Привязать схему'
|
||||||
|
onClick={() => {
|
||||||
|
handleClick();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { memo, type FC, type CSSProperties } from 'react';
|
import { Handle, Position } from '@reactflow/core';
|
||||||
import { Handle, Position, type NodeProps } from '@reactflow/core';
|
import { type CSSProperties, type FC, memo } from 'react';
|
||||||
import MiniButton from '@/components/ui/MiniButton.tsx';
|
|
||||||
import { IoGitNetworkSharp } from 'react-icons/io5';
|
|
||||||
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
|
||||||
import { CiSquareRemove } from 'react-icons/ci';
|
import { CiSquareRemove } from 'react-icons/ci';
|
||||||
import { VscDebugStart } from "react-icons/vsc";
|
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 sourceHandleStyleA: CSSProperties = { left: 50 };
|
||||||
const sourceHandleStyleB: CSSProperties = {
|
const sourceHandleStyleB: CSSProperties = {
|
||||||
|
@ -18,8 +19,8 @@ interface OperationNodeProps {
|
||||||
label: string;
|
label: string;
|
||||||
onDelete: (nodeId: string) => void;
|
onDelete: (nodeId: string) => void;
|
||||||
};
|
};
|
||||||
xPos: number,
|
xPos: number;
|
||||||
yPos: number,
|
yPos: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OperationNode: FC<OperationNodeProps> = ({ id, data, xPos, yPos }) => {
|
const OperationNode: FC<OperationNodeProps> = ({ id, data, xPos, yPos }) => {
|
||||||
|
@ -30,60 +31,48 @@ const OperationNode: FC<OperationNodeProps> = ({ id, data, xPos, yPos }) => {
|
||||||
onDelete(id);
|
onDelete(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubstitution = () =>{
|
const handleSubstitution = () => {
|
||||||
controller.selectNode(id);
|
controller.selectNode(id);
|
||||||
controller.showSynthesis();
|
controller.showSynthesis();
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleSynthesis = () => {
|
const handleSynthesis = () => {
|
||||||
controller.singleSynthesis(id)
|
controller.singleSynthesis(id);
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Handle type="target" position={Position.Bottom} />
|
<Handle type='target' position={Position.Bottom} />
|
||||||
<div>
|
<div>
|
||||||
<MiniButton className="float-right"
|
<MiniButton
|
||||||
icon={<CiSquareRemove className="icon-red" />}
|
className='float-right'
|
||||||
title="Удалить"
|
icon={<CiSquareRemove className='icon-red' />}
|
||||||
onClick={handleDelete}
|
title='Удалить'
|
||||||
color={'red'}
|
onClick={handleDelete}
|
||||||
|
color={'red'}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
Тип: <strong>Отождествление</strong>
|
Тип: <strong>Отождествление</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Схема:{' '}
|
Схема: <strong></strong>
|
||||||
<strong>
|
|
||||||
</strong>
|
|
||||||
<MiniButton
|
<MiniButton
|
||||||
className="float-right"
|
className='float-right'
|
||||||
icon={<VscDebugStart className="icon-green" />}
|
icon={<VscDebugStart className='icon-green' />}
|
||||||
title="Синтез"
|
title='Синтез'
|
||||||
onClick={() => handleSynthesis()}
|
onClick={() => handleSynthesis()}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
className="float-right"
|
className='float-right'
|
||||||
icon={<IoGitNetworkSharp className="icon-green" />}
|
icon={<IoGitNetworkSharp className='icon-green' />}
|
||||||
title="Отождествления"
|
title='Отождествления'
|
||||||
onClick={() => handleSubstitution()}
|
onClick={() => handleSubstitution()}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Handle
|
<Handle type='source' position={Position.Top} id='a' style={sourceHandleStyleA} />
|
||||||
type="source"
|
<Handle type='source' position={Position.Top} id='b' style={sourceHandleStyleB} />
|
||||||
position={Position.Top}
|
|
||||||
id="a"
|
|
||||||
style={sourceHandleStyleA}
|
|
||||||
/>
|
|
||||||
<Handle
|
|
||||||
type="source"
|
|
||||||
position={Position.Top}
|
|
||||||
id="b"
|
|
||||||
style={sourceHandleStyleB}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,42 +1,31 @@
|
||||||
import { useCallback, useMemo } from 'react';
|
|
||||||
import {
|
|
||||||
ReactFlow,
|
|
||||||
addEdge,
|
|
||||||
useNodesState,
|
|
||||||
useEdgesState,
|
|
||||||
type Connection,
|
|
||||||
type Edge,
|
|
||||||
type Node, OnSelectionChangeParams
|
|
||||||
} from '@reactflow/core';
|
|
||||||
|
|
||||||
|
|
||||||
import OperationNode from './OperationNode';
|
|
||||||
import InputNode from './InputNode';
|
|
||||||
|
|
||||||
// this is important! You need to import the styles from the lib to make it work
|
// this is important! You need to import the styles from the lib to make it work
|
||||||
import '@reactflow/core/dist/style.css';
|
import '@reactflow/core/dist/style.css';
|
||||||
|
|
||||||
import './SynthesisFlow.css';
|
import './SynthesisFlow.css';
|
||||||
import { useState } from 'react';
|
|
||||||
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
import { NodeTypes, ReactFlow } from '@reactflow/core';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import { useConceptOptions } from '@/context/OptionsContext.tsx';
|
import { useConceptOptions } from '@/context/OptionsContext.tsx';
|
||||||
|
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
||||||
|
|
||||||
|
import InputNode from './InputNode';
|
||||||
|
import OperationNode from './OperationNode';
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes: NodeTypes = {
|
||||||
custom: OperationNode,
|
custom: OperationNode,
|
||||||
input: InputNode
|
input: InputNode
|
||||||
};
|
};
|
||||||
|
|
||||||
function Flow() {
|
function Flow() {
|
||||||
const controller = useSynthesis();
|
const controller = useSynthesis();
|
||||||
const { calculateHeight, darkMode } = useConceptOptions();
|
const { calculateHeight } = useConceptOptions();
|
||||||
const canvasWidth = useMemo(() => {
|
const canvasWidth = useMemo(() => {
|
||||||
return 'calc(100vw - 1rem)';
|
return 'calc(100vw - 1rem)';
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const canvasHeight = useMemo(() => calculateHeight('1.75rem + 4px'), [calculateHeight]);
|
const canvasHeight = useMemo(() => calculateHeight('1.75rem + 4px'), [calculateHeight]);
|
||||||
return (
|
return (
|
||||||
<div className="relative" style={{ height: canvasHeight, width: canvasWidth }}>
|
<div className='relative' style={{ height: canvasHeight, width: canvasWidth }}>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
nodes={controller.getNodes()}
|
nodes={controller.getNodes()}
|
||||||
onNodesChange={controller.onNodesChange}
|
onNodesChange={controller.onNodesChange}
|
||||||
|
|
|
@ -1,27 +1,15 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import clsx from 'clsx';
|
||||||
|
import { useMemo, useState } from 'react';
|
||||||
|
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import Checkbox from '@/components/ui/Checkbox.tsx';
|
|
||||||
import FileInput from '@/components/ui/FileInput.tsx';
|
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal.tsx';
|
import Modal, { ModalProps } from '@/components/ui/Modal.tsx';
|
||||||
import { useRSForm } from '@/context/RSFormContext.tsx';
|
|
||||||
import { IRSForm, IRSFormUploadData, ISubstitution } from '@/models/rsform.ts';
|
|
||||||
import { EXTEOR_TRS_FILE } from '@/utils/constants.ts';
|
|
||||||
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
|
||||||
import clsx from 'clsx';
|
|
||||||
import TabLabel from '@/components/ui/TabLabel.tsx';
|
import TabLabel from '@/components/ui/TabLabel.tsx';
|
||||||
import SubstitutionsTab from '@/dialogs/DlgInlineSynthesis/SubstitutionsTab.tsx';
|
|
||||||
import useRSFormDetails from '@/hooks/useRSFormDetails.ts';
|
|
||||||
import { LibraryItemID } from '@/models/library.ts';
|
|
||||||
import { ISynthesisData } from '@/models/synthesis.ts';
|
|
||||||
import { TabID } from '@/dialogs/DlgInlineSynthesis/DlgInlineSynthesis.tsx';
|
|
||||||
import SynthesisSubstitutionsTab from '@/pages/OssPage/SynthesisSubstitutionsTab.tsx';
|
|
||||||
import SchemaTab from '@/dialogs/DlgInlineSynthesis/SchemaTab.tsx';
|
import SchemaTab from '@/dialogs/DlgInlineSynthesis/SchemaTab.tsx';
|
||||||
import {
|
import { LibraryItemID } from '@/models/library.ts';
|
||||||
Node
|
import { ISubstitution } from '@/models/rsform.ts';
|
||||||
} from '@reactflow/core';
|
|
||||||
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
||||||
|
|
||||||
interface DlgCreateSynthesisProps extends Pick<ModalProps, 'hideWindow'> {
|
interface DlgCreateSynthesisProps extends Pick<ModalProps, 'hideWindow'> {
|
||||||
|
@ -41,7 +29,6 @@ function DlgSelectInputScheme({ nodeId, hideWindow }: DlgCreateSynthesisProps) {
|
||||||
const [substitutions, setSubstitutions] = useState<ISubstitution[]>([]);
|
const [substitutions, setSubstitutions] = useState<ISubstitution[]>([]);
|
||||||
const [donorID, setDonorID] = useState<LibraryItemID | undefined>(undefined);
|
const [donorID, setDonorID] = useState<LibraryItemID | undefined>(undefined);
|
||||||
|
|
||||||
|
|
||||||
const schemaPanel = useMemo(
|
const schemaPanel = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
|
@ -67,22 +54,21 @@ function DlgSelectInputScheme({ nodeId, hideWindow }: DlgCreateSynthesisProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header="Синтез концептуальных скем"
|
header='Синтез концептуальных схем'
|
||||||
hideWindow={hideWindow}
|
hideWindow={hideWindow}
|
||||||
submitText="Привязать"
|
submitText='Привязать'
|
||||||
className="w-[25rem] px-6"
|
className='w-[25rem] px-6'
|
||||||
canSubmit={validate()}
|
canSubmit={validate()}
|
||||||
|
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
<Tabs
|
<Tabs
|
||||||
selectedTabClassName="clr-selected"
|
selectedTabClassName='clr-selected'
|
||||||
className="flex flex-col"
|
className='flex flex-col'
|
||||||
selectedIndex={activeTab}
|
selectedIndex={activeTab}
|
||||||
onSelect={setActiveTab}
|
onSelect={setActiveTab}
|
||||||
>
|
>
|
||||||
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none')}>
|
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none')}>
|
||||||
<TabLabel label="Схема" title="Источник конституент" className="w-[8rem]" />
|
<TabLabel label='Схема' title='Источник конституент' className='w-[8rem]' />
|
||||||
</TabList>
|
</TabList>
|
||||||
{schemaPanel}
|
{schemaPanel}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useMemo, useState } from 'react';
|
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 Modal, { ModalProps } from '@/components/ui/Modal.tsx';
|
||||||
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
|
||||||
import clsx from 'clsx';
|
|
||||||
import TabLabel from '@/components/ui/TabLabel.tsx';
|
import TabLabel from '@/components/ui/TabLabel.tsx';
|
||||||
import useRSFormDetails from '@/hooks/useRSFormDetails.ts';
|
import useRSFormDetails from '@/hooks/useRSFormDetails.ts';
|
||||||
import SynthesisSubstitutionsTab from '@/pages/OssPage/SynthesisSubstitutionsTab.tsx';
|
|
||||||
import { useSynthesis } from '@/pages/OssPage/SynthesisContext.tsx';
|
|
||||||
import { ISynthesisSubstitution } from '@/models/oss.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<ModalProps, 'hideWindow'> {
|
interface DlgCreateSynthesisProps extends Pick<ModalProps, 'hideWindow'> {
|
||||||
nodeId: string;
|
nodeId: string;
|
||||||
|
@ -25,24 +25,24 @@ function DlgSynthesis({ hideWindow, nodeId, onSynthesis }: DlgCreateSynthesisPro
|
||||||
const controller = useSynthesis();
|
const controller = useSynthesis();
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = useState(SynthesisTabID.SCHEMA);
|
const [activeTab, setActiveTab] = useState(SynthesisTabID.SCHEMA);
|
||||||
|
|
||||||
const sourceLeft = useRSFormDetails({
|
const sourceLeft = useRSFormDetails({
|
||||||
target: controller.getNodeParentsRsform(nodeId)[0] ?
|
target: controller.getNodeParentsRsform(nodeId)[0] ? String(controller.getNodeParentsRsform(nodeId)[0]) : undefined
|
||||||
String(controller.getNodeParentsRsform(nodeId)[0]) : undefined
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const sourceRight = useRSFormDetails({
|
const sourceRight = useRSFormDetails({
|
||||||
target: controller.getNodeParentsRsform(nodeId)[1] ?
|
target: controller.getNodeParentsRsform(nodeId)[1] ? String(controller.getNodeParentsRsform(nodeId)[1]) : undefined
|
||||||
String(controller.getNodeParentsRsform(nodeId)[1]) : undefined
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const validated = useMemo(() => controller.getNodeParentsRsform(nodeId).length == 2, [controller, nodeId]);
|
||||||
|
|
||||||
//const validated = useMemo(() => !!source.schema && selected.length > 0, [source.schema, selected]);
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
const parents = controller.getNodeParentsRsform(nodeId);
|
const parents = controller.getNodeParentsRsform(nodeId);
|
||||||
|
|
||||||
if (parents.length != 2) {
|
if (parents.length != 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data: ISynthesisSubstitution[] = controller.substitutions.map((item) => ({
|
const data: ISynthesisSubstitution[] = controller.substitutions.map(item => ({
|
||||||
id: null,
|
id: null,
|
||||||
operation_id: nodeId,
|
operation_id: nodeId,
|
||||||
leftCst: item.leftCst,
|
leftCst: item.leftCst,
|
||||||
|
@ -53,27 +53,17 @@ function DlgSynthesis({ hideWindow, nodeId, onSynthesis }: DlgCreateSynthesisPro
|
||||||
controller.setSubstitutions(data);
|
controller.setSubstitutions(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function validated() {
|
const schemaPanel = useMemo(() => <TabPanel></TabPanel>, []);
|
||||||
const parents = controller.getNodeParentsRsform(nodeId);
|
|
||||||
return parents.length == 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
const schemaPanel = useMemo(
|
const selectedSubstitutions = useMemo(() => controller.getSubstitution(nodeId), [controller, nodeId]);
|
||||||
() => (
|
|
||||||
<TabPanel></TabPanel>
|
|
||||||
), []
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedSubstitutions = useMemo(
|
const setSelectedSubstitutions = useCallback(
|
||||||
() => controller.getSubstitution(nodeId),
|
(newElement: ISynthesisSubstitution[]) => {
|
||||||
|
controller.updateSubstitution(nodeId, newElement);
|
||||||
|
},
|
||||||
[controller, nodeId]
|
[controller, nodeId]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSelectedSubstitutions = (newElement: ISynthesisSubstitution[]) => {
|
|
||||||
controller.updateSubstitution(nodeId, newElement, controller.setSubstitutions);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const substitutesPanel = useMemo(
|
const substitutesPanel = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
|
@ -85,34 +75,31 @@ function DlgSynthesis({ hideWindow, nodeId, onSynthesis }: DlgCreateSynthesisPro
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
),
|
),
|
||||||
[sourceLeft.schema, sourceRight.schema, controller]
|
[sourceLeft.schema, sourceRight.schema, selectedSubstitutions, setSelectedSubstitutions]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
header="Синтез концептуальных схем"
|
header='Синтез концептуальных схем'
|
||||||
hideWindow={hideWindow}
|
hideWindow={hideWindow}
|
||||||
submitText="Сохранить"
|
submitText='Сохранить'
|
||||||
className="w-[25rem] px-6"
|
className='w-[35rem] px-6'
|
||||||
canSubmit={validated}
|
canSubmit={validated}
|
||||||
|
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
|
||||||
>
|
>
|
||||||
<Tabs
|
<Tabs
|
||||||
selectedTabClassName="clr-selected"
|
selectedTabClassName='clr-selected'
|
||||||
className="flex flex-col"
|
className='flex flex-col'
|
||||||
selectedIndex={activeTab}
|
selectedIndex={activeTab}
|
||||||
onSelect={setActiveTab}
|
onSelect={setActiveTab}
|
||||||
>
|
>
|
||||||
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none')}>
|
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none')}>
|
||||||
<TabLabel label="Схема" title="Источник конституент" className="w-[8rem]" />
|
<TabLabel label='Схема' title='Источник конституент' className='w-[8rem]' />
|
||||||
<TabLabel label="Отождествления" title="Таблица отождествлений" className="w-[8rem]" />
|
<TabLabel label='Отождествления' title='Таблица отождествлений' className='w-[8rem]' />
|
||||||
</TabList>
|
</TabList>
|
||||||
{schemaPanel}
|
{schemaPanel}
|
||||||
{substitutesPanel}
|
{substitutesPanel}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { getOssDetails } from '@/app/backendAPI';
|
import { getOssDetails } from '@/app/backendAPI';
|
||||||
import { type ErrorData } from '@/components/info/InfoError';
|
import { type ErrorData } from '@/components/info/InfoError';
|
||||||
|
import { AccessPolicy, LibraryItemType } from '@/models/library.ts';
|
||||||
import { IOperationSchema, IOperationSchemaData } from '@/models/oss';
|
import { IOperationSchema, IOperationSchemaData } from '@/models/oss';
|
||||||
import { OssLoader } from '@/models/OssLoader';
|
import { OssLoader } from '@/models/OssLoader';
|
||||||
import { AccessPolicy, LibraryItemType } from '@/models/library.ts';
|
|
||||||
|
|
||||||
function useOssDetails({ target }: { target?: string }) {
|
function useOssDetails({ target }: { target?: string }) {
|
||||||
const [schema, setInner] = useState<IOperationSchema | undefined>(undefined);
|
const [schema, setInner] = useState<IOperationSchema | undefined>(undefined);
|
||||||
|
@ -57,7 +57,7 @@ function useOssDetails({ target }: { target?: string }) {
|
||||||
const combinedData = {
|
const combinedData = {
|
||||||
...staticData,
|
...staticData,
|
||||||
...schema
|
...schema
|
||||||
}
|
};
|
||||||
setSchema(combinedData);
|
setSchema(combinedData);
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,13 @@ import { IOperationSchema, IOperationSchemaData } from './oss';
|
||||||
export class OssLoader {
|
export class OssLoader {
|
||||||
private schema: IOperationSchemaData;
|
private schema: IOperationSchemaData;
|
||||||
|
|
||||||
|
|
||||||
constructor(input: IOperationSchemaData) {
|
constructor(input: IOperationSchemaData) {
|
||||||
this.schema = input;
|
this.schema = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
produceOSS(): IOperationSchema {
|
produceOSS(): IOperationSchema {
|
||||||
const result = this.schema as IOperationSchema;
|
const result = this.schema as IOperationSchema;
|
||||||
//result.producedData = [1, 2, 3]; // TODO: put data processing here
|
// TODO: put data processing here
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
* Module: Schema of Synthesis Operations.
|
* Module: Schema of Synthesis Operations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ISubstitution } from '@/models/rsform.ts';
|
||||||
|
|
||||||
import { ILibraryItemData } from './library';
|
import { ILibraryItemData } from './library';
|
||||||
import { UserID } from './user';
|
import { UserID } from './user';
|
||||||
import { IConstituenta, ISubstitution } from '@/models/rsform.ts';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents backend data for Schema of Synthesis Operations.
|
* Represents backend data for Schema of Synthesis Operations.
|
||||||
|
@ -65,3 +66,4 @@ export interface IRunSynthesisResponse {
|
||||||
export interface IOperationSchema extends IOperationSchemaData {
|
export interface IOperationSchema extends IOperationSchemaData {
|
||||||
subscribers: UserID[];
|
subscribers: UserID[];
|
||||||
editors: UserID[];
|
editors: UserID[];
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
import { IRSFormData, ISubstitution } from '@/models/rsform.ts';
|
|
||||||
import { DataCallback, runSingleSynthesis, postSynthesisGraph } from '@/app/backendAPI.ts';
|
|
||||||
import { ISynthesisData } from '@/models/synthesis.ts';
|
|
||||||
import { createContext, Dispatch, SetStateAction, useCallback, useContext, useEffect, useState } from 'react';
|
|
||||||
import DlgSynthesis from '@/dialogs/DlgOssGraph/DlgSynthesis.tsx';
|
|
||||||
import {
|
import {
|
||||||
Node,
|
|
||||||
Edge,
|
|
||||||
useNodesState,
|
|
||||||
useEdgesState,
|
|
||||||
type Connection,
|
|
||||||
addEdge,
|
addEdge,
|
||||||
getIncomers,
|
type Connection,
|
||||||
getOutgoers,
|
Edge,
|
||||||
getConnectedEdges
|
EdgeChange,
|
||||||
|
Node,
|
||||||
|
NodeChange,
|
||||||
|
useEdgesState,
|
||||||
|
useNodesState
|
||||||
} from '@reactflow/core';
|
} from '@reactflow/core';
|
||||||
import DlgSelectInputScheme from '@/dialogs/DlgOssGraph/DlgSelectInputScheme.tsx';
|
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||||
import { IOperationSchemaData, IRunSynthesis, ISynthesisSubstitution } from '@/models/oss.ts';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
import { postSynthesisGraph, runSingleSynthesis } from '@/app/backendAPI.ts';
|
||||||
import { useOSS } from '@/context/OssContext.tsx';
|
import { useOSS } from '@/context/OssContext.tsx';
|
||||||
import viewConstituents from '@/pages/RSFormPage/ViewConstituents';
|
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 {
|
interface ISynthesisContext {
|
||||||
synthesisSchemaID: string;
|
synthesisSchemaID: string;
|
||||||
|
@ -32,32 +31,32 @@ interface ISynthesisContext {
|
||||||
removeItem: () => void;
|
removeItem: () => void;
|
||||||
runSynthesisLayer: () => void;
|
runSynthesisLayer: () => void;
|
||||||
|
|
||||||
getNodes: () => Node[],
|
getNodes: () => Node[];
|
||||||
getEdges: () => Edge[]
|
getEdges: () => Edge[];
|
||||||
|
|
||||||
setNodes: (nodes: Node[]) => void;
|
setNodes: (nodes: Node[]) => void;
|
||||||
setEdges: (nodes: Edge[]) => void;
|
setEdges: (nodes: Edge[]) => void;
|
||||||
|
|
||||||
onNodesChange: any,
|
onNodesChange: (changes: NodeChange[]) => void;
|
||||||
onEdgesChange: any,
|
onEdgesChange: (changes: EdgeChange[]) => void;
|
||||||
onNodesDelete: any,
|
onNodesDelete: (nodes: Node[]) => void;
|
||||||
onConnect: any,
|
onConnect: (connection: Connection) => void;
|
||||||
addBind: () => void,
|
addBind: () => void;
|
||||||
|
|
||||||
updateBounds: (nodeId: string, newRsform: number) => void,
|
updateBounds: (nodeId: string, newRsform: number) => void;
|
||||||
getBind: (nodeId: string) => number
|
getBind: (nodeId: string) => number | undefined;
|
||||||
getNodeParentsRsform: (nodeId: string) => number[]
|
getNodeParentsRsform: (nodeId: string) => number[];
|
||||||
saveGraph: () => void;
|
saveGraph: () => void;
|
||||||
substitutions: ISynthesisSubstitution[]
|
|
||||||
setSubstitutions: () => void,
|
|
||||||
getSubstitution: (id: string) => ISynthesisSubstitution[],
|
|
||||||
updateSubstitution: (id: string, substitution: ISynthesisSubstitution[], setSubstitutions: React.Dispatch<React.SetStateAction<ISynthesisSubstitution[]>>) => void,
|
|
||||||
|
|
||||||
|
substitutions: ISynthesisSubstitution[];
|
||||||
|
setSubstitutions: React.Dispatch<React.SetStateAction<ISynthesisSubstitution[]>>;
|
||||||
|
getSubstitution: (id: string) => ISynthesisSubstitution[];
|
||||||
|
updateSubstitution: (id: string, substitution: ISubstitution[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IBoundMap {
|
interface IBoundMap {
|
||||||
nodeId: string,
|
nodeId: string;
|
||||||
rsformId: number
|
rsformId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SynthesisContext = createContext<ISynthesisContext | null>(null);
|
const SynthesisContext = createContext<ISynthesisContext | null>(null);
|
||||||
|
@ -84,69 +83,98 @@ export const SynthesisState = ({ synthesisSchemaID, children }: SynthesisStatePr
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||||
|
|
||||||
const [bounds, setBounds] = useState<IBoundMap[]>([]);
|
const [bounds, setBounds] = useState<IBoundMap[]>([]);
|
||||||
const [substitutionBounds, setSubstitutionBounds] = useState<IBoundMap[]>([]);
|
// const [substitutionBounds, setSubstitutionBounds] = useState<IBoundMap[]>([]);
|
||||||
const [substitutions, setSubstitutions] = useState<ISynthesisSubstitution[]>([]);
|
const [substitutions, setSubstitutions] = useState<ISynthesisSubstitution[]>([]);
|
||||||
const { schema, loading, errorLoading } = useOSS();
|
|
||||||
const ossSchema = useOSS();
|
|
||||||
|
|
||||||
|
const ossSchema = useOSS();
|
||||||
|
|
||||||
const getSubstitution = (operation_id: string): ISynthesisSubstitution[] => {
|
const getSubstitution = (operation_id: string): ISynthesisSubstitution[] => {
|
||||||
return substitutions.filter(substitution => substitution.operation_id === operation_id);
|
return substitutions.filter(substitution => substitution.operation_id === operation_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateSubstitution = (
|
const updateSubstitution = (operation_id: string, newElements: ISubstitution[]) => {
|
||||||
operation_id: number,
|
// TODO: Call backend API and reload OSS or use returned data for
|
||||||
newElements: ISubstitution[],
|
console.log(operation_id);
|
||||||
setSubstitutions: React.Dispatch<React.SetStateAction<ISynthesisSubstitution[]>>
|
console.log(newElements);
|
||||||
) => {
|
toast('Saving substitution table not supported');
|
||||||
if (!Array.isArray(newElements)) {
|
return;
|
||||||
console.error('newElements should be an array.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSubstitutions((prevSubstitutions) => {
|
// if (!Array.isArray(newElements)) {
|
||||||
// Обновление существующих элементов
|
// console.error('newElements should be an array.');
|
||||||
const updatedSubstitutions = prevSubstitutions.map((substitution) => {
|
// return;
|
||||||
const newElement = newElements.find((el) => el.id === substitution.id);
|
// }
|
||||||
if (newElement) {
|
|
||||||
// Обновляем только соответствующие элементы
|
|
||||||
return { ...substitution, ...newElement, operation_id: substitution.operation_id };
|
|
||||||
}
|
|
||||||
return substitution;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Добавление новых элементов с присвоением operation_id
|
// setSubstitutions(prevSubstitutions => {
|
||||||
const newSubstitutions = newElements
|
// // Обновление существующих элементов
|
||||||
.filter((newElement) => !prevSubstitutions.some((sub) => sub.id === newElement.id))
|
// const updatedSubstitutions = prevSubstitutions.map(substitution => {
|
||||||
.map((newElement) => ({ ...newElement, operation_id }));
|
// const newElement = newElements.find(el => el.id === substitution.id);
|
||||||
|
// if (newElement) {
|
||||||
|
// // Обновляем только соответствующие элементы
|
||||||
|
// return { ...substitution, ...newElement, operation_id: substitution.operation_id };
|
||||||
|
// }
|
||||||
|
// return substitution;
|
||||||
|
// });
|
||||||
|
|
||||||
return [...updatedSubstitutions, ...newSubstitutions];
|
// // Добавление новых элементов с присвоением 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 extractEdgeId = (edgeId: string) => {
|
||||||
const matches = edgeId.match(/\d+/g);
|
const matches = edgeId.match(/\d+/g);
|
||||||
const combined = matches ? matches.join('') : '';
|
const combined = matches ? matches.join('') : '';
|
||||||
return Number(combined);
|
return Number(combined);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getBind = useCallback(
|
||||||
|
(nodeId: string) => {
|
||||||
|
const bound = bounds.find(item => item.nodeId == nodeId);
|
||||||
|
return bound ? bound.rsformId : undefined;
|
||||||
|
},
|
||||||
|
[bounds]
|
||||||
|
);
|
||||||
|
|
||||||
function saveGraph() {
|
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 = {
|
const data: IOperationSchemaData = {
|
||||||
graph: {
|
graph: {
|
||||||
id: schema?.id,
|
id: ossSchema.schema?.id,
|
||||||
status: 'Draft'
|
status: 'Draft'
|
||||||
},
|
},
|
||||||
input_nodes: nodes.filter((node) => node.type == 'input').map(item =>
|
input_nodes: nodes
|
||||||
({
|
.filter(node => node.type == 'input')
|
||||||
|
.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
vertical_coordinate: item.position.y,
|
vertical_coordinate: item.position.y,
|
||||||
horizontal_coordinate: item.position.x,
|
horizontal_coordinate: item.position.x,
|
||||||
rsform_id: getBind(item.id)
|
rsform_id: getBind(item.id)
|
||||||
})),
|
})),
|
||||||
operation_nodes: nodes.filter((node) => node.type == 'custom').map(item =>
|
operation_nodes: nodes
|
||||||
({
|
.filter(node => node.type == 'custom')
|
||||||
|
.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
vertical_coordinate: item.position.y,
|
vertical_coordinate: item.position.y,
|
||||||
horizontal_coordinate: item.position.x,
|
horizontal_coordinate: item.position.x,
|
||||||
|
@ -155,34 +183,32 @@ export const SynthesisState = ({ synthesisSchemaID, children }: SynthesisStatePr
|
||||||
rsform_id: getBind(item.id),
|
rsform_id: getBind(item.id),
|
||||||
name: 'name',
|
name: 'name',
|
||||||
status: 'status'
|
status: 'status'
|
||||||
})
|
})),
|
||||||
),
|
|
||||||
edges: edges.map(item => ({
|
edges: edges.map(item => ({
|
||||||
id: extractEdgeId(item.id),
|
id: extractEdgeId(item.id),
|
||||||
decoded_id: item.id,
|
decoded_id: item.id,
|
||||||
source_handle: item.sourceHandle,
|
source_handle: item.sourceHandle,
|
||||||
node_from: item.source,
|
node_from: item.source,
|
||||||
node_to: item.target
|
node_to: item.target
|
||||||
})
|
})),
|
||||||
),
|
|
||||||
substitutions: substitutions
|
substitutions: substitutions
|
||||||
};
|
};
|
||||||
|
|
||||||
postSynthesisGraph({
|
postSynthesisGraph({
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
}
|
}, [ossSchema, edges, nodes, getBind, substitutions, getNodeParentsRsform]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ossSchema.schema !== undefined) {
|
if (ossSchema.schema !== undefined) {
|
||||||
const initialNodes = [
|
const initialNodes = [
|
||||||
...ossSchema.schema.input_nodes.map((node) => ({
|
...ossSchema.schema.input_nodes.map(node => ({
|
||||||
id: node.id?.toString() || 'null',
|
id: node.id?.toString() || 'null',
|
||||||
data: { label: '123' },
|
data: { label: '123' },
|
||||||
position: { x: node.horizontal_coordinate, y: node.vertical_coordinate },
|
position: { x: node.horizontal_coordinate, y: node.vertical_coordinate },
|
||||||
type: 'input'
|
type: 'input'
|
||||||
})),
|
})),
|
||||||
...ossSchema.schema.operation_nodes.map((node) => ({
|
...ossSchema.schema.operation_nodes.map(node => ({
|
||||||
id: node.id?.toString() || 'null',
|
id: node.id?.toString() || 'null',
|
||||||
data: { label: '123' },
|
data: { label: '123' },
|
||||||
position: { x: node.horizontal_coordinate, y: node.vertical_coordinate },
|
position: { x: node.horizontal_coordinate, y: node.vertical_coordinate },
|
||||||
|
@ -190,88 +216,64 @@ export const SynthesisState = ({ synthesisSchemaID, children }: SynthesisStatePr
|
||||||
}))
|
}))
|
||||||
];
|
];
|
||||||
|
|
||||||
const initialEdges = ossSchema.schema.edges.map((edge) => ({
|
const initialEdges = ossSchema.schema.edges.map(edge => ({
|
||||||
id: edge.decoded_id,
|
id: edge.decoded_id,
|
||||||
source: String(edge.node_from),
|
source: String(edge.node_from),
|
||||||
sourceHandle: edge.source_handle,
|
sourceHandle: edge.source_handle,
|
||||||
target: String(edge.node_to)
|
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' }];
|
// const initialEdges = [
|
||||||
|
// { id: 'reactflow__edge-2a-0', source: '2', target: '0' },
|
||||||
|
// { id: 'reactflow__edge-2b-1', sourceHandle: 'b', source: '2', target: '1' }
|
||||||
|
// ];
|
||||||
|
|
||||||
setNodes(initialNodes);
|
setNodes(initialNodes);
|
||||||
setEdges(initialEdges);
|
setEdges(initialEdges);
|
||||||
setSubstitutions(ossSchema.schema.substitutions);
|
setSubstitutions(ossSchema.schema.substitutions);
|
||||||
[...ossSchema.schema.input_nodes, ...ossSchema.schema.operation_nodes].forEach((node) => {
|
[...ossSchema.schema.input_nodes, ...ossSchema.schema.operation_nodes].forEach(node => {
|
||||||
const nodeId = node.id?.toString() || 'null';
|
const nodeId = node.id?.toString() || 'null';
|
||||||
const rsformId = node.rsform_id; // Предполагаем, что rsform_id есть в данных нод
|
const rsformId = node.rsform_id; // Предполагаем, что rsform_id есть в данных нод
|
||||||
updateBounds(nodeId, rsformId);
|
updateBounds(nodeId, rsformId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}, [ossSchema, setEdges, setNodes]);
|
||||||
}, [ossSchema]);
|
|
||||||
|
|
||||||
const getBind = (nodeId: string) => {
|
|
||||||
const bound = bounds.find((item) => item.nodeId == nodeId);
|
|
||||||
return bound ? bound.rsformId : null;
|
|
||||||
|
|
||||||
};
|
|
||||||
const getBounds = (nodeId: string[]) => {
|
|
||||||
const parentBounds = bounds.filter((item) => item.nodeId in nodeId);
|
|
||||||
return parentBounds.map((item) => item.rsformId);
|
|
||||||
};
|
|
||||||
|
|
||||||
function getNodeParentsRsform(nodeId: string) {
|
|
||||||
const parentEdges = edges.filter((edge) => edge.source === nodeId);
|
|
||||||
const parentNodeIds = parentEdges.map((edge) => edge.target);
|
|
||||||
return getBounds(parentNodeIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateBounds = (nodeId: string, newRsform: number) => {
|
const updateBounds = (nodeId: string, newRsform: number) => {
|
||||||
setBounds((prevItems) => {
|
setBounds(prevItems => {
|
||||||
const existingItem = prevItems.find((item) => item.nodeId === nodeId);
|
const existingItem = prevItems.find(item => item.nodeId === nodeId);
|
||||||
|
|
||||||
if (existingItem) {
|
if (existingItem) {
|
||||||
return prevItems.map((item) =>
|
return prevItems.map(item => (item.nodeId === nodeId ? { ...item, rsformId: newRsform } : item));
|
||||||
item.nodeId === nodeId ? { ...item, rsformId: newRsform } : item
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return [...prevItems, { nodeId: nodeId, rsformId: newRsform }];
|
return [...prevItems, { nodeId: nodeId, rsformId: newRsform }];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onConnect = useCallback(
|
const onConnect = useCallback((params: Connection | Edge) => setEdges(eds => addEdge(params, eds)), [setEdges]);
|
||||||
(params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)),
|
|
||||||
[setEdges]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onNodeDelete = useCallback(
|
const onNodeDelete = useCallback(
|
||||||
(nodeId: string) => {
|
(nodeId: string) => {
|
||||||
setNodes((nodes) => nodes.filter((node) => node.id !== nodeId));
|
setNodes(nodes => nodes.filter(node => node.id !== nodeId));
|
||||||
setEdges((edges) =>
|
setEdges(edges => edges.filter(edge => edge.source !== nodeId && edge.target !== nodeId));
|
||||||
edges.filter((edge) => edge.source !== nodeId && edge.target !== nodeId)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
[]
|
[setEdges, setNodes]
|
||||||
);
|
);
|
||||||
|
|
||||||
const singleSynthesis = useCallback(
|
const singleSynthesis = useCallback((operationId: number) => {
|
||||||
(operationId: number) => {
|
const data: IRunSynthesis = {
|
||||||
const data: IRunSynthesis = {
|
operationId: Number(operationId)
|
||||||
operationId: Number(operationId)
|
};
|
||||||
};
|
runSingleSynthesis({ data: data });
|
||||||
runSingleSynthesis({ data: data });
|
}, []);
|
||||||
},
|
|
||||||
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
const newLibrarySchema = {
|
const newLibrarySchema = {
|
||||||
id: String(nodes.length > 0 ? 1 + Math.max(...nodes.map(item => Number(item.id))) : 0),
|
id: String(nodes.length > 0 ? 1 + Math.max(...nodes.map(item => Number(item.id))) : 0),
|
||||||
type: 'input',
|
type: 'input',
|
||||||
position: { x: 250, y: 5 },
|
position: { x: 250, y: 5 },
|
||||||
data: {
|
data: {
|
||||||
label: 'Node 1', onDelete: onNodeDelete
|
label: 'Node 1',
|
||||||
|
onDelete: onNodeDelete
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -280,7 +282,8 @@ export const SynthesisState = ({ synthesisSchemaID, children }: SynthesisStatePr
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
position: { x: 350, y: 20 },
|
position: { x: 350, y: 20 },
|
||||||
data: {
|
data: {
|
||||||
label: 'Node 1', onDelete: onNodeDelete
|
label: 'Node 1',
|
||||||
|
onDelete: onNodeDelete
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -292,54 +295,56 @@ export const SynthesisState = ({ synthesisSchemaID, children }: SynthesisStatePr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [nodes]
|
},
|
||||||
|
[nodes]
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<SynthesisContext.Provider value={{
|
<SynthesisContext.Provider
|
||||||
synthesisSchemaID: synthesisSchemaID,
|
value={{
|
||||||
singleSynthesis: singleSynthesis,
|
synthesisSchemaID: synthesisSchemaID,
|
||||||
showSynthesis: () => setShowSynthesisModal(true),
|
singleSynthesis: singleSynthesis,
|
||||||
showSelectInput: () => setShowSelectInputModal(true),
|
showSynthesis: () => setShowSynthesisModal(true),
|
||||||
selectNode: (nodeId) => selectNode(nodeId),
|
showSelectInput: () => setShowSelectInputModal(true),
|
||||||
getSelectedNode: () => selectedNode?.id,
|
selectNode: nodeId => selectNode(nodeId),
|
||||||
addLibrarySchema: () => {
|
getSelectedNode: () => selectedNode?.id,
|
||||||
setNodes([...nodes, newLibrarySchema]);
|
addLibrarySchema: () => {
|
||||||
},
|
setNodes([...nodes, newLibrarySchema]);
|
||||||
addSynthesisOperation: () => {
|
},
|
||||||
setNodes([...nodes, newOperation]);
|
addSynthesisOperation: () => {
|
||||||
},
|
setNodes([...nodes, newOperation]);
|
||||||
setNodes: (nodes: Node[]) => {
|
},
|
||||||
setNodes(nodes);
|
setNodes: (nodes: Node[]) => {
|
||||||
},
|
setNodes(nodes);
|
||||||
setEdges: (edges: Edge[]) => {
|
},
|
||||||
setEdges(edges);
|
setEdges: (edges: Edge[]) => {
|
||||||
},
|
setEdges(edges);
|
||||||
getNodes: () => nodes,
|
},
|
||||||
getEdges: () => edges,
|
getNodes: () => nodes,
|
||||||
onNodesChange: onNodesChange,
|
getEdges: () => edges,
|
||||||
onEdgesChange: onEdgesChange,
|
onNodesChange: onNodesChange,
|
||||||
onConnect: onConnect,
|
onEdgesChange: onEdgesChange,
|
||||||
updateBounds: updateBounds,
|
onConnect: onConnect,
|
||||||
getNodeParentsRsform: getNodeParentsRsform,
|
updateBounds: updateBounds,
|
||||||
getBind: getBind,
|
getNodeParentsRsform: getNodeParentsRsform,
|
||||||
saveGraph: saveGraph,
|
getBind: getBind,
|
||||||
setSubstitutions: setSubstitutions,
|
saveGraph: saveGraph,
|
||||||
substitutions: substitutions,
|
setSubstitutions: setSubstitutions,
|
||||||
updateSubstitution: updateSubstitution,
|
substitutions: substitutions,
|
||||||
getSubstitution: getSubstitution
|
updateSubstitution: updateSubstitution,
|
||||||
|
getSubstitution: getSubstitution
|
||||||
}}>
|
}}
|
||||||
{showSynthesisModal ? (<DlgSynthesis
|
>
|
||||||
hideWindow={() => setShowSynthesisModal(false)}
|
{showSynthesisModal ? (
|
||||||
nodeId={selectedNode?.id}
|
<DlgSynthesis
|
||||||
onSynthesis={() => singleSynthesis}
|
hideWindow={() => setShowSynthesisModal(false)}
|
||||||
/>) : null}
|
nodeId={selectedNode!.id}
|
||||||
{showSelectInputModal ? (<DlgSelectInputScheme
|
onSynthesis={() => singleSynthesis}
|
||||||
nodeId={selectedNode?.id}
|
/>
|
||||||
hideWindow={() => setShowSelectInputModal(false)}
|
) : null}
|
||||||
/>) : null}
|
{showSelectInputModal ? (
|
||||||
|
<DlgSelectInputScheme nodeId={selectedNode!.id} hideWindow={() => setShowSelectInputModal(false)} />
|
||||||
|
) : null}
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
</SynthesisContext.Provider>
|
</SynthesisContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
|
@ -1,9 +1,5 @@
|
||||||
|
function SynthesisOperation() {
|
||||||
|
return <div></div>;
|
||||||
|
|
||||||
function SynthesisOperation = () => {
|
|
||||||
return (<div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default SynthesisOperation;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { ErrorData } from '@/components/info/InfoError.tsx';
|
||||||
import DataLoader from '@/components/wrap/DataLoader.tsx';
|
import DataLoader from '@/components/wrap/DataLoader.tsx';
|
||||||
import { IRSForm, ISubstitution } from '@/models/rsform.ts';
|
import { IRSForm, ISubstitution } from '@/models/rsform.ts';
|
||||||
import { prefixes } from '@/utils/constants.ts';
|
import { prefixes } from '@/utils/constants.ts';
|
||||||
|
|
||||||
import PickSubstitutions from '../../components/select/PickSubstitutions';
|
import PickSubstitutions from '../../components/select/PickSubstitutions';
|
||||||
|
|
||||||
interface SynthesisSubstitutionsTabProps {
|
interface SynthesisSubstitutionsTabProps {
|
||||||
|
@ -17,14 +18,14 @@ interface SynthesisSubstitutionsTabProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function SynthesisSubstitutionsTab({
|
function SynthesisSubstitutionsTab({
|
||||||
source,
|
source,
|
||||||
receiver,
|
receiver,
|
||||||
error,
|
error,
|
||||||
substitutions,
|
substitutions,
|
||||||
setSubstitutions
|
setSubstitutions
|
||||||
}: SynthesisSubstitutionsTabProps) {
|
}: SynthesisSubstitutionsTabProps) {
|
||||||
return (
|
return (
|
||||||
<DataLoader id="dlg-substitutions-tab" className="cc-column" isLoading={false} error={error} hasNoData={!source}>
|
<DataLoader id='dlg-substitutions-tab' className='cc-column' isLoading={false} error={error} hasNoData={!source}>
|
||||||
<PickSubstitutions
|
<PickSubstitutions
|
||||||
items={substitutions}
|
items={substitutions}
|
||||||
setItems={setSubstitutions}
|
setItems={setSubstitutions}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user