feat: 数据提升
This commit is contained in:
parent
90e3e22e44
commit
25529dd73d
@ -5,5 +5,4 @@
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: scroll;
|
|
||||||
}
|
}
|
@ -1,8 +1,13 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
import NodeTableComponent, {
|
import NodeTableComponent, {
|
||||||
DataTemplateInterface,
|
DataTemplateInterface,
|
||||||
} from "../NodeTableComponent/NodeTableComponent";
|
} from "../NodeTableComponent/NodeTableComponent";
|
||||||
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
|
|
||||||
export default function DosHeader() {
|
export default function DosHeader() {
|
||||||
|
|
||||||
|
const [data, setData] = useState<any[]>([]);
|
||||||
|
|
||||||
const dataTemplate: DataTemplateInterface = {
|
const dataTemplate: DataTemplateInterface = {
|
||||||
e_magic: {
|
e_magic: {
|
||||||
name: "e_magic",
|
name: "e_magic",
|
||||||
@ -149,17 +154,20 @@ export default function DosHeader() {
|
|||||||
title: "字段名",
|
title: "字段名",
|
||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
key: "name",
|
key: "name",
|
||||||
|
width: 120
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "偏移",
|
title: "偏移",
|
||||||
dataIndex: "offset",
|
dataIndex: "offset",
|
||||||
key: "offset",
|
key: "offset",
|
||||||
hexSwitch: true,
|
hexSwitch: true,
|
||||||
|
width: 80
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "大小",
|
title: "大小",
|
||||||
dataIndex: "size",
|
dataIndex: "size",
|
||||||
key: "size",
|
key: "size",
|
||||||
|
width: 80
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "值",
|
title: "值",
|
||||||
@ -167,18 +175,27 @@ export default function DosHeader() {
|
|||||||
key: "value",
|
key: "value",
|
||||||
hexSwitch: true,
|
hexSwitch: true,
|
||||||
editable: true,
|
editable: true,
|
||||||
|
minWidth: 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "描述信息",
|
title: "描述信息",
|
||||||
dataIndex: "description",
|
dataIndex: "description",
|
||||||
key: "description",
|
key: "description",
|
||||||
|
width: 250
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
invoke(command).then(res => {
|
||||||
|
console.log("asdfsadf",res);
|
||||||
|
setData(res as any);
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeTableComponent
|
<NodeTableComponent
|
||||||
dataTemplate={dataTemplate}
|
dataTemplate={dataTemplate}
|
||||||
command={command}
|
defaultData={data}
|
||||||
columns={columns as any}
|
columns={columns as any}
|
||||||
></NodeTableComponent>
|
></NodeTableComponent>
|
||||||
);
|
);
|
||||||
|
@ -5,5 +5,4 @@
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: scroll;
|
|
||||||
}
|
}
|
@ -1,119 +1,195 @@
|
|||||||
import NodeTableComponent, {
|
import NodeTableComponent, {
|
||||||
DataTemplateInterface,
|
DataTemplateInterface,
|
||||||
} from "../NodeTableComponent/NodeTableComponent";
|
} from "../NodeTableComponent/NodeTableComponent";
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
import { Select, Space } from "antd";
|
||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
// 写一个组件,用于展示位枚举值
|
||||||
|
interface BitEnumComponentProps {
|
||||||
|
value: number;
|
||||||
|
enum: {
|
||||||
|
[key: number]: {
|
||||||
|
enum_name: string; // 枚举值名称
|
||||||
|
description?: string; // 枚举值描述
|
||||||
|
};
|
||||||
|
};
|
||||||
|
onChange?: (value: any, options: any) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BitEnumComponent = (props: BitEnumComponentProps) => {
|
||||||
|
const formatOptions = useMemo(() => {
|
||||||
|
const options = Object.entries(props.enum).map(([key, value]) => {
|
||||||
|
return {
|
||||||
|
label: value.enum_name,
|
||||||
|
value: key,
|
||||||
|
title: value.description,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}, [props.enum, props.value]);
|
||||||
|
|
||||||
|
const formatValue = useMemo(() => {
|
||||||
|
const value = [];
|
||||||
|
for (const key in props.enum) {
|
||||||
|
if (props.value & parseInt(key)) {
|
||||||
|
value.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}, [props.value]);
|
||||||
|
|
||||||
|
const handleChange = (value: number[], options) => {
|
||||||
|
// 如果props.onChange存在,那么调用
|
||||||
|
props.onChange?.(value, options);
|
||||||
|
// TODO: 做一些自己的事
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space style={{ width: "100%" }} direction="vertical">
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
options={formatOptions}
|
||||||
|
value={formatValue}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default function FileHeader() {
|
export default function FileHeader() {
|
||||||
|
const [data, setData] = useState<any[]>([]);
|
||||||
|
const [valueHex, setValueHex] = useState(false);
|
||||||
|
|
||||||
|
const handleChangeBitEnum = (record: any, value: number[], _options) => {
|
||||||
|
const { name } = record;
|
||||||
|
const newData: any = { ...data };
|
||||||
|
newData.fields[name] = value.reduce(
|
||||||
|
(prev, cur: any) => prev | parseInt(cur),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
setData(newData);
|
||||||
|
};
|
||||||
|
|
||||||
const dataTemplate: DataTemplateInterface = {
|
const dataTemplate: DataTemplateInterface = {
|
||||||
machine: {
|
machine: {
|
||||||
name: "Machine",
|
name: "machine",
|
||||||
|
description: "目标机器类型,例如 x86 或 x64。",
|
||||||
offset: 0,
|
offset: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
value: null,
|
value: null,
|
||||||
data_type: "hex",
|
data_type: "hex",
|
||||||
},
|
},
|
||||||
number_of_sections: {
|
number_of_sections: {
|
||||||
name: "Number of Sections",
|
name: "number_of_sections",
|
||||||
|
description: "节的数量,表示文件中包含的段数量。",
|
||||||
offset: 2,
|
offset: 2,
|
||||||
size: 2,
|
size: 2,
|
||||||
value: null,
|
value: null,
|
||||||
data_type: "hex",
|
data_type: "hex",
|
||||||
},
|
},
|
||||||
time_date_stamp: {
|
time_date_stamp: {
|
||||||
name: "Time Date Stamp",
|
name: "time_date_stamp",
|
||||||
|
description: "文件的创建时间戳,以自 1970-01-01 的秒数表示。",
|
||||||
offset: 4,
|
offset: 4,
|
||||||
size: 4,
|
size: 4,
|
||||||
value: null,
|
value: null,
|
||||||
data_type: "hex",
|
data_type: "hex",
|
||||||
},
|
},
|
||||||
pointer_to_symbol_table: {
|
pointer_to_symbol_table: {
|
||||||
name: "Pointer to Symbol Table",
|
name: "pointer_to_symbol_table",
|
||||||
|
description: "符号表的文件偏移(通常为 0 表示未使用)。",
|
||||||
offset: 8,
|
offset: 8,
|
||||||
size: 4,
|
size: 4,
|
||||||
value: null,
|
value: null,
|
||||||
data_type: "hex",
|
data_type: "hex",
|
||||||
},
|
},
|
||||||
number_of_symbols: {
|
number_of_symbols: {
|
||||||
name: "Number of Symbols",
|
name: "number_of_symbols",
|
||||||
|
description: "符号表中符号的数量(通常为 0 表示未使用)。",
|
||||||
offset: 12,
|
offset: 12,
|
||||||
size: 4,
|
size: 4,
|
||||||
value: null,
|
value: null,
|
||||||
data_type: "hex",
|
data_type: "hex",
|
||||||
},
|
},
|
||||||
size_of_optional_header: {
|
size_of_optional_header: {
|
||||||
name: "Size of Optional Header",
|
name: "size_of_optional_header",
|
||||||
|
description: "可选头的大小,用于进一步描述文件。",
|
||||||
offset: 16,
|
offset: 16,
|
||||||
size: 2,
|
size: 2,
|
||||||
value: null,
|
value: null,
|
||||||
data_type: "hex",
|
data_type: "hex",
|
||||||
},
|
},
|
||||||
characteristics: {
|
characteristics: {
|
||||||
name: "Characteristics",
|
name: "characteristics",
|
||||||
|
description: "文件特性标志,例如可执行、DLL、移除调试信息等。",
|
||||||
offset: 18,
|
offset: 18,
|
||||||
size: 2,
|
size: 2,
|
||||||
value: null,
|
value: null,
|
||||||
data_type: "enum",
|
data_type: "bit_enum",
|
||||||
enum: {
|
enum: {
|
||||||
0x1: {
|
0x1: {
|
||||||
enum_name: "RELOCS_STRIPPED",
|
enum_name: "RELOCS_STRIPPED",
|
||||||
description: "Relocation info stripped from file.",
|
description: "已从文件中移除重定位信息。",
|
||||||
},
|
},
|
||||||
0x2: {
|
0x2: {
|
||||||
enum_name: "EXECUTABLE_IMAGE",
|
enum_name: "EXECUTABLE_IMAGE",
|
||||||
description:
|
description: "文件是可执行的(例如,没有未解析的外部引用)。",
|
||||||
"File is executable (i.e. no unresolved external references).",
|
|
||||||
},
|
},
|
||||||
0x4: {
|
0x4: {
|
||||||
enum_name: "LINE_NUMS_STRIPPED",
|
enum_name: "LINE_NUMS_STRIPPED",
|
||||||
description: "Line nunbers stripped from file.",
|
description: "已从文件中移除行号信息。",
|
||||||
},
|
},
|
||||||
0x8: {
|
0x8: {
|
||||||
enum_name: "LOCAL_SYMS_STRIPPED",
|
enum_name: "LOCAL_SYMS_STRIPPED",
|
||||||
description: "Local symbols stripped from file.",
|
description: "已从文件中移除本地符号信息。",
|
||||||
},
|
},
|
||||||
0x10: {
|
0x10: {
|
||||||
enum_name: "AGGRESSIVE_WS_TRIM",
|
enum_name: "AGGRESSIVE_WS_TRIM",
|
||||||
description: "Aggressively trim working set",
|
description: "积极地减少工作集。",
|
||||||
},
|
},
|
||||||
0x20: {
|
0x20: {
|
||||||
enum_name: "LARGE_ADDRESS_AWARE",
|
enum_name: "LARGE_ADDRESS_AWARE",
|
||||||
description: "App can handle >2gb addresses",
|
description: "应用程序可以处理大于 2GB 的地址。",
|
||||||
},
|
},
|
||||||
0x80: {
|
0x80: {
|
||||||
enum_name: "BYTES_REVERSED_LO",
|
enum_name: "BYTES_REVERSED_LO",
|
||||||
description: "Bytes of machine word are reversed.",
|
description: "机器字的字节顺序被颠倒(低位字节)。",
|
||||||
},
|
},
|
||||||
0x100: {
|
0x100: {
|
||||||
enum_name: "MACHINE_32BIT",
|
enum_name: "MACHINE_32BIT",
|
||||||
description: "32 bit word machine.",
|
description: "32 位字长的机器。",
|
||||||
},
|
},
|
||||||
0x200: {
|
0x200: {
|
||||||
enum_name: "DEBUG_STRIPPED",
|
enum_name: "DEBUG_STRIPPED",
|
||||||
description: "Debugging info stripped from file in .DBG file",
|
description: "调试信息已被移到 .DBG 文件中。",
|
||||||
},
|
},
|
||||||
0x400: {
|
0x400: {
|
||||||
enum_name: "REMOVABLE_RUN_FROM_SWAP",
|
enum_name: "REMOVABLE_RUN_FROM_SWAP",
|
||||||
description:
|
description: "如果映像位于可移动介质上,则复制并从交换文件运行。",
|
||||||
"If Image is on removable media, copy and run from the swap file.",
|
|
||||||
},
|
},
|
||||||
0x800: {
|
0x800: {
|
||||||
enum_name: "NET_RUN_FROM_SWAP",
|
enum_name: "NET_RUN_FROM_SWAP",
|
||||||
description: "If Image is on Net, copy and run from the swap file.",
|
description: "如果映像位于网络上,则复制并从交换文件运行。",
|
||||||
},
|
},
|
||||||
0x1000: {
|
0x1000: {
|
||||||
enum_name: "SYSTEM",
|
enum_name: "SYSTEM",
|
||||||
description: "System File.",
|
description: "系统文件。",
|
||||||
},
|
},
|
||||||
0x2000: {
|
0x2000: {
|
||||||
enum_name: "DLL",
|
enum_name: "DLL",
|
||||||
description: "File is a DLL.",
|
description: "文件是一个 DLL。",
|
||||||
},
|
},
|
||||||
0x4000: {
|
0x4000: {
|
||||||
enum_name: "UP_SYSTEM_ONLY",
|
enum_name: "UP_SYSTEM_ONLY",
|
||||||
description: "File should only be run on a UP machine",
|
description: "文件只能在单处理器机器上运行。",
|
||||||
},
|
},
|
||||||
0x8000: {
|
0x8000: {
|
||||||
enum_name: "BYTES_REVERSED_HI",
|
enum_name: "BYTES_REVERSED_HI",
|
||||||
description: "Bytes of machine word are reversed.",
|
description: "机器字的字节顺序被颠倒(高位字节)。",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -140,19 +216,51 @@ export default function FileHeader() {
|
|||||||
title: "值",
|
title: "值",
|
||||||
dataIndex: "value",
|
dataIndex: "value",
|
||||||
key: "value",
|
key: "value",
|
||||||
hexSwitch: true,
|
|
||||||
editable: true,
|
editable: true,
|
||||||
|
render: (text: any, record: any) => {
|
||||||
|
if (record.data_type === "bit_enum") {
|
||||||
|
return (
|
||||||
|
<BitEnumComponent
|
||||||
|
value={text}
|
||||||
|
enum={record.enum}
|
||||||
|
onChange={(value, options) =>
|
||||||
|
handleChangeBitEnum(record, value, options)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else if (record.data_type === "hex") {
|
||||||
|
return (
|
||||||
|
<span style={{ cursor: "pointer" }}>
|
||||||
|
{valueHex ? `0x${text.toString(16).toUpperCase()}` : text}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <span>{text}</span>;
|
||||||
|
},
|
||||||
|
onHeaderCell: () => ({
|
||||||
|
onClick: () => {
|
||||||
|
setValueHex(!valueHex);
|
||||||
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "描述信息",
|
title: "描述信息",
|
||||||
dataIndex: "description",
|
dataIndex: "description",
|
||||||
key: "description",
|
key: "description",
|
||||||
|
minWidth: 200,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
invoke(command).then((res) => {
|
||||||
|
setData(res as any);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeTableComponent
|
<NodeTableComponent
|
||||||
dataTemplate={dataTemplate}
|
dataTemplate={dataTemplate}
|
||||||
command={command}
|
defaultData={data}
|
||||||
columns={columns as any}
|
columns={columns as any}
|
||||||
></NodeTableComponent>
|
></NodeTableComponent>
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
import NodeTableComponent, {
|
import NodeTableComponent, {
|
||||||
DataTemplateInterface,
|
DataTemplateInterface,
|
||||||
} from "../NodeTableComponent/NodeTableComponent";
|
} from "../NodeTableComponent/NodeTableComponent";
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
|
||||||
export default function NTHeader() {
|
export default function NTHeader() {
|
||||||
|
const [data, setData] = useState<any[]>([]);
|
||||||
// TODO: 这里要分64位和32位,最好让后端返回
|
// TODO: 这里要分64位和32位,最好让后端返回
|
||||||
const dataTemplate: DataTemplateInterface = {
|
const dataTemplate: DataTemplateInterface = {
|
||||||
signature: {
|
signature: {
|
||||||
@ -44,10 +47,17 @@ export default function NTHeader() {
|
|||||||
key: "description",
|
key: "description",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
invoke(command).then((res) => {
|
||||||
|
setData(res as any);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeTableComponent
|
<NodeTableComponent
|
||||||
|
defaultData={data}
|
||||||
dataTemplate={dataTemplate}
|
dataTemplate={dataTemplate}
|
||||||
command={command}
|
|
||||||
columns={columns as any}
|
columns={columns as any}
|
||||||
></NodeTableComponent>
|
></NodeTableComponent>
|
||||||
);
|
);
|
||||||
|
@ -1,14 +1,7 @@
|
|||||||
.NodeTableComponentRootFlex {
|
.NodeTableComponentRootFlex {
|
||||||
background-color: white;
|
min-width: calc(100% - 16px);
|
||||||
border-radius: 5px;
|
|
||||||
padding: 8px;
|
|
||||||
margin-right: 8px;
|
|
||||||
overflow-y: scroll;
|
|
||||||
height: 100%;
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.NodeTableComponentTable{
|
.NodeTableComponentTable{
|
||||||
height: calc(100% - 16px);
|
height: calc(100% - 16px);
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
@ -2,7 +2,6 @@ import { Table, Flex } from "antd/lib";
|
|||||||
import { ColumnType } from "antd/lib/table";
|
import { ColumnType } from "antd/lib/table";
|
||||||
import { useState, useMemo, useEffect, useRef, useContext } from "react";
|
import { useState, useMemo, useEffect, useRef, useContext } from "react";
|
||||||
import styles from "./NodeTableComponent.module.scss";
|
import styles from "./NodeTableComponent.module.scss";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
|
||||||
import { cloneDeep } from "lodash-es";
|
import { cloneDeep } from "lodash-es";
|
||||||
import { Form, FormInstance, Input, InputRef } from "antd";
|
import { Form, FormInstance, Input, InputRef } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
@ -33,10 +32,11 @@ export interface DataType {
|
|||||||
};
|
};
|
||||||
array_element_size?: number; // 数组元素大小
|
array_element_size?: number; // 数组元素大小
|
||||||
// hex: 16进制
|
// hex: 16进制
|
||||||
// enum: 枚举值,对于枚举的处理一律按位处理
|
// enum: 枚举值
|
||||||
|
// bit_enum: 位枚举值
|
||||||
// array: 数组
|
// array: 数组
|
||||||
// char_array: 字符数组
|
// char_array: 字符数组
|
||||||
data_type: "hex" | "enum" | "array"| "char_array";
|
data_type: "hex" | "enum" | "array" | "char_array" | "bit_enum";
|
||||||
children?: DataType[];
|
children?: DataType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,8 +52,9 @@ export interface NodeTableColumnInterface<T> extends ColumnType<T> {
|
|||||||
|
|
||||||
interface NodeTableComponentProps {
|
interface NodeTableComponentProps {
|
||||||
dataTemplate: DataTemplateInterface; // 数据模板
|
dataTemplate: DataTemplateInterface; // 数据模板
|
||||||
command: string; // 请求数据的命令
|
// command: string; // 请求数据的命令
|
||||||
columns: NodeTableColumnInterface<DataType>[];
|
columns: NodeTableColumnInterface<DataType>[];
|
||||||
|
defaultData?: DataType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EditableRowProps {
|
interface EditableRowProps {
|
||||||
@ -92,7 +93,6 @@ const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
|||||||
const [editing, setEditing] = useState(false);
|
const [editing, setEditing] = useState(false);
|
||||||
const inputRef = useRef<InputRef>(null);
|
const inputRef = useRef<InputRef>(null);
|
||||||
const form = useContext(EditableContext)!;
|
const form = useContext(EditableContext)!;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editing) {
|
if (editing) {
|
||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
@ -116,7 +116,7 @@ const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
|||||||
|
|
||||||
let childNode = children;
|
let childNode = children;
|
||||||
|
|
||||||
if (editable) {
|
if (editable && record?.data_type == "hex") {
|
||||||
childNode = editing ? (
|
childNode = editing ? (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
style={{ margin: 0 }}
|
style={{ margin: 0 }}
|
||||||
@ -140,7 +140,6 @@ const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function NodeTableComponent(props: NodeTableComponentProps) {
|
export default function NodeTableComponent(props: NodeTableComponentProps) {
|
||||||
const [data, setData] = useState<DataType[]>([]);
|
|
||||||
// 需要搞一个状态,用来保存不同列的hex显示状态
|
// 需要搞一个状态,用来保存不同列的hex显示状态
|
||||||
const [hexSwitchStatus, setHexSwitchStatus] = useState<{
|
const [hexSwitchStatus, setHexSwitchStatus] = useState<{
|
||||||
[key: string]: boolean;
|
[key: string]: boolean;
|
||||||
@ -152,7 +151,7 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
|
|||||||
setHexSwitchStatus(newHexSwitchStatus);
|
setHexSwitchStatus(newHexSwitchStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = (row: DataType) => {
|
const handleSave = (_row: DataType) => {
|
||||||
// TODO: 保存逻辑
|
// TODO: 保存逻辑
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -194,8 +193,8 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...col,
|
|
||||||
...extraCol,
|
...extraCol,
|
||||||
|
...col,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}, [props.columns, hexSwitchStatus]);
|
}, [props.columns, hexSwitchStatus]);
|
||||||
@ -205,6 +204,10 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
|
|||||||
const cloneData = cloneDeep(props.dataTemplate);
|
const cloneData = cloneDeep(props.dataTemplate);
|
||||||
// 2. 遍历resData,更新cloneData
|
// 2. 遍历resData,更新cloneData
|
||||||
for (let key in cloneData) {
|
for (let key in cloneData) {
|
||||||
|
if(!resData || !resData.fields){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cloneData[key].value = resData.fields[key];
|
cloneData[key].value = resData.fields[key];
|
||||||
cloneData[key].offset += resData.base_offset;
|
cloneData[key].offset += resData.base_offset;
|
||||||
// 如果是array
|
// 如果是array
|
||||||
@ -244,23 +247,30 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
|
|||||||
cloneData[key].children = children;
|
cloneData[key].children = children;
|
||||||
}
|
}
|
||||||
// TODO: 字符数组处理
|
// TODO: 字符数组处理
|
||||||
|
|
||||||
}
|
}
|
||||||
// TODO: 应该从columns中获需要排序的字段,来进行排序
|
// TODO: 应该从columns中获需要排序的字段,来进行排序
|
||||||
// 如果cloneData的成员中有offset字段,那么需要按照offset排序
|
// 如果cloneData的成员中有offset字段,那么需要按照offset排序
|
||||||
let cloneDataArray = Object.values(cloneData);
|
let cloneDataArray = Object.values(cloneData);
|
||||||
if(cloneDataArray[0].offset){
|
if (cloneDataArray[0].offset) {
|
||||||
cloneDataArray.sort((a, b) => a.offset - b.offset);
|
cloneDataArray.sort((a, b) => a.offset - b.offset);
|
||||||
}
|
}
|
||||||
setData(cloneDataArray);
|
return cloneDataArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const formatData = useMemo(()=>{
|
||||||
// 请求数据
|
return handleData(props.defaultData as any);
|
||||||
invoke(props.command).then((resData: ResponsData) => {
|
|
||||||
handleData(resData);
|
}, [props.defaultData])
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// // 请求数据
|
||||||
|
// invoke(props.command).then((resData: ResponsData) => {
|
||||||
|
// handleData(resData);
|
||||||
|
// });
|
||||||
|
// }, []);
|
||||||
return (
|
return (
|
||||||
<Flex className={styles.NodeTableComponentRootFlex}>
|
<Flex className={styles.NodeTableComponentRootFlex}>
|
||||||
<Table
|
<Table
|
||||||
@ -268,12 +278,13 @@ export default function NodeTableComponent(props: NodeTableComponentProps) {
|
|||||||
className={styles.NodeTableComponentTable}
|
className={styles.NodeTableComponentTable}
|
||||||
rowClassName={() => "editable-row"}
|
rowClassName={() => "editable-row"}
|
||||||
columns={formatCol}
|
columns={formatCol}
|
||||||
dataSource={data}
|
dataSource={formatData}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
|
tableLayout="auto"
|
||||||
rowKey={"name"}
|
rowKey={"name"}
|
||||||
bordered
|
bordered
|
||||||
size="small"
|
size="small"
|
||||||
sticky={{ offsetHeader: -8 }}
|
sticky={{ offsetHeader: -16 }}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
import NodeTableComponent, {
|
import NodeTableComponent, {
|
||||||
DataTemplateInterface,
|
DataTemplateInterface,
|
||||||
} from "../NodeTableComponent/NodeTableComponent";
|
} from "../NodeTableComponent/NodeTableComponent";
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
|
||||||
export default function OptionalHeader() {
|
export default function OptionalHeader() {
|
||||||
|
const [data, setData] = useState<any[]>([]);
|
||||||
const dataTemplate: DataTemplateInterface = {
|
const dataTemplate: DataTemplateInterface = {
|
||||||
magic: {
|
magic: {
|
||||||
name: "magic",
|
name: "magic",
|
||||||
@ -268,10 +271,17 @@ export default function OptionalHeader() {
|
|||||||
key: "description",
|
key: "description",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
invoke(command).then((res) => {
|
||||||
|
setData(res as any);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeTableComponent
|
<NodeTableComponent
|
||||||
dataTemplate={dataTemplate}
|
dataTemplate={dataTemplate}
|
||||||
command={command}
|
defaultData={data}
|
||||||
columns={columns as any}
|
columns={columns as any}
|
||||||
></NodeTableComponent>
|
></NodeTableComponent>
|
||||||
);
|
);
|
||||||
|
@ -54,7 +54,6 @@ import NodeTableComponent, {
|
|||||||
return (
|
return (
|
||||||
<NodeTableComponent
|
<NodeTableComponent
|
||||||
dataTemplate={dataTemplate}
|
dataTemplate={dataTemplate}
|
||||||
command={command}
|
|
||||||
columns={columns as any}
|
columns={columns as any}
|
||||||
></NodeTableComponent>
|
></NodeTableComponent>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.root {
|
.root {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
width: 100%;
|
width: 200px;
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -2,7 +2,6 @@ import React from "react";
|
|||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import { delay} from "lodash-es"
|
|
||||||
|
|
||||||
async function setup() {
|
async function setup() {
|
||||||
invoke('set_complete')
|
invoke('set_complete')
|
||||||
|
@ -2,16 +2,13 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background-color: #e3e3e3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.sider {
|
.sider {
|
||||||
flex-shrink: 0;
|
|
||||||
width: 260px;
|
margin-right: 8px;
|
||||||
height: calc(100% - 64px);
|
|
||||||
margin: 8px;
|
|
||||||
margin-top: 0;
|
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
// 圆角
|
// 圆角
|
||||||
@ -27,5 +24,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content{
|
.content{
|
||||||
height: calc(100% - 64px);
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: scroll;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainContent {
|
||||||
|
margin: 8px;
|
||||||
|
margin-top: 0;
|
||||||
|
height: calc(100% - 16px);
|
||||||
|
background-color: #e3e3e3;
|
||||||
|
border-radius: 5px;
|
||||||
|
min-height: 500px;
|
||||||
}
|
}
|
@ -10,9 +10,6 @@ import DosHeader from "../components/DosHeader/DosHeader";
|
|||||||
import NtHeader from "../components/NTHeader/NTHeader";
|
import NtHeader from "../components/NTHeader/NTHeader";
|
||||||
import FileHeader from "../components/FileHeader/FileHeader";
|
import FileHeader from "../components/FileHeader/FileHeader";
|
||||||
import OptionalHeader from "../components/OptionalHeader/OptionalHeader";
|
import OptionalHeader from "../components/OptionalHeader/OptionalHeader";
|
||||||
import NodeTableComponent, {
|
|
||||||
DataTemplateInterface,
|
|
||||||
} from "../components/NodeTableComponent/NodeTableComponent";
|
|
||||||
import { open } from "@tauri-apps/plugin-dialog";
|
import { open } from "@tauri-apps/plugin-dialog";
|
||||||
|
|
||||||
const SelectNodeMap = {
|
const SelectNodeMap = {
|
||||||
@ -85,15 +82,10 @@ export default function MainPage() {
|
|||||||
保存
|
保存
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex className={styles.mainContent}>
|
||||||
style={{
|
|
||||||
backgroundColor: "#e5e5e5",
|
|
||||||
paddingBottom: "16px",
|
|
||||||
height: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Flex className={styles.sider}>
|
<Flex className={styles.sider}>
|
||||||
<SiderTree
|
<SiderTree
|
||||||
|
|
||||||
treeData={treeData}
|
treeData={treeData}
|
||||||
defaultSelectedKey={treeData[0]?.key || ""}
|
defaultSelectedKey={treeData[0]?.key || ""}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
@ -103,105 +95,12 @@ export default function MainPage() {
|
|||||||
{selectedKey && SelectNodeMap[selectedKey] ? (
|
{selectedKey && SelectNodeMap[selectedKey] ? (
|
||||||
SelectNodeMap[selectedKey]
|
SelectNodeMap[selectedKey]
|
||||||
) : (
|
) : (
|
||||||
<Empty description={"请选择一个节点"} />
|
<Empty style={{
|
||||||
|
alignSelf: "center",
|
||||||
|
}} description={"请选择一个节点"} />
|
||||||
)}
|
)}
|
||||||
{/* <TestNodeTableComponent></TestNodeTableComponent> */}
|
|
||||||
</Content>
|
</Content>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TestNodeTableComponent = () => {
|
|
||||||
const [sortStatus, setSortStatus] = useState<"ascend" | "descend" | null>(
|
|
||||||
"ascend"
|
|
||||||
);
|
|
||||||
const dataTemplate: DataTemplateInterface = {
|
|
||||||
e_magic: {
|
|
||||||
name: "e_magic",
|
|
||||||
value: 0,
|
|
||||||
size: 2,
|
|
||||||
offset: 0,
|
|
||||||
description: "Magic number",
|
|
||||||
data_type: "hex",
|
|
||||||
},
|
|
||||||
e_res: {
|
|
||||||
name: "e_res",
|
|
||||||
value: null,
|
|
||||||
size: 8,
|
|
||||||
offset: 28,
|
|
||||||
description: "Reserved",
|
|
||||||
data_type: "array",
|
|
||||||
array_element_size: 2,
|
|
||||||
},
|
|
||||||
test_enum: {
|
|
||||||
name: "test_enum",
|
|
||||||
value: 0,
|
|
||||||
size: 2,
|
|
||||||
offset: 10,
|
|
||||||
description: "Test enum",
|
|
||||||
data_type: "enum",
|
|
||||||
enum: {
|
|
||||||
1: {
|
|
||||||
enum_name: "enum1",
|
|
||||||
description: "enum1 description",
|
|
||||||
},
|
|
||||||
2: {
|
|
||||||
enum_name: "enum2",
|
|
||||||
description: "enum2 description",
|
|
||||||
},
|
|
||||||
4: {
|
|
||||||
enum_name: "enum4",
|
|
||||||
description: "enum4 description",
|
|
||||||
},
|
|
||||||
8: {
|
|
||||||
enum_name: "enum8",
|
|
||||||
description: "enum8 description",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const command = "test_command";
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
title: "Name",
|
|
||||||
dataIndex: "name",
|
|
||||||
key: "name",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "偏移",
|
|
||||||
dataIndex: "offset",
|
|
||||||
hexSwitch: true,
|
|
||||||
key: "offset",
|
|
||||||
sortOrder: sortStatus,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "大小",
|
|
||||||
dataIndex: "size",
|
|
||||||
key: "size",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "值",
|
|
||||||
dataIndex: "value",
|
|
||||||
hexSwitch: true,
|
|
||||||
editable: true,
|
|
||||||
key: "value",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "描述",
|
|
||||||
dataIndex: "description",
|
|
||||||
key: "description",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<NodeTableComponent
|
|
||||||
dataTemplate={dataTemplate}
|
|
||||||
command={command}
|
|
||||||
columns={columns as any}
|
|
||||||
></NodeTableComponent>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user