feat: get network interface
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ReactNode, useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useLockFn } from "ahooks";
|
||||
import yaml from "js-yaml";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -30,7 +30,11 @@ import {
|
||||
styled,
|
||||
} from "@mui/material";
|
||||
import { GroupItem } from "@/components/profile/group-item";
|
||||
import { readProfileFile, saveProfileFile } from "@/services/cmds";
|
||||
import {
|
||||
getNetworkInterfaces,
|
||||
readProfileFile,
|
||||
saveProfileFile,
|
||||
} from "@/services/cmds";
|
||||
import { Notice, Switch } from "@/components/base";
|
||||
import getSystem from "@/utils/get-system";
|
||||
import { BaseSearchBox } from "../base/base-search-box";
|
||||
@@ -60,7 +64,7 @@ export const GroupsEditorViewer = (props: Props) => {
|
||||
const [currData, setCurrData] = useState("");
|
||||
const [visualization, setVisualization] = useState(true);
|
||||
const [match, setMatch] = useState(() => (_: string) => true);
|
||||
|
||||
const [interfaceNameList, setInterfaceNameList] = useState<string[]>([]);
|
||||
const { control, watch, register, ...formIns } = useForm<IProxyGroupConfig>({
|
||||
defaultValues: {
|
||||
type: "select",
|
||||
@@ -251,6 +255,10 @@ export const GroupsEditorViewer = (props: Props) => {
|
||||
setProxyProviderList(Object.keys(provider));
|
||||
setGroupList(originGroupsObj?.["proxy-groups"] || []);
|
||||
};
|
||||
const getInterfaceNameList = async () => {
|
||||
let list = await getNetworkInterfaces();
|
||||
setInterfaceNameList(list);
|
||||
};
|
||||
useEffect(() => {
|
||||
fetchProxyPolicy();
|
||||
}, [prependSeq, appendSeq, deleteSeq]);
|
||||
@@ -259,6 +267,7 @@ export const GroupsEditorViewer = (props: Props) => {
|
||||
fetchContent();
|
||||
fetchProxyPolicy();
|
||||
fetchProfile();
|
||||
getInterfaceNameList();
|
||||
}, [open]);
|
||||
|
||||
const validateGroup = () => {
|
||||
@@ -485,11 +494,13 @@ export const GroupsEditorViewer = (props: Props) => {
|
||||
render={({ field }) => (
|
||||
<Item>
|
||||
<ListItemText primary={t("Interface Name")} />
|
||||
<TextField
|
||||
autoComplete="new-password"
|
||||
<Autocomplete
|
||||
size="small"
|
||||
sx={{ width: "calc(100% - 150px)" }}
|
||||
{...field}
|
||||
options={interfaceNameList}
|
||||
value={field.value}
|
||||
onChange={(_, value) => value && field.onChange(value)}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
/>
|
||||
</Item>
|
||||
)}
|
||||
|
||||
@@ -475,64 +475,78 @@ export const ProfileItem = (props: Props) => {
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
{fileOpen && (
|
||||
<EditorViewer
|
||||
open={true}
|
||||
initialData={readProfileFile(uid)}
|
||||
language="yaml"
|
||||
schema="clash"
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(uid, curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
)}
|
||||
{rulesOpen && (
|
||||
<RulesEditorViewer
|
||||
groupsUid={option?.groups ?? ""}
|
||||
mergeUid={option?.merge ?? ""}
|
||||
profileUid={uid}
|
||||
property={option?.rules ?? ""}
|
||||
open={true}
|
||||
onSave={onSave}
|
||||
onClose={() => setRulesOpen(false)}
|
||||
/>
|
||||
)}
|
||||
{proxiesOpen && (
|
||||
<ProxiesEditorViewer
|
||||
profileUid={uid}
|
||||
property={option?.proxies ?? ""}
|
||||
open={true}
|
||||
onSave={onSave}
|
||||
onClose={() => setProxiesOpen(false)}
|
||||
/>
|
||||
)}
|
||||
{groupsOpen && (
|
||||
<GroupsEditorViewer
|
||||
mergeUid={option?.merge ?? ""}
|
||||
proxiesUid={option?.proxies ?? ""}
|
||||
profileUid={uid}
|
||||
property={option?.groups ?? ""}
|
||||
open={true}
|
||||
onSave={onSave}
|
||||
onClose={() => {
|
||||
setGroupsOpen(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{mergeOpen && (
|
||||
<EditorViewer
|
||||
open={true}
|
||||
initialData={readProfileFile(option?.merge ?? "")}
|
||||
language="yaml"
|
||||
schema="clash"
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.merge ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setMergeOpen(false)}
|
||||
/>
|
||||
)}
|
||||
{scriptOpen && (
|
||||
<EditorViewer
|
||||
open={true}
|
||||
initialData={readProfileFile(option?.script ?? "")}
|
||||
language="javascript"
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.script ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setScriptOpen(false)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<EditorViewer
|
||||
open={fileOpen}
|
||||
initialData={readProfileFile(uid)}
|
||||
language="yaml"
|
||||
schema="clash"
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(uid, curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
<RulesEditorViewer
|
||||
groupsUid={option?.groups ?? ""}
|
||||
mergeUid={option?.merge ?? ""}
|
||||
profileUid={uid}
|
||||
property={option?.rules ?? ""}
|
||||
open={rulesOpen}
|
||||
onSave={onSave}
|
||||
onClose={() => setRulesOpen(false)}
|
||||
/>
|
||||
<ProxiesEditorViewer
|
||||
profileUid={uid}
|
||||
property={option?.proxies ?? ""}
|
||||
open={proxiesOpen}
|
||||
onSave={onSave}
|
||||
onClose={() => setProxiesOpen(false)}
|
||||
/>
|
||||
<GroupsEditorViewer
|
||||
mergeUid={option?.merge ?? ""}
|
||||
proxiesUid={option?.proxies ?? ""}
|
||||
profileUid={uid}
|
||||
property={option?.groups ?? ""}
|
||||
open={groupsOpen}
|
||||
onSave={onSave}
|
||||
onClose={() => setGroupsOpen(false)}
|
||||
/>
|
||||
<EditorViewer
|
||||
open={mergeOpen}
|
||||
initialData={readProfileFile(option?.merge ?? "")}
|
||||
language="yaml"
|
||||
schema="clash"
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.merge ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setMergeOpen(false)}
|
||||
/>
|
||||
<EditorViewer
|
||||
open={scriptOpen}
|
||||
initialData={readProfileFile(option?.script ?? "")}
|
||||
language="javascript"
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(option?.script ?? "", curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setScriptOpen(false)}
|
||||
/>
|
||||
<ConfirmViewer
|
||||
title={t("Confirm deletion")}
|
||||
message={t("This operation is not reversible")}
|
||||
|
||||
@@ -167,25 +167,27 @@ export const ProfileMore = (props: Props) => {
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
|
||||
<EditorViewer
|
||||
open={fileOpen}
|
||||
title={`${t("Global " + id)}`}
|
||||
initialData={readProfileFile(id)}
|
||||
language={id === "Merge" ? "yaml" : "javascript"}
|
||||
schema={id === "Merge" ? "clash" : undefined}
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(id, curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
|
||||
<LogViewer
|
||||
open={logOpen}
|
||||
logInfo={logInfo}
|
||||
onClose={() => setLogOpen(false)}
|
||||
/>
|
||||
{fileOpen && (
|
||||
<EditorViewer
|
||||
open={true}
|
||||
title={`${t("Global " + id)}`}
|
||||
initialData={readProfileFile(id)}
|
||||
language={id === "Merge" ? "yaml" : "javascript"}
|
||||
schema={id === "Merge" ? "clash" : undefined}
|
||||
onSave={async (prev, curr) => {
|
||||
await saveProfileFile(id, curr ?? "");
|
||||
onSave && onSave(prev, curr);
|
||||
}}
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
)}
|
||||
{logOpen && (
|
||||
<LogViewer
|
||||
open={logOpen}
|
||||
logInfo={logInfo}
|
||||
onClose={() => setLogOpen(false)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user