Compare commits
3 Commits
25029a212b
...
b3c8b217c0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b3c8b217c0 | ||
![]() |
afe3ec0adb | ||
![]() |
a4e2d2c25f |
|
@ -361,6 +361,11 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
|||
model = self._get_item()
|
||||
load_metadata = input_serializer.validated_data['load_metadata']
|
||||
data = utility.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME)
|
||||
if data is None:
|
||||
return Response(
|
||||
status=c.HTTP_400_BAD_REQUEST,
|
||||
data={'file': msg.exteorFileCorrupted()}
|
||||
)
|
||||
data['id'] = model.pk
|
||||
|
||||
serializer = s.RSFormTRSSerializer(
|
||||
|
@ -486,11 +491,17 @@ class TrsImportView(views.APIView):
|
|||
request=s.FileSerializer,
|
||||
responses={
|
||||
c.HTTP_201_CREATED: LibraryItemSerializer,
|
||||
c.HTTP_400_BAD_REQUEST: None,
|
||||
c.HTTP_403_FORBIDDEN: None
|
||||
}
|
||||
)
|
||||
def post(self, request: Request) -> HttpResponse:
|
||||
data = utility.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME)
|
||||
if data is None:
|
||||
return Response(
|
||||
status=c.HTTP_400_BAD_REQUEST,
|
||||
data={'file': msg.exteorFileCorrupted()}
|
||||
)
|
||||
owner = cast(User, self.request.user)
|
||||
_prepare_rsform_data(data, request, owner)
|
||||
serializer = s.RSFormTRSSerializer(
|
||||
|
@ -526,6 +537,11 @@ def create_rsform(request: Request) -> HttpResponse:
|
|||
)
|
||||
|
||||
data = utility.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME)
|
||||
if data is None:
|
||||
return Response(
|
||||
status=c.HTTP_400_BAD_REQUEST,
|
||||
data={'file': msg.exteorFileCorrupted()}
|
||||
)
|
||||
_prepare_rsform_data(data, request, owner)
|
||||
serializer_rsform = s.RSFormTRSSerializer(data=data, context={'load_meta': True})
|
||||
serializer_rsform.is_valid(raise_exception=True)
|
||||
|
|
|
@ -14,6 +14,10 @@ def operationNotInOSS(title: str):
|
|||
return f'Операция не принадлежит ОСС: {title}'
|
||||
|
||||
|
||||
def exteorFileCorrupted():
|
||||
return 'Файл Экстеор не соответствует ожидаемому формату. Попробуйте сохранить файл в новой версии'
|
||||
|
||||
|
||||
def previousResultMissing():
|
||||
return 'Отсутствует результат предыдущей операции'
|
||||
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
''' Utility functions. '''
|
||||
import json
|
||||
from io import BytesIO
|
||||
from zipfile import ZipFile
|
||||
from typing import Optional
|
||||
from zipfile import BadZipFile, ZipFile
|
||||
|
||||
|
||||
def read_zipped_json(data, json_filename: str) -> dict:
|
||||
''' Read JSON from zipped data '''
|
||||
with ZipFile(data, 'r') as archive:
|
||||
json_data = archive.read(json_filename)
|
||||
def read_zipped_json(data, json_filename: str) -> Optional[dict]:
|
||||
''' Read JSON from zipped data. '''
|
||||
try:
|
||||
with ZipFile(data, 'r') as archive:
|
||||
json_data = archive.read(json_filename)
|
||||
except BadZipFile:
|
||||
return None
|
||||
result: dict = json.loads(json_data)
|
||||
return result
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ function TextInput({
|
|||
<input
|
||||
id={id}
|
||||
className={clsx(
|
||||
'py-2',
|
||||
'min-w-0 py-2',
|
||||
'leading-tight truncate hover:text-clip',
|
||||
{
|
||||
'px-3': !noBorder || !disabled,
|
||||
|
|
|
@ -62,7 +62,7 @@ function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreat
|
|||
id='dlg_cst_alias'
|
||||
dense
|
||||
label='Имя'
|
||||
className='w-[7rem] mr-8'
|
||||
className='w-[7rem]'
|
||||
value={state.alias}
|
||||
onChange={event => partialUpdate({ alias: event.target.value })}
|
||||
/>
|
||||
|
|
|
@ -46,7 +46,7 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
|
|||
hideWindow={hideWindow}
|
||||
canSubmit={validated}
|
||||
onSubmit={() => onRename(cstData)}
|
||||
className={clsx('w-[30rem]', 'py-6 pr-3 pl-6 flex justify-center items-center')}
|
||||
className={clsx('w-[30rem]', 'py-6 pr-3 pl-6 flex gap-3 justify-center items-center')}
|
||||
>
|
||||
<SelectSingle
|
||||
id='dlg_cst_type'
|
||||
|
@ -64,7 +64,7 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
|
|||
id='dlg_cst_alias'
|
||||
dense
|
||||
label='Имя'
|
||||
className='w-[7rem] ml-3'
|
||||
className='w-[7rem]'
|
||||
value={cstData.alias}
|
||||
onChange={event => updateData({ alias: event.target.value })}
|
||||
/>
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
'use client';
|
||||
|
||||
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||
import { useCallback, useLayoutEffect, useMemo } from 'react';
|
||||
|
||||
import BadgeConstituenta from '@/components/info/BadgeConstituenta';
|
||||
import DataTable, { createColumnHelper, IConditionalStyle, VisibilityState } from '@/components/ui/DataTable';
|
||||
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
|
||||
import NoData from '@/components/ui/NoData';
|
||||
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||
import useWindowSize from '@/hooks/useWindowSize';
|
||||
import { ConstituentaID, IConstituenta } from '@/models/rsform';
|
||||
import { isMockCst } from '@/models/rsformAPI';
|
||||
import { PARAMETER, prefixes } from '@/utils/constants';
|
||||
|
@ -16,7 +15,6 @@ interface TableSideConstituentsProps {
|
|||
items: IConstituenta[];
|
||||
activeCst?: IConstituenta;
|
||||
onOpenEdit: (cstID: ConstituentaID) => void;
|
||||
denseThreshold?: number;
|
||||
autoScroll?: boolean;
|
||||
maxHeight: string;
|
||||
}
|
||||
|
@ -28,13 +26,9 @@ function TableSideConstituents({
|
|||
activeCst,
|
||||
autoScroll = true,
|
||||
onOpenEdit,
|
||||
maxHeight,
|
||||
denseThreshold = 9999
|
||||
maxHeight
|
||||
}: TableSideConstituentsProps) {
|
||||
const { colors } = useConceptOptions();
|
||||
const windowSize = useWindowSize();
|
||||
|
||||
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({ expression: true });
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!activeCst) {
|
||||
|
@ -54,17 +48,6 @@ function TableSideConstituents({
|
|||
}
|
||||
}, [activeCst, autoScroll]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setColumnVisibility(prev => {
|
||||
const newValue = (windowSize.width ?? 0) >= denseThreshold;
|
||||
if (newValue === prev.expression) {
|
||||
return prev;
|
||||
} else {
|
||||
return { expression: newValue };
|
||||
}
|
||||
});
|
||||
}, [windowSize, denseThreshold]);
|
||||
|
||||
const handleRowClicked = useCallback(
|
||||
(cst: IConstituenta) => {
|
||||
if (!isMockCst(cst)) {
|
||||
|
@ -103,25 +86,6 @@ function TableSideConstituents({
|
|||
{props.getValue()}
|
||||
</div>
|
||||
)
|
||||
}),
|
||||
columnHelper.accessor('definition_formal', {
|
||||
id: 'expression',
|
||||
header: 'Выражение',
|
||||
size: 2000,
|
||||
minSize: 0,
|
||||
maxSize: 2000,
|
||||
enableHiding: true,
|
||||
cell: props => (
|
||||
<div
|
||||
style={{
|
||||
textWrap: 'pretty',
|
||||
fontSize: 12,
|
||||
color: isMockCst(props.row.original) ? colors.fgWarning : undefined
|
||||
}}
|
||||
>
|
||||
{props.getValue()}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
],
|
||||
[colors]
|
||||
|
@ -162,8 +126,6 @@ function TableSideConstituents({
|
|||
conditionalRowStyles={conditionalRowStyles}
|
||||
headPosition='0'
|
||||
enableHiding
|
||||
columnVisibility={columnVisibility}
|
||||
onColumnVisibilityChange={setColumnVisibility}
|
||||
noDataComponent={
|
||||
<NoData className='min-h-[5rem]'>
|
||||
<p>Список конституент пуст</p>
|
||||
|
|
|
@ -14,9 +14,6 @@ import { animateSideView } from '@/styling/animations';
|
|||
import ConstituentsSearch from './ConstituentsSearch';
|
||||
import TableSideConstituents from './TableSideConstituents';
|
||||
|
||||
// Window width cutoff for expression show
|
||||
const COLUMN_EXPRESSION_HIDE_THRESHOLD = 1500;
|
||||
|
||||
// Window width cutoff for dense search bar
|
||||
const COLUMN_DENSE_SEARCH_THRESHOLD = 1100;
|
||||
|
||||
|
@ -47,7 +44,6 @@ function ViewConstituents({ expression, schema, activeCst, isBottom, onOpenEdit
|
|||
activeCst={activeCst}
|
||||
onOpenEdit={onOpenEdit}
|
||||
autoScroll={!isBottom}
|
||||
denseThreshold={COLUMN_EXPRESSION_HIDE_THRESHOLD}
|
||||
/>
|
||||
),
|
||||
[isBottom, filteredData, activeCst, onOpenEdit, calculateHeight, accessLevel]
|
||||
|
|
Loading…
Reference in New Issue
Block a user