F: Remove unnecessary updates and fix UI
This commit is contained in:
parent
ae22e9b9f7
commit
9d8405fc36
|
@ -18,6 +18,8 @@ from .basics import NodeSerializer, SubstitutionExSerializer
|
||||||
|
|
||||||
class OperationSerializer(serializers.ModelSerializer):
|
class OperationSerializer(serializers.ModelSerializer):
|
||||||
''' Serializer: Operation data. '''
|
''' Serializer: Operation data. '''
|
||||||
|
is_import = serializers.BooleanField(default=False, required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
''' serializer metadata. '''
|
''' serializer metadata. '''
|
||||||
model = Operation
|
model = Operation
|
||||||
|
@ -407,7 +409,13 @@ class OperationSchemaSerializer(serializers.ModelSerializer):
|
||||||
result['arguments'] = []
|
result['arguments'] = []
|
||||||
result['substitutions'] = []
|
result['substitutions'] = []
|
||||||
for operation in oss.operations().order_by('pk'):
|
for operation in oss.operations().order_by('pk'):
|
||||||
result['operations'].append(OperationSerializer(operation).data)
|
operation_data = OperationSerializer(operation).data
|
||||||
|
operation_result = operation.result
|
||||||
|
operation_data['is_import'] = \
|
||||||
|
operation_result is not None and \
|
||||||
|
(operation_result.owner_id != instance.owner_id or
|
||||||
|
operation_result.location != instance.location)
|
||||||
|
result['operations'].append(operation_data)
|
||||||
for block in oss.blocks().order_by('pk'):
|
for block in oss.blocks().order_by('pk'):
|
||||||
result['blocks'].append(BlockSerializer(block).data)
|
result['blocks'].append(BlockSerializer(block).data)
|
||||||
for argument in oss.arguments().order_by('order'):
|
for argument in oss.arguments().order_by('order'):
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
* Module: OSS data loading and processing.
|
* Module: OSS data loading and processing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { type ILibraryItem } from '@/features/library';
|
|
||||||
|
|
||||||
import { Graph } from '@/models/graph';
|
import { Graph } from '@/models/graph';
|
||||||
import { type RO } from '@/utils/meta';
|
import { type RO } from '@/utils/meta';
|
||||||
|
|
||||||
|
@ -29,11 +27,9 @@ export class OssLoader {
|
||||||
private itemByNodeID = new Map<string, IOssItem>();
|
private itemByNodeID = new Map<string, IOssItem>();
|
||||||
private blockByID = new Map<number, IBlock>();
|
private blockByID = new Map<number, IBlock>();
|
||||||
private schemaIDs: number[] = [];
|
private schemaIDs: number[] = [];
|
||||||
private items: RO<ILibraryItem[]>;
|
|
||||||
|
|
||||||
constructor(input: RO<IOperationSchemaDTO>, items: RO<ILibraryItem[]>) {
|
constructor(input: RO<IOperationSchemaDTO>) {
|
||||||
this.oss = structuredClone(input) as IOperationSchema;
|
this.oss = structuredClone(input) as IOperationSchema;
|
||||||
this.items = items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
produceOSS(): IOperationSchema {
|
produceOSS(): IOperationSchema {
|
||||||
|
@ -89,12 +85,10 @@ export class OssLoader {
|
||||||
private inferOperationAttributes() {
|
private inferOperationAttributes() {
|
||||||
this.graph.topologicalOrder().forEach(operationID => {
|
this.graph.topologicalOrder().forEach(operationID => {
|
||||||
const operation = this.operationByID.get(operationID)!;
|
const operation = this.operationByID.get(operationID)!;
|
||||||
const schema = this.items.find(item => item.id === operation.result);
|
|
||||||
const position = this.oss.layout.find(item => item.nodeID === operation.nodeID);
|
const position = this.oss.layout.find(item => item.nodeID === operation.nodeID);
|
||||||
operation.x = position?.x ?? 0;
|
operation.x = position?.x ?? 0;
|
||||||
operation.y = position?.y ?? 0;
|
operation.y = position?.y ?? 0;
|
||||||
operation.is_consolidation = this.inferConsolidation(operationID);
|
operation.is_consolidation = this.inferConsolidation(operationID);
|
||||||
operation.is_owned = !schema || (schema.owner === this.oss.owner && schema.location === this.oss.location);
|
|
||||||
operation.substitutions = this.oss.substitutions.filter(item => item.operation === operationID);
|
operation.substitutions = this.oss.substitutions.filter(item => item.operation === operationID);
|
||||||
operation.arguments = this.oss.arguments
|
operation.arguments = this.oss.arguments
|
||||||
.filter(item => item.operation === operationID)
|
.filter(item => item.operation === operationID)
|
||||||
|
@ -132,7 +126,7 @@ export class OssLoader {
|
||||||
count_inputs: operations.filter(item => item.operation_type === OperationType.INPUT).length,
|
count_inputs: operations.filter(item => item.operation_type === OperationType.INPUT).length,
|
||||||
count_synthesis: operations.filter(item => item.operation_type === OperationType.SYNTHESIS).length,
|
count_synthesis: operations.filter(item => item.operation_type === OperationType.SYNTHESIS).length,
|
||||||
count_schemas: this.schemaIDs.length,
|
count_schemas: this.schemaIDs.length,
|
||||||
count_owned: operations.filter(item => !!item.result && item.is_owned).length,
|
count_owned: operations.filter(item => !!item.result && !item.is_import).length,
|
||||||
count_block: this.oss.blocks.length
|
count_block: this.oss.blocks.length
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ export const schemaOperation = z.strictObject({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
parent: z.number().nullable(),
|
parent: z.number().nullable(),
|
||||||
|
is_import: z.boolean(),
|
||||||
result: z.number().nullable()
|
result: z.number().nullable()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,24 @@
|
||||||
import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
|
import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useLibrary, useLibrarySuspense } from '@/features/library/backend/use-library';
|
|
||||||
|
|
||||||
import { queryClient } from '@/backend/query-client';
|
import { queryClient } from '@/backend/query-client';
|
||||||
|
|
||||||
import { ossApi } from './api';
|
import { ossApi } from './api';
|
||||||
import { OssLoader } from './oss-loader';
|
import { OssLoader } from './oss-loader';
|
||||||
|
|
||||||
export function useOss({ itemID }: { itemID?: number }) {
|
export function useOss({ itemID }: { itemID?: number }) {
|
||||||
const { items: libraryItems, isLoading: libraryLoading } = useLibrary();
|
|
||||||
const { data, isLoading, error } = useQuery({
|
const { data, isLoading, error } = useQuery({
|
||||||
...ossApi.getOssQueryOptions({ itemID })
|
...ossApi.getOssQueryOptions({ itemID })
|
||||||
});
|
});
|
||||||
|
|
||||||
const schema = data && !libraryLoading ? new OssLoader(data, libraryItems).produceOSS() : undefined;
|
const schema = data ? new OssLoader(data).produceOSS() : undefined;
|
||||||
return { schema: schema, isLoading: isLoading || libraryLoading, error: error };
|
return { schema: schema, isLoading: isLoading, error: error };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useOssSuspense({ itemID }: { itemID: number }) {
|
export function useOssSuspense({ itemID }: { itemID: number }) {
|
||||||
const { items: libraryItems } = useLibrarySuspense();
|
|
||||||
const { data } = useSuspenseQuery({
|
const { data } = useSuspenseQuery({
|
||||||
...ossApi.getOssQueryOptions({ itemID })
|
...ossApi.getOssQueryOptions({ itemID })
|
||||||
});
|
});
|
||||||
const schema = new OssLoader(data!, libraryItems).produceOSS();
|
const schema = new OssLoader(data!).produceOSS();
|
||||||
return { schema };
|
return { schema };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ export function InfoOperation({ operation }: InfoOperationProps) {
|
||||||
<p>
|
<p>
|
||||||
<b>Тип:</b> {labelOperationType(operation.operation_type)}
|
<b>Тип:</b> {labelOperationType(operation.operation_type)}
|
||||||
</p>
|
</p>
|
||||||
{!operation.is_owned ? (
|
{operation.is_import ? (
|
||||||
<p>
|
<p>
|
||||||
<b>КС не принадлежит ОСС</b>
|
<b>КС не принадлежит ОСС</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -68,13 +68,13 @@ export function DlgDeleteOperation() {
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label='Удалить схему'
|
label='Удалить схему'
|
||||||
titleHtml={
|
titleHtml={
|
||||||
!target.is_owned || target.result === null
|
target.is_import || target.result === null
|
||||||
? 'Привязанную схему нельзя удалить'
|
? 'Привязанную схему нельзя удалить'
|
||||||
: 'Удалить схему вместе с операцией'
|
: 'Удалить схему вместе с операцией'
|
||||||
}
|
}
|
||||||
value={field.value}
|
value={field.value}
|
||||||
onChange={field.onChange}
|
onChange={field.onChange}
|
||||||
disabled={!target.is_owned || target.result === null}
|
disabled={target.is_import || target.result === null}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -24,7 +24,7 @@ export interface IOperation extends IOperationDTO {
|
||||||
nodeType: typeof NodeType.OPERATION;
|
nodeType: typeof NodeType.OPERATION;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
is_owned: boolean;
|
is_import: boolean;
|
||||||
is_consolidation: boolean; // aka 'diamond synthesis'
|
is_consolidation: boolean; // aka 'diamond synthesis'
|
||||||
substitutions: ICstSubstituteInfo[];
|
substitutions: ICstSubstituteInfo[];
|
||||||
arguments: number[];
|
arguments: number[];
|
||||||
|
|
|
@ -70,8 +70,8 @@ export function NodeCore({ node }: NodeCoreProps) {
|
||||||
<div className='absolute top-[3px] right-1/2 translate-x-1/2 border-t w-[30px]' />
|
<div className='absolute top-[3px] right-1/2 translate-x-1/2 border-t w-[30px]' />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{!node.data.operation.is_owned ? (
|
{node.data.operation.is_import ? (
|
||||||
<div className='absolute left-[2px] top-[6px] border-r rounded-none bg-input h-[22px]' />
|
<div className='absolute left-[3px] top-1/2 -translate-y-1/2 border-r rounded-none bg-input h-[22px]' />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -16,7 +16,7 @@ export function BlockStats({ target, oss }: BlockStatsProps) {
|
||||||
count_inputs: operations.filter(item => item.operation_type === OperationType.INPUT).length,
|
count_inputs: operations.filter(item => item.operation_type === OperationType.INPUT).length,
|
||||||
count_synthesis: operations.filter(item => item.operation_type === OperationType.SYNTHESIS).length,
|
count_synthesis: operations.filter(item => item.operation_type === OperationType.SYNTHESIS).length,
|
||||||
count_schemas: operations.filter(item => !!item.result).length,
|
count_schemas: operations.filter(item => !!item.result).length,
|
||||||
count_owned: operations.filter(item => !!item.result && item.is_owned).length,
|
count_owned: operations.filter(item => !!item.result && !item.is_import).length,
|
||||||
count_block: contents.length - operations.length
|
count_block: contents.length - operations.length
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ export function SidePanel({ isMounted, className }: SidePanelProps) {
|
||||||
<div className='text-center text-sm cc-fade-in'>Отсутствует концептуальная схема для выбранной операции</div>
|
<div className='text-center text-sm cc-fade-in'>Отсутствует концептуальная схема для выбранной операции</div>
|
||||||
) : selectedOperation && selectedSchema && debouncedMounted ? (
|
) : selectedOperation && selectedSchema && debouncedMounted ? (
|
||||||
<Suspense fallback={<Loader />}>
|
<Suspense fallback={<Loader />}>
|
||||||
<ViewSchema schemaID={selectedSchema} isMutable={isMutable && selectedOperation.is_owned} />
|
<ViewSchema schemaID={selectedSchema} isMutable={isMutable && !selectedOperation.is_import} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
) : null}
|
) : null}
|
||||||
{selectedBlock ? <BlockStats target={selectedBlock} oss={schema} /> : null}
|
{selectedBlock ? <BlockStats target={selectedBlock} oss={schema} /> : null}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user