1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
|||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
.zed
|
.zed
|
||||||
|
.history
|
||||||
upload
|
upload
|
||||||
*.exe
|
*.exe
|
||||||
*.db
|
*.db
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import {
|
|||||||
TextArea,
|
TextArea,
|
||||||
Typography,
|
Typography,
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import { IconDelete, IconPlus } from '@douyinfe/semi-icons';
|
import { IconDelete, IconMenu, IconPlus } from '@douyinfe/semi-icons';
|
||||||
import { copy, showError, showSuccess, verifyJSON } from '../../../../helpers';
|
import { copy, showError, showSuccess, verifyJSON } from '../../../../helpers';
|
||||||
import {
|
import {
|
||||||
CLAUDE_CLI_HEADER_PASSTHROUGH_TEMPLATE,
|
CLAUDE_CLI_HEADER_PASSTHROUGH_TEMPLATE,
|
||||||
@@ -800,6 +800,38 @@ const normalizeOperation = (operation = {}) => ({
|
|||||||
|
|
||||||
const createDefaultOperation = () => normalizeOperation({ mode: 'set' });
|
const createDefaultOperation = () => normalizeOperation({ mode: 'set' });
|
||||||
|
|
||||||
|
const reorderOperations = (
|
||||||
|
sourceOperations = [],
|
||||||
|
sourceId,
|
||||||
|
targetId,
|
||||||
|
position = 'before',
|
||||||
|
) => {
|
||||||
|
if (!sourceId || !targetId || sourceId === targetId) {
|
||||||
|
return sourceOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sourceIndex = sourceOperations.findIndex((item) => item.id === sourceId);
|
||||||
|
|
||||||
|
if (sourceIndex < 0) {
|
||||||
|
return sourceOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextOperations = [...sourceOperations];
|
||||||
|
const [moved] = nextOperations.splice(sourceIndex, 1);
|
||||||
|
let insertIndex = nextOperations.findIndex((item) => item.id === targetId);
|
||||||
|
|
||||||
|
if (insertIndex < 0) {
|
||||||
|
return sourceOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position === 'after') {
|
||||||
|
insertIndex += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextOperations.splice(insertIndex, 0, moved);
|
||||||
|
return nextOperations;
|
||||||
|
};
|
||||||
|
|
||||||
const getOperationSummary = (operation = {}, index = 0) => {
|
const getOperationSummary = (operation = {}, index = 0) => {
|
||||||
const mode = operation.mode || 'set';
|
const mode = operation.mode || 'set';
|
||||||
const modeLabel = OPERATION_MODE_LABEL_MAP[mode] || mode;
|
const modeLabel = OPERATION_MODE_LABEL_MAP[mode] || mode;
|
||||||
@@ -1037,6 +1069,9 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
|
|||||||
const [operationSearch, setOperationSearch] = useState('');
|
const [operationSearch, setOperationSearch] = useState('');
|
||||||
const [selectedOperationId, setSelectedOperationId] = useState('');
|
const [selectedOperationId, setSelectedOperationId] = useState('');
|
||||||
const [expandedConditionMap, setExpandedConditionMap] = useState({});
|
const [expandedConditionMap, setExpandedConditionMap] = useState({});
|
||||||
|
const [draggedOperationId, setDraggedOperationId] = useState('');
|
||||||
|
const [dragOverOperationId, setDragOverOperationId] = useState('');
|
||||||
|
const [dragOverPosition, setDragOverPosition] = useState('before');
|
||||||
const [templateGroupKey, setTemplateGroupKey] = useState('basic');
|
const [templateGroupKey, setTemplateGroupKey] = useState('basic');
|
||||||
const [templatePresetKey, setTemplatePresetKey] = useState('operations_default');
|
const [templatePresetKey, setTemplatePresetKey] = useState('operations_default');
|
||||||
const [fieldGuideVisible, setFieldGuideVisible] = useState(false);
|
const [fieldGuideVisible, setFieldGuideVisible] = useState(false);
|
||||||
@@ -1055,6 +1090,9 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
|
|||||||
setOperationSearch('');
|
setOperationSearch('');
|
||||||
setSelectedOperationId(nextState.operations[0]?.id || '');
|
setSelectedOperationId(nextState.operations[0]?.id || '');
|
||||||
setExpandedConditionMap({});
|
setExpandedConditionMap({});
|
||||||
|
setDraggedOperationId('');
|
||||||
|
setDragOverOperationId('');
|
||||||
|
setDragOverPosition('before');
|
||||||
if (nextState.visualMode === 'legacy') {
|
if (nextState.visualMode === 'legacy') {
|
||||||
setTemplateGroupKey('basic');
|
setTemplateGroupKey('basic');
|
||||||
setTemplatePresetKey('legacy_default');
|
setTemplatePresetKey('legacy_default');
|
||||||
@@ -1583,6 +1621,67 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
|
|||||||
setSelectedOperationId(created.id);
|
setSelectedOperationId(created.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resetOperationDragState = useCallback(() => {
|
||||||
|
setDraggedOperationId('');
|
||||||
|
setDragOverOperationId('');
|
||||||
|
setDragOverPosition('before');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const moveOperation = useCallback(
|
||||||
|
(sourceId, targetId, position = 'before') => {
|
||||||
|
if (!sourceId || !targetId || sourceId === targetId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setOperations((prev) =>
|
||||||
|
reorderOperations(prev, sourceId, targetId, position),
|
||||||
|
);
|
||||||
|
setSelectedOperationId(sourceId);
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOperationDragStart = useCallback((event, operationId) => {
|
||||||
|
setDraggedOperationId(operationId);
|
||||||
|
setSelectedOperationId(operationId);
|
||||||
|
event.dataTransfer.effectAllowed = 'move';
|
||||||
|
event.dataTransfer.setData('text/plain', operationId);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleOperationDragOver = useCallback(
|
||||||
|
(event, operationId) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (!draggedOperationId || draggedOperationId === operationId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rect = event.currentTarget.getBoundingClientRect();
|
||||||
|
const position =
|
||||||
|
event.clientY - rect.top > rect.height / 2 ? 'after' : 'before';
|
||||||
|
setDragOverOperationId(operationId);
|
||||||
|
setDragOverPosition(position);
|
||||||
|
event.dataTransfer.dropEffect = 'move';
|
||||||
|
},
|
||||||
|
[draggedOperationId],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOperationDrop = useCallback(
|
||||||
|
(event, operationId) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const sourceId =
|
||||||
|
draggedOperationId || event.dataTransfer.getData('text/plain');
|
||||||
|
const position =
|
||||||
|
dragOverOperationId === operationId ? dragOverPosition : 'before';
|
||||||
|
moveOperation(sourceId, operationId, position);
|
||||||
|
resetOperationDragState();
|
||||||
|
},
|
||||||
|
[
|
||||||
|
dragOverOperationId,
|
||||||
|
dragOverPosition,
|
||||||
|
draggedOperationId,
|
||||||
|
moveOperation,
|
||||||
|
resetOperationDragState,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
const duplicateOperation = (operationId) => {
|
const duplicateOperation = (operationId) => {
|
||||||
let insertedId = '';
|
let insertedId = '';
|
||||||
setOperations((prev) => {
|
setOperations((prev) => {
|
||||||
@@ -1941,14 +2040,31 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
|
|||||||
);
|
);
|
||||||
const isActive =
|
const isActive =
|
||||||
operation.id === selectedOperationId;
|
operation.id === selectedOperationId;
|
||||||
|
const isDragging =
|
||||||
|
operation.id === draggedOperationId;
|
||||||
|
const isDropTarget =
|
||||||
|
operation.id === dragOverOperationId &&
|
||||||
|
draggedOperationId &&
|
||||||
|
draggedOperationId !== operation.id;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={operation.id}
|
key={operation.id}
|
||||||
role='button'
|
role='button'
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
|
draggable={operations.length > 1}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setSelectedOperationId(operation.id)
|
setSelectedOperationId(operation.id)
|
||||||
}
|
}
|
||||||
|
onDragStart={(event) =>
|
||||||
|
handleOperationDragStart(event, operation.id)
|
||||||
|
}
|
||||||
|
onDragOver={(event) =>
|
||||||
|
handleOperationDragOver(event, operation.id)
|
||||||
|
}
|
||||||
|
onDrop={(event) =>
|
||||||
|
handleOperationDrop(event, operation.id)
|
||||||
|
}
|
||||||
|
onDragEnd={resetOperationDragState}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (
|
if (
|
||||||
event.key === 'Enter' ||
|
event.key === 'Enter' ||
|
||||||
@@ -1966,35 +2082,53 @@ const ParamOverrideEditorModal = ({ visible, value, onSave, onCancel }) => {
|
|||||||
border: isActive
|
border: isActive
|
||||||
? '1px solid var(--semi-color-primary)'
|
? '1px solid var(--semi-color-primary)'
|
||||||
: '1px solid var(--semi-color-border)',
|
: '1px solid var(--semi-color-border)',
|
||||||
|
opacity: isDragging ? 0.6 : 1,
|
||||||
|
boxShadow: isDropTarget
|
||||||
|
? dragOverPosition === 'after'
|
||||||
|
? 'inset 0 -3px 0 var(--semi-color-primary)'
|
||||||
|
: 'inset 0 3px 0 var(--semi-color-primary)'
|
||||||
|
: 'none',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='flex items-start justify-between gap-2'>
|
<div className='flex items-start justify-between gap-2'>
|
||||||
<div>
|
<div className='flex items-start gap-2 min-w-0'>
|
||||||
<Text strong>{`#${index + 1}`}</Text>
|
<div
|
||||||
<Text
|
className='flex-shrink-0'
|
||||||
type='tertiary'
|
style={{
|
||||||
size='small'
|
color: 'var(--semi-color-text-2)',
|
||||||
className='block mt-1'
|
cursor: operations.length > 1 ? 'grab' : 'default',
|
||||||
|
marginTop: 1,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{getOperationSummary(operation, index)}
|
<IconMenu />
|
||||||
</Text>
|
</div>
|
||||||
{String(operation.description || '').trim() ? (
|
<div className='min-w-0'>
|
||||||
|
<Text strong>{`#${index + 1}`}</Text>
|
||||||
<Text
|
<Text
|
||||||
type='tertiary'
|
type='tertiary'
|
||||||
size='small'
|
size='small'
|
||||||
className='block mt-1'
|
className='block mt-1'
|
||||||
style={{
|
|
||||||
lineHeight: 1.5,
|
|
||||||
wordBreak: 'break-word',
|
|
||||||
overflow: 'hidden',
|
|
||||||
display: '-webkit-box',
|
|
||||||
WebkitLineClamp: 2,
|
|
||||||
WebkitBoxOrient: 'vertical',
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{operation.description}
|
{getOperationSummary(operation, index)}
|
||||||
</Text>
|
</Text>
|
||||||
) : null}
|
{String(operation.description || '').trim() ? (
|
||||||
|
<Text
|
||||||
|
type='tertiary'
|
||||||
|
size='small'
|
||||||
|
className='block mt-1'
|
||||||
|
style={{
|
||||||
|
lineHeight: 1.5,
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
overflow: 'hidden',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitLineClamp: 2,
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{operation.description}
|
||||||
|
</Text>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Tag size='small' color='grey'>
|
<Tag size='small' color='grey'>
|
||||||
{(operation.conditions || []).length}
|
{(operation.conditions || []).length}
|
||||||
|
|||||||
Reference in New Issue
Block a user