mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Refactor constituenta move functionality
This commit is contained in:
parent
2b7a4c04ce
commit
a5f3539798
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { BiDuplicate, BiPlusCircle, BiReset, BiTrash } from 'react-icons/bi';
|
||||
import { BiDownvote, BiDuplicate, BiPlusCircle, BiReset, BiTrash, BiUpvote } from 'react-icons/bi';
|
||||
import { FiSave } from 'react-icons/fi';
|
||||
|
||||
import HelpButton from '@/components/Help/HelpButton';
|
||||
|
@ -16,6 +16,8 @@ interface ConstituentaToolbarProps {
|
|||
onSubmit: () => void;
|
||||
onReset: () => void;
|
||||
|
||||
onMoveUp: () => void;
|
||||
onMoveDown: () => void;
|
||||
onDelete: () => void;
|
||||
onClone: () => void;
|
||||
onCreate: () => void;
|
||||
|
@ -26,6 +28,8 @@ function ConstituentaToolbar({
|
|||
isModified,
|
||||
onSubmit,
|
||||
onReset,
|
||||
onMoveUp,
|
||||
onMoveDown,
|
||||
onDelete,
|
||||
onClone,
|
||||
onCreate
|
||||
|
@ -63,6 +67,18 @@ function ConstituentaToolbar({
|
|||
onClick={onDelete}
|
||||
icon={<BiTrash size='1.25rem' className={isMutable ? 'clr-text-warning' : ''} />}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Переместить вверх [Alt + вверх]'
|
||||
icon={<BiUpvote size='1.25rem' className={isMutable ? 'clr-text-primary' : ''} />}
|
||||
disabled={!isMutable}
|
||||
onClick={onMoveUp}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Переместить вниз [Alt + вниз]'
|
||||
icon={<BiDownvote size='1.25rem' className={isMutable ? 'clr-text-primary' : ''} />}
|
||||
disabled={!isMutable}
|
||||
onClick={onMoveDown}
|
||||
/>
|
||||
<HelpButton topic={HelpTopic.CONSTITUENTA} offset={4} />
|
||||
</Overlay>
|
||||
);
|
||||
|
|
|
@ -26,6 +26,8 @@ interface EditorConstituentaProps {
|
|||
isModified: boolean;
|
||||
setIsModified: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
|
||||
onMoveUp: () => void;
|
||||
onMoveDown: () => void;
|
||||
onOpenEdit: (cstID: number) => void;
|
||||
onClone: () => void;
|
||||
onCreate: (type?: CstType) => void;
|
||||
|
@ -40,11 +42,13 @@ function EditorConstituenta({
|
|||
isModified,
|
||||
setIsModified,
|
||||
activeCst,
|
||||
onEditTerm,
|
||||
onMoveUp,
|
||||
onMoveDown,
|
||||
onOpenEdit,
|
||||
onClone,
|
||||
onCreate,
|
||||
onRename,
|
||||
onOpenEdit,
|
||||
onEditTerm,
|
||||
onDelete
|
||||
}: EditorConstituentaProps) {
|
||||
const windowSize = useWindowSize();
|
||||
|
@ -99,6 +103,8 @@ function EditorConstituenta({
|
|||
<ConstituentaToolbar
|
||||
isMutable={!disabled}
|
||||
isModified={isModified}
|
||||
onMoveUp={onMoveUp}
|
||||
onMoveDown={onMoveDown}
|
||||
onSubmit={initiateSubmit}
|
||||
onReset={() => setToggleReset(prev => !prev)}
|
||||
onDelete={onDelete}
|
||||
|
|
|
@ -4,16 +4,18 @@ import { useLayoutEffect, useState } from 'react';
|
|||
|
||||
import { type RowSelectionState } from '@/components/DataTable';
|
||||
import SelectedCounter from '@/components/SelectedCounter';
|
||||
import { useRSForm } from '@/context/RSFormContext';
|
||||
import { CstType, ICstMovetoData } from '@/models/rsform';
|
||||
import { CstType, IRSForm } from '@/models/rsform';
|
||||
|
||||
import RSListToolbar from './RSListToolbar';
|
||||
import RSTable from './RSTable';
|
||||
|
||||
interface EditorRSListProps {
|
||||
schema?: IRSForm;
|
||||
isMutable: boolean;
|
||||
selected: number[];
|
||||
setSelected: React.Dispatch<React.SetStateAction<number[]>>;
|
||||
onMoveUp: () => void;
|
||||
onMoveDown: () => void;
|
||||
onOpenEdit: (cstID: number) => void;
|
||||
onClone: () => void;
|
||||
onCreate: (type?: CstType) => void;
|
||||
|
@ -21,16 +23,17 @@ interface EditorRSListProps {
|
|||
}
|
||||
|
||||
function EditorRSList({
|
||||
schema,
|
||||
selected,
|
||||
setSelected,
|
||||
isMutable,
|
||||
onMoveUp,
|
||||
onMoveDown,
|
||||
onOpenEdit,
|
||||
onClone,
|
||||
onCreate,
|
||||
onDelete
|
||||
}: EditorRSListProps) {
|
||||
const { schema, cstMoveTo } = useRSForm();
|
||||
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||
|
||||
useLayoutEffect(() => {
|
||||
|
@ -60,52 +63,6 @@ function EditorRSList({
|
|||
}
|
||||
}
|
||||
|
||||
// Move selected cst up
|
||||
function handleMoveUp() {
|
||||
if (!schema?.items || selected.length === 0) {
|
||||
return;
|
||||
}
|
||||
const currentIndex = schema.items.reduce((prev, cst, index) => {
|
||||
if (!selected.includes(cst.id)) {
|
||||
return prev;
|
||||
} else if (prev === -1) {
|
||||
return index;
|
||||
}
|
||||
return Math.min(prev, index);
|
||||
}, -1);
|
||||
const target = Math.max(0, currentIndex - 1) + 1;
|
||||
const data = {
|
||||
items: selected,
|
||||
move_to: target
|
||||
};
|
||||
cstMoveTo(data);
|
||||
}
|
||||
|
||||
// Move selected cst down
|
||||
function handleMoveDown() {
|
||||
if (!schema?.items || selected.length === 0) {
|
||||
return;
|
||||
}
|
||||
let count = 0;
|
||||
const currentIndex = schema.items.reduce((prev, cst, index) => {
|
||||
if (!selected.includes(cst.id)) {
|
||||
return prev;
|
||||
} else {
|
||||
count += 1;
|
||||
if (prev === -1) {
|
||||
return index;
|
||||
}
|
||||
return Math.max(prev, index);
|
||||
}
|
||||
}, -1);
|
||||
const target = Math.min(schema.items.length - 1, currentIndex - count + 2) + 1;
|
||||
const data: ICstMovetoData = {
|
||||
items: selected,
|
||||
move_to: target
|
||||
};
|
||||
cstMoveTo(data);
|
||||
}
|
||||
|
||||
// Implement hotkeys for working with constituents table
|
||||
function handleTableKey(event: React.KeyboardEvent<HTMLDivElement>) {
|
||||
if (!isMutable) {
|
||||
|
@ -129,8 +86,8 @@ function EditorRSList({
|
|||
if (selected.length > 0) {
|
||||
// prettier-ignore
|
||||
switch (code) {
|
||||
case 'ArrowUp': handleMoveUp(); return true;
|
||||
case 'ArrowDown': handleMoveDown(); return true;
|
||||
case 'ArrowUp': onMoveUp(); return true;
|
||||
case 'ArrowDown': onMoveDown(); return true;
|
||||
case 'KeyV': onClone(); return true;
|
||||
}
|
||||
}
|
||||
|
@ -161,8 +118,8 @@ function EditorRSList({
|
|||
<RSListToolbar
|
||||
selectedCount={selected.length}
|
||||
isMutable={isMutable}
|
||||
onMoveUp={handleMoveUp}
|
||||
onMoveDown={handleMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
onMoveDown={onMoveDown}
|
||||
onClone={onClone}
|
||||
onCreate={onCreate}
|
||||
onDelete={onDelete}
|
||||
|
|
|
@ -28,7 +28,15 @@ import DlgRenameCst from '@/dialogs/DlgRenameCst';
|
|||
import DlgUploadRSForm from '@/dialogs/DlgUploadRSForm';
|
||||
import useQueryStrings from '@/hooks/useQueryStrings';
|
||||
import { UserAccessMode } from '@/models/miscellaneous';
|
||||
import { CstType, IConstituenta, ICstCreateData, ICstRenameData, ICstUpdateData, TermForm } from '@/models/rsform';
|
||||
import {
|
||||
CstType,
|
||||
IConstituenta,
|
||||
ICstCreateData,
|
||||
ICstMovetoData,
|
||||
ICstRenameData,
|
||||
ICstUpdateData,
|
||||
TermForm
|
||||
} from '@/models/rsform';
|
||||
import { generateAlias } from '@/models/rsformAPI';
|
||||
import { EXTEOR_TRS_FILE, prefixes, TIMEOUT_UI_REFRESH } from '@/utils/constants';
|
||||
|
||||
|
@ -66,6 +74,7 @@ function RSTabs() {
|
|||
subscribe,
|
||||
unsubscribe,
|
||||
cstUpdate,
|
||||
cstMoveTo,
|
||||
resetAliases
|
||||
} = useRSForm();
|
||||
const { destroyItem } = useLibrary();
|
||||
|
@ -262,6 +271,52 @@ function RSTabs() {
|
|||
|
||||
const onReindex = useCallback(() => resetAliases(() => toast.success('Имена конституент обновлены')), [resetAliases]);
|
||||
|
||||
// Move selected cst up
|
||||
function handleMoveUp() {
|
||||
if (!schema?.items || selected.length === 0) {
|
||||
return;
|
||||
}
|
||||
const currentIndex = schema.items.reduce((prev, cst, index) => {
|
||||
if (!selected.includes(cst.id)) {
|
||||
return prev;
|
||||
} else if (prev === -1) {
|
||||
return index;
|
||||
}
|
||||
return Math.min(prev, index);
|
||||
}, -1);
|
||||
const target = Math.max(0, currentIndex - 1) + 1;
|
||||
const data = {
|
||||
items: selected,
|
||||
move_to: target
|
||||
};
|
||||
cstMoveTo(data);
|
||||
}
|
||||
|
||||
// Move selected cst down
|
||||
function handleMoveDown() {
|
||||
if (!schema?.items || selected.length === 0) {
|
||||
return;
|
||||
}
|
||||
let count = 0;
|
||||
const currentIndex = schema.items.reduce((prev, cst, index) => {
|
||||
if (!selected.includes(cst.id)) {
|
||||
return prev;
|
||||
} else {
|
||||
count += 1;
|
||||
if (prev === -1) {
|
||||
return index;
|
||||
}
|
||||
return Math.max(prev, index);
|
||||
}
|
||||
}, -1);
|
||||
const target = Math.min(schema.items.length - 1, currentIndex - count + 2) + 1;
|
||||
const data: ICstMovetoData = {
|
||||
items: selected,
|
||||
move_to: target
|
||||
};
|
||||
cstMoveTo(data);
|
||||
}
|
||||
|
||||
const handleDeleteCst = useCallback(
|
||||
(deleted: number[]) => {
|
||||
if (!schema) {
|
||||
|
@ -479,9 +534,12 @@ function RSTabs() {
|
|||
|
||||
<TabPanel forceRender style={{ display: activeTab === RSTabID.CST_LIST ? '' : 'none' }}>
|
||||
<EditorRSList
|
||||
schema={schema}
|
||||
selected={selected}
|
||||
setSelected={setSelected}
|
||||
isMutable={isMutable}
|
||||
onMoveUp={handleMoveUp}
|
||||
onMoveDown={handleMoveDown}
|
||||
onOpenEdit={onOpenCst}
|
||||
onClone={handleCloneCst}
|
||||
onCreate={type => promptCreateCst(type, type !== undefined)}
|
||||
|
@ -496,6 +554,8 @@ function RSTabs() {
|
|||
isModified={isModified}
|
||||
setIsModified={setIsModified}
|
||||
activeCst={activeCst}
|
||||
onMoveUp={handleMoveUp}
|
||||
onMoveDown={handleMoveDown}
|
||||
onOpenEdit={onOpenCst}
|
||||
onClone={handleCloneCst}
|
||||
onCreate={type => promptCreateCst(type, false)}
|
||||
|
|
Loading…
Reference in New Issue
Block a user