file structure and comments unified
Some checks failed
Build and Deploy MITM Webserver / build (push) Failing after 3s
Some checks failed
Build and Deploy MITM Webserver / build (push) Failing after 3s
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
// src/pages/ScriptsManager.tsx
|
||||
import {
|
||||
DeleteOutlined,
|
||||
DownloadOutlined,
|
||||
@@ -65,49 +64,36 @@ const { Paragraph } = Typography;
|
||||
*/
|
||||
|
||||
export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (code: string) => void }) {
|
||||
// --------------------
|
||||
// State
|
||||
// --------------------
|
||||
const [scripts, setScripts] = useState<ScriptWithStatus[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// modals & editor values
|
||||
const [uploadModalVisible, setUploadModalVisible] = useState(false);
|
||||
const [editorModalVisible, setEditorModalVisible] = useState(false);
|
||||
const [editorValue, setEditorValue] = useState<string>('');
|
||||
const [currentEditingName, setCurrentEditingName] = useState<string | null>(null);
|
||||
|
||||
// inline requirements editor toggle + value for upload modal
|
||||
const [useInlineReqEditor, setUseInlineReqEditor] = useState(false);
|
||||
const [inlineReqValue, setInlineReqValue] = useState<string>('');
|
||||
|
||||
// pip output modal
|
||||
const [pipModalVisible, setPipModalVisible] = useState(false);
|
||||
const [pipOutput, setPipOutput] = useState<{ stdout?: string; stderr?: string } | null>(null);
|
||||
|
||||
// requirements editor modal (existing per-script editor)
|
||||
const [reqModalVisible, setReqModalVisible] = useState(false);
|
||||
const [reqEditorValue, setReqEditorValue] = useState<string>('');
|
||||
const [reqEditingName, setReqEditingName] = useState<string | null>(null);
|
||||
|
||||
// add-requirements modal (for scripts that have no requirements)
|
||||
const [addReqModalVisible, setAddReqModalVisible] = useState(false);
|
||||
const [addReqTarget, setAddReqTarget] = useState<string | null>(null);
|
||||
const [addReqUseInline, setAddReqUseInline] = useState(false);
|
||||
const [addReqInlineValue, setAddReqInlineValue] = useState('');
|
||||
const [addReqFile, setAddReqFile] = useState<File | null>(null);
|
||||
|
||||
// enable modal
|
||||
const [enableModalVisible, setEnableModalVisible] = useState(false);
|
||||
const [enableTarget, setEnableTarget] = useState<string | null>(null);
|
||||
|
||||
// forms
|
||||
const [form] = Form.useForm();
|
||||
const [enableForm] = Form.useForm();
|
||||
|
||||
// --------------------
|
||||
// Data fetch
|
||||
// --------------------
|
||||
const refreshAll = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
@@ -148,9 +134,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
refreshAll();
|
||||
}, [refreshAll]);
|
||||
|
||||
// --------------------
|
||||
// Helpers
|
||||
// --------------------
|
||||
const getMappingsForScript = useCallback(
|
||||
(scriptName: string) => {
|
||||
const s = scripts.find((x) => x.name === scriptName);
|
||||
@@ -171,7 +154,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
[scripts],
|
||||
);
|
||||
|
||||
// Focus helper: tries to find a textarea inside the modal and put caret at the end.
|
||||
const focusEditorInModal = useCallback((modalSelector = '.ant-modal') => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
@@ -184,7 +166,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
ta.setSelectionRange(val.length, val.length);
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, 80);
|
||||
}, []);
|
||||
@@ -205,7 +186,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
if (addReqModalVisible) focusEditorInModal('.ant-modal');
|
||||
}, [addReqModalVisible, focusEditorInModal]);
|
||||
|
||||
// show pip modal if pip output is present
|
||||
const showPipIfPresent = useCallback(
|
||||
(resp?: ScriptUploadResponse | { pip?: { stdout?: string; stderr?: string } } | null) => {
|
||||
const pip = (resp as any)?.pip;
|
||||
@@ -217,9 +197,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
[],
|
||||
);
|
||||
|
||||
// --------------------
|
||||
// API Handlers
|
||||
// --------------------
|
||||
const handleDownload = useCallback(async (name: string) => {
|
||||
try {
|
||||
const blob = await downloadScript(name);
|
||||
@@ -358,9 +335,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
[refreshAll],
|
||||
);
|
||||
|
||||
// --------------------
|
||||
// Upload handler (prefers file; falls back to inline editors)
|
||||
// --------------------
|
||||
const handleUpload = useCallback(
|
||||
async (formValues: any) => {
|
||||
const { name, scriptFile, requirementsFile } = formValues;
|
||||
@@ -369,10 +343,8 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
return;
|
||||
}
|
||||
|
||||
// script: prefer uploaded file; else use editorValue
|
||||
const script = scriptFile || new Blob([editorValue], { type: 'text/x-python' });
|
||||
|
||||
// requirements: prefer uploaded file; else use inlineReqValue if toggle enabled; else null
|
||||
let req: File | Blob | null = null;
|
||||
if (requirementsFile) {
|
||||
req = requirementsFile;
|
||||
@@ -476,10 +448,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
[refreshAll],
|
||||
);
|
||||
|
||||
// --------------------
|
||||
// Upload form helpers
|
||||
// --------------------
|
||||
// Normalize Upload event to return single File object for Form storage
|
||||
const normFile = (e: any) => {
|
||||
if (!e) return undefined;
|
||||
const list: UploadFile[] = e.fileList || [];
|
||||
@@ -488,7 +456,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
return (last as any).originFileObj ?? last;
|
||||
};
|
||||
|
||||
// Icon-only button wrapped in Tooltip
|
||||
function IconButtonTooltip({
|
||||
title,
|
||||
onClick,
|
||||
@@ -509,9 +476,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
);
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// Add Requirements (for scripts missing requirements)
|
||||
// --------------------
|
||||
const openAddRequirements = useCallback((scriptName: string) => {
|
||||
setAddReqTarget(scriptName);
|
||||
setAddReqUseInline(false);
|
||||
@@ -549,7 +513,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
}
|
||||
}, [addReqFile, addReqInlineValue, addReqTarget, refreshAll, showPipIfPresent]);
|
||||
|
||||
// helper for Upload change inside add-req modal
|
||||
const onAddReqUploadChange = useCallback((info: any) => {
|
||||
const list: UploadFile[] = info.fileList || [];
|
||||
if (list.length === 0) {
|
||||
@@ -560,9 +523,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
setAddReqFile(last.originFileObj ?? last);
|
||||
}, []);
|
||||
|
||||
// --------------------
|
||||
// Table columns
|
||||
// --------------------
|
||||
const columns: ColumnsType<ScriptWithStatus> = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -715,9 +675,6 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
[getMappingsForScript, nestedColumns],
|
||||
);
|
||||
|
||||
// --------------------
|
||||
// Render
|
||||
// --------------------
|
||||
return (
|
||||
<div>
|
||||
<Row justify="space-between" style={{ marginBottom: 12 }}>
|
||||
@@ -740,7 +697,7 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
expandable={expandable}
|
||||
/>
|
||||
|
||||
{/* Upload Modal (wider) */}
|
||||
|
||||
<Modal
|
||||
open={uploadModalVisible}
|
||||
title="Upload or create script"
|
||||
@@ -816,7 +773,7 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
{/* Editor Modal */}
|
||||
|
||||
<Modal
|
||||
open={editorModalVisible}
|
||||
title={currentEditingName ? `Editing — ${currentEditingName}` : 'Editor'}
|
||||
@@ -874,7 +831,7 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
<PythonEditor value={editorValue} onChange={setEditorValue} height={520} />
|
||||
</Modal>
|
||||
|
||||
{/* Requirements Editor Modal (per-script) */}
|
||||
|
||||
<Modal
|
||||
open={reqModalVisible}
|
||||
title={reqEditingName ? `requirements.txt — ${reqEditingName}` : 'requirements.txt'}
|
||||
@@ -913,7 +870,7 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
<PythonEditor value={reqEditorValue} onChange={setReqEditorValue} height={420} />
|
||||
</Modal>
|
||||
|
||||
{/* Add Requirements Modal (for scripts without requirements) */}
|
||||
|
||||
<Modal
|
||||
open={addReqModalVisible}
|
||||
title={addReqTarget ? `Add requirements — ${addReqTarget}` : 'Add requirements'}
|
||||
@@ -967,7 +924,7 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
{/* Pip output modal */}
|
||||
|
||||
<Modal
|
||||
open={pipModalVisible}
|
||||
title="pip install output"
|
||||
@@ -986,7 +943,7 @@ export default function ScriptsManager({ onOpenInEditor }: { onOpenInEditor?: (c
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
{/* Enable Modal */}
|
||||
|
||||
<Modal
|
||||
open={enableModalVisible}
|
||||
title={`Enable ${enableTarget ?? ''}`}
|
||||
|
||||
Reference in New Issue
Block a user