增加复制功能, 优化交互

This commit is contained in:
cnwhy
2023-12-01 02:34:47 +08:00
parent 3e4c1f5365
commit ff34d8d371
12 changed files with 397 additions and 586 deletions
+5 -180
View File
@@ -1,40 +1,14 @@
import { useState, useEffect, useCallback, useRef } from "react";
import {
Button,
Col,
ConfigProvider,
Form,
Layout,
Row,
Select,
Space,
theme,
} from "antd";
import { ProCard } from "@ant-design/pro-components";
import { useState, useEffect, useRef } from "react";
import { ConfigProvider, theme } from "antd";
import Ctx from "./uitls/ctx";
import { init, logout, useGolstCofnig } from "./uitls/server";
import * as API from "./api";
import Home from "./Pages/Home";
import "./App.css";
import { configEvent } from "./uitls/events";
import { download, jsonFormat } from "./uitls";
import ListCard from "./components/ListCard";
import ChainCard from "./components/ListCard/Chains";
import ServiceCard from "./components/ListCard/Services";
import zhCN from "antd/locale/zh_CN";
const colSpan = {
xs: 24,
sm: 24,
md: 12,
lg: 12,
xl: 12,
xxl: 8,
};
const colSpan1 = {
sm: 24,
xxl: 8,
};
import zhCN from "antd/locale/zh_CN";
import Manage from "./Pages/Manage";
function App() {
const gostInfo = useGolstCofnig();
@@ -88,156 +62,7 @@ function App() {
theme={{ algorithm: isDark ? theme.darkAlgorithm : undefined }}
locale={zhCN}
>
{gostInfo ? (
<Layout style={{ height: "100vh", overflow: "hidden" }}>
<Layout.Header style={{ color: "#FFF" }}>
<Row
align="middle"
justify="space-between"
wrap={false}
// style={{ padding: "0 15px" }}
>
<Col color="">
<Space>
<Select placeholder="快捷操作"></Select>
</Space>
</Col>
<Col>{gostInfo.addr}</Col>
<Col>
<Space>
<Button
// type="link"
onClick={() => {
API.saveCofnig();
}}
>
</Button>
<Button
// type="link"
onClick={() => {
download(jsonFormat(gostConfig), "gost.json");
}}
>
</Button>
<Button type="link" onClick={logout}>
</Button>
</Space>
</Col>
</Row>
</Layout.Header>
<Layout.Content style={{ height: "100%", overflow: "auto" }}>
<Row style={{ padding: 16, overflow: "hidden" }}>
<Row gutter={[16, 16]}>
<Col {...colSpan}>
<ServiceCard></ServiceCard>
</Col>
<Col {...colSpan}>
<ChainCard></ChainCard>
</Col>
<Col {...colSpan}>
<ListCard
title="认证器(Auther)"
subTitle="认证器"
name="authers"
api={API.authers}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="准入控制器(Admission)"
subTitle="准入控制器"
name="admissions"
api={API.admissions}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="分流器(Bypass)"
subTitle="分流器"
name="bypass"
api={API.bypasses}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="主机映射器(Hosts)"
subTitle="主机映射器"
name="hosts"
api={API.hosts}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="跳跃点(Hop)"
subTitle="跳跃点"
name="hop"
api={API.hops}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="Ingress"
subTitle="Ingress"
name="ingresses"
api={API.ingresses}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="域名解析器(Resolver)"
subTitle="Resolver"
name="resolvers"
api={API.resolvers}
></ListCard>
</Col>
<Col span={24}>
<ProCard boxShadow title="限速限流">
<Row gutter={[16, 16]}>
<Col {...colSpan1}>
<ListCard
title="流量速率限制"
subTitle=""
name="limiters"
api={API.limiters}
bordered
></ListCard>
</Col>
<Col {...colSpan1}>
<ListCard
title="请求速率限制"
subTitle=""
name="rlimiters"
api={API.rlimiters}
bordered
></ListCard>
</Col>
<Col {...colSpan1}>
<ListCard
title="并发连接数限制"
subTitle=""
name="climiters"
api={API.climiters}
bordered
></ListCard>
</Col>
</Row>
</ProCard>
</Col>
<Col span={24}>
<ProCard boxShadow title="All Config JSON">
<pre>{jsonFormat(gostConfig)}</pre>
</ProCard>
</Col>
</Row>
</Row>
</Layout.Content>
</Layout>
) : (
<Home></Home>
)}
{gostInfo ? <Manage /> : <Home />}
</ConfigProvider>
</Ctx.Provider>
);
+177
View File
@@ -0,0 +1,177 @@
import { Button, Col, Layout, Row, Select, Space } from "antd";
import { logout, useGolstCofnig } from "../uitls/server";
import { download, jsonFormat } from "../uitls";
import Ctx from "../uitls/ctx";
import { useContext } from "react";
import * as API from "../api";
import ListCard from "../components/ListCard";
import ChainCard from "../components/ListCard/Chains";
import ServiceCard from "../components/ListCard/Services";
import { ProCard } from "@ant-design/pro-components";
const colSpan = {
xs: 24,
sm: 24,
md: 12,
lg: 12,
xl: 12,
xxl: 8,
};
const colSpan1 = {
sm: 24,
xxl: 8,
};
const Manage = () => {
const gostInfo = useGolstCofnig()!;
const { gostConfig } = useContext(Ctx);
return (
<Layout style={{ height: "100vh", overflow: "hidden" }}>
<Layout.Header style={{ color: "#FFF" }}>
<Row
align="middle"
justify="space-between"
wrap={false}
// style={{ padding: "0 15px" }}
>
<Col color="">
<Space>
<Select placeholder="快捷操作"></Select>
</Space>
</Col>
<Col>{gostInfo.addr}</Col>
<Col>
<Space>
<Button
// type="link"
onClick={() => {
API.saveCofnig();
}}
>
</Button>
<Button
// type="link"
onClick={() => {
download(jsonFormat(gostConfig!), "gost.json");
}}
>
</Button>
<Button type="link" onClick={logout}>
</Button>
</Space>
</Col>
</Row>
</Layout.Header>
<Layout.Content style={{ height: "100%", overflow: "auto" }}>
<Row style={{ padding: 16, overflow: "hidden" }}>
<Row gutter={[16, 16]}>
<Col {...colSpan}>
<ServiceCard></ServiceCard>
</Col>
<Col {...colSpan}>
<ChainCard></ChainCard>
</Col>
<Col {...colSpan}>
<ListCard
title="认证器(Auther)"
subTitle="认证器"
name="authers"
api={API.authers}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="准入控制器(Admission)"
subTitle="准入控制器"
name="admissions"
api={API.admissions}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="分流器(Bypass)"
subTitle="分流器"
name="bypass"
api={API.bypasses}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="主机映射器(Hosts)"
subTitle="主机映射器"
name="hosts"
api={API.hosts}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="跳跃点(Hop)"
subTitle="跳跃点"
name="hop"
api={API.hops}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="Ingress"
subTitle="Ingress"
name="ingresses"
api={API.ingresses}
></ListCard>
</Col>
<Col {...colSpan}>
<ListCard
title="域名解析器(Resolver)"
subTitle="Resolver"
name="resolvers"
api={API.resolvers}
></ListCard>
</Col>
<Col span={24}>
<ProCard boxShadow title="限速限流">
<Row gutter={[16, 16]}>
<Col {...colSpan1}>
<ListCard
title="流量速率限制"
subTitle=""
name="limiters"
api={API.limiters}
bordered
></ListCard>
</Col>
<Col {...colSpan1}>
<ListCard
title="请求速率限制"
subTitle=""
name="rlimiters"
api={API.rlimiters}
bordered
></ListCard>
</Col>
<Col {...colSpan1}>
<ListCard
title="并发连接数限制"
subTitle=""
name="climiters"
api={API.climiters}
bordered
></ListCard>
</Col>
</Row>
</ProCard>
</Col>
<Col span={24}>
<ProCard boxShadow title="All Config JSON">
<pre>{jsonFormat(gostConfig!)}</pre>
</ProCard>
</Col>
</Row>
</Row>
</Layout.Content>
</Layout>
);
};
export default Manage;
+11 -39
View File
@@ -1,12 +1,12 @@
import { useContext, useMemo, useState } from "react";
import { useContext } from "react";
import JsonForm from "./Json";
import templates from "../../uitls/templates";
import { Button, message } from "antd";
import { Button } from "antd";
import { getRESTfulApi } from "../../api";
import { PlusOutlined } from "@ant-design/icons";
import Ctx, { CardCtx } from "../../uitls/ctx";
import { CardCtx } from "../../uitls/ctx";
import { jsonParse } from "../../uitls";
import { GostCommit } from "../../api/local";
import { UseTemplates } from "../ListCard/hooks";
type Props = {
name: string;
@@ -17,48 +17,20 @@ type Props = {
};
const AddButton: React.FC<Props> = (props) => {
const { name, title, api, localApi } = props;
const { gostConfig } = useContext(Ctx);
const { localList, updateLocalList } = useContext(CardCtx);
const dataList = (gostConfig as any)?.[name] || [];
const dataSource = [...dataList, ...localList];
const ts = useMemo(() => {
return templates[name];
}, [name]);
const addService = async (servic: any) => {
const data = jsonParse(servic);
await api.post(data);
};
const { name, title } = props;
const { comm } = useContext(CardCtx);
const templates = UseTemplates({ name });
return (
<JsonForm
title={`添加 ${title || ""}`}
templates={ts}
templates={templates}
trigger={<Button icon={<PlusOutlined />} size="small" />}
onFinish={async (values: any) => {
// const { value } = values;
// await addService(value);
// return true;
const { value } = values;
const json = jsonParse(value);
let addName = json.name || `${name}-0`;
let rename = json.name ? false : true;
const hasName = () => {
return dataSource?.find((item: any) => {
return item.name === addName;
});
};
while (hasName()) {
addName = (addName as string).replace(/\d*$/, (a) => {
return String(a == "" ? "-0" : Number(a) + 1);
});
rename = true;
}
await addService(JSON.stringify({ ...json, name: addName }));
rename && message.info(`已自动处理 name 为 "${addName}"`);
return true;
await comm!.addValue(json);
return true
}}
></JsonForm>
);
+1 -1
View File
@@ -4,7 +4,7 @@ import { Button, Dropdown, Form, Space } from "antd";
import { DownOutlined } from "@ant-design/icons";
import { jsonFormat, jsonStringFormat, jsonParse } from "../../uitls";
import MonacoEditor, { MonacoEditorProps } from "react-monaco-editor";
import "./userMonacoWorker";
import "../../uitls/userMonacoWorker";
type Template = {
label: string;
-124
View File
@@ -1,124 +0,0 @@
import { useContext, useEffect, useMemo, useState } from "react";
import { Button, Popconfirm, Space, Table } from "antd";
import Ctx from "../../uitls/ctx";
import * as API from "../../api";
import JsonForm from "../Forms/Json";
import { ChainConfig } from "../../api/types";
import { jsonFormat, jsonParse } from "../../uitls";
import templates from "../../uitls/templates";
const Chains: React.FC = () => {
const { gostConfig, updateConfig } = useContext(Ctx);
const { chains } = gostConfig || {};
const [json, setJson] = useState<any>(null);
const [config, setConfig] = useState("");
const ts = useMemo(() => {
return templates["chains"];
}, []);
useEffect(() => {
if (json) {
setConfig(JSON.stringify(json));
}
}, [json]);
const addService = async (servic: any) => {
const data = jsonParse(servic);
await API.chains.post(data);
};
const updateService = async (id: string, servic: any) => {
const data = jsonParse(servic);
await API.chains.put(id, data);
};
const deleteService = async (servic: any) => {
if (json === servic) {
setJson(null);
}
await API.chains.delete(servic.name);
};
return (
<div style={{ height: 230, overflow: "auto" }}>
<Table
size="small"
dataSource={chains}
columns={[
{ title: "Name", dataIndex: "name", width: 100 },
{
title: "详情",
ellipsis: true,
render: (value, record: ChainConfig, index) => {
const { hops } = record;
const _hops = hops.map((hop) => {
const { nodes } = hop;
const _nodes = nodes.map((node) => {
const {
addr,
connector: { type: connectorType, auth },
dialer: { type: dialerType },
} = node;
const _auth = auth
? auth.username + ":" + auth.password + "@"
: "";
return `${connectorType}${
dialerType ? "+" + dialerType : ""
}://${_auth}${addr}`;
});
return _nodes.join(",");
});
return _hops.join(" -> ");
},
},
{
title: "操作",
width: 120,
render: (value, record, index) => {
return (
<Space size={"small"}>
<JsonForm
templates={ts}
trigger={
<Button type="link" size={"small"}>
</Button>
}
initialValues={{ value: jsonFormat(record) }}
onFinish={async (values: any) => {
const { value } = values;
await updateService(record.name, value);
return true;
}}
></JsonForm>
<Popconfirm
title="警告"
description="确定要删除吗?"
onConfirm={() => deleteService(record)}
>
<Button type="link" size={"small"}>
</Button>
</Popconfirm>
</Space>
);
},
},
]}
></Table>
<div>
<JsonForm
title="添加 Chains"
templates={ts}
trigger={<Button></Button>}
onFinish={async (values: any) => {
const { value } = values;
await addService(value);
return true;
}}
></JsonForm>
</div>
</div>
);
};
export default Chains;
+30 -48
View File
@@ -1,19 +1,19 @@
import { useContext, useMemo, useRef } from "react";
import { useContext } from "react";
import { Button, Popconfirm, Space, Table } from "antd";
import { red, green } from "@ant-design/colors";
import Ctx from "../../uitls/ctx";
import { getRESTfulApi } from "../../api";
import JsonForm from "../Forms/Json";
import { jsonFormat, jsonParse } from "../../uitls";
import templates from "../../uitls/templates";
import {
CheckCircleOutlined,
CopyOutlined,
DeleteOutlined,
EditOutlined,
StopOutlined,
} from "@ant-design/icons";
import { GostCommit } from "../../api/local";
import { CardCtx } from "../../uitls/ctx";
import { UseListData, UseTemplates } from "../ListCard/hooks";
type Props = {
name: string;
@@ -37,48 +37,9 @@ const PublicList: React.FC<Props> = (props) => {
keyName = "name",
renderConfig = defaultRenderConfig,
} = props;
const { gostConfig } = useContext(Ctx);
const { localList, updateLocalList } = useContext(CardCtx);
const dataList = (gostConfig as any)?.[name] || [];
const dataSource = [...dataList, ...localList];
const ts = useMemo(() => {
return templates[name];
}, [name]);
const comm = useRef({
updateValue: async (id: string, value: any) => {
const data = jsonParse(value);
await api.put(id, data);
},
deleteValue: async (value: any) => {
await api.delete(value.name);
},
dispatch: async (value: any) => {
const { deleteValue } = comm.current;
if (!localApi) return;
await deleteValue(value);
await localApi.add(value);
updateLocalList?.();
},
enable: async (value: any) => {
if (!localApi) return;
// console.log("enable", value);
await api.post(value);
await localApi.delete(value.name);
updateLocalList?.();
},
updateLocal: async (key: string, value: any) => {
if (!localApi) return;
const data = jsonParse(value);
await localApi.put(key, { ...data, name: key });
updateLocalList?.();
},
deleteLocal: async (value: any) => {
if (!localApi) return;
await localApi.delete(value.name);
updateLocalList?.();
},
});
const { localList, comm } = useContext(CardCtx);
const { dataList, dataSource } = UseListData({ localList, name });
const templates = UseTemplates({ name });
return (
<div style={{ height: 348, overflow: "auto" }}>
@@ -95,7 +56,7 @@ const PublicList: React.FC<Props> = (props) => {
},
{
title: "操作",
width: 90,
width: name === "services" ? 120 : 90,
align: "right",
dataIndex: keyName,
render: (value, record, index) => {
@@ -107,7 +68,9 @@ const PublicList: React.FC<Props> = (props) => {
enable,
updateLocal,
deleteLocal,
} = comm.current;
addValue,
// } = comm.current;
} = comm!;
const isEnable = dataList.includes(record);
return (
<Space size={2}>
@@ -144,7 +107,7 @@ const PublicList: React.FC<Props> = (props) => {
) : null}
<JsonForm
title={`修改 ${value || ""}`}
templates={ts}
templates={templates}
trigger={
<Button
title="修改"
@@ -165,6 +128,25 @@ const PublicList: React.FC<Props> = (props) => {
}
}}
></JsonForm>
<JsonForm
title={`复制自 ${value || ""}`}
templates={templates}
trigger={
<Button
title="复制"
icon={<CopyOutlined />}
type="link"
size={"small"}
/>
}
initialValues={{ value: jsonFormat(record) }}
onFinish={async (values: any) => {
const { value } = values;
const json = jsonParse(value);
await comm!.addValue(json);
return true;
}}
></JsonForm>
<Popconfirm
title="警告"
description="确定要删除吗?"
-152
View File
@@ -1,152 +0,0 @@
import { useContext, useEffect, useMemo, useState } from "react";
import { Button, Popconfirm, Space, Table, message } from "antd";
import qs from "qs";
// import { ProTable, ProCard } from "@ant-design/pro-components";
import Ctx from "../../uitls/ctx";
import * as API from "../../api";
import JsonForm from "../Forms/Json";
import { ServiceConfig } from "../../api/types";
import templates from "../../uitls/templates";
import { jsonFormat, jsonParse } from "../../uitls";
const Services: React.FC = () => {
const { gostConfig, updateConfig } = useContext(Ctx);
const { services: dataList } = gostConfig || {};
const [json, setJson] = useState<any>(null);
const [config, setConfig] = useState("");
const ts = useMemo(() => {
return templates["services"];
}, []);
useEffect(() => {
if (json) {
setConfig(JSON.stringify(json));
}
}, [json]);
const submit = async (v?: string) => {
const data = jsonParse(v || config);
if (json) {
await API.services.put(data.name, data);
} else {
await API.services.post(data);
}
};
const addService = async (servic: any) => {
const data = jsonParse(servic);
await API.services.post(data);
};
const updateService = async (id: string, servic: any) => {
const data = jsonParse(servic);
await API.services.put(id, data);
};
const deleteService = async (servic: any) => {
if (json === servic) {
setJson(null);
}
await API.services.delete(servic.name);
};
return (
<div style={{ height: 230, overflow: "auto" }}>
<Table
size="small"
dataSource={dataList}
pagination={false}
columns={[
{ title: "Name", dataIndex: "name", width: 100 },
{
title: "详情",
ellipsis: true,
render: (value, record: ServiceConfig, index) => {
const { handler, listener, addr, forwarder } = record;
const xy =
handler.type === listener.type
? handler.type
: handler.type + "+" + listener.type;
const auth = handler.auth
? handler.auth.username + ":" + handler.auth.password + "@"
: "";
const metadata = handler.metadata
? qs.stringify(handler.metadata)
: "";
const targets =
forwarder?.nodes.map((item) => item.addr).join(",") || "";
return `${xy}://${auth}${addr}${targets ? "/" + targets : ""}${
metadata ? "?" + metadata : ""
}`;
},
},
{
title: "操作",
width: 120,
render: (value, record, index) => {
return (
<Space size={"small"}>
<JsonForm
layoutType="ModalForm"
templates={ts}
trigger={
<Button type="link" size={"small"}>
</Button>
}
initialValues={{ value: jsonFormat(record) }}
onFinish={async (values: any) => {
const { value } = values;
await updateService(record.name, value);
return true;
}}
></JsonForm>
<Popconfirm
title="警告"
description="确定要删除吗?"
onConfirm={() => deleteService(record)}
// okText="Yes"
// cancelText="No"
>
<Button type="link" size={"small"}>
</Button>
</Popconfirm>
</Space>
);
},
},
]}
></Table>
{/* <div>
<JsonForm
title="添加 Services"
templates={ts}
trigger={<Button>{"新增"}</Button>}
// initialValues={{ value: "" }}
onFinish={async (values: any) => {
const { value } = values;
const json = jsonParse(value);
let addName = json.name || "services-0";
let rename = json.name ? false : true;
const hasName = () => {
return dataList?.find((item) => {
return item.name === addName;
});
};
while (hasName()) {
addName = (addName as string).replace(/\d*$/, (a) => {
return String(a == "" ? "-0" : Number(a) + 1);
});
rename = true;
}
await addService(JSON.stringify({ ...json, name: addName }));
rename && message.info(`name 已自动处理为 "${addName}"`);
return true;
}}
></JsonForm>
</div> */}
</div>
);
};
export default Services;
+33
View File
@@ -0,0 +1,33 @@
import Ctx, { CardCtx } from "../../uitls/ctx";
import ConfigTemplates from "../../uitls/templates";
import { useContext, useMemo } from "react";
type UseListDataProps = {
name: string;
localList?: any[];
};
export const UseTemplates = (props: { name: string }) => {
const { name } = props;
const templates = useMemo(() => {
return ConfigTemplates[name];
}, [name]);
return templates;
};
export const UseListData = (props: UseListDataProps) => {
const { localList = [], name } = props;
const { gostConfig } = useContext(Ctx);
const dataList = useMemo(
() => (gostConfig as any)?.[name] || [],
[gostConfig, name]
);
const dataSource = useMemo(
() => [...dataList, ...localList],
[dataList, localList]
);
return {
dataList,
dataSource,
};
};
+88 -3
View File
@@ -1,10 +1,18 @@
import {
useCallback,
useEffect,
useState,
useMemo,
} from "react";
import { getRESTfulApi } from "../../api";
import { ProCard } from "@ant-design/pro-components";
import PublicList from "../List/Public";
import AddButton from "../Forms/AddButton";
import { GostCommit } from "../../api/local";
import { CardCtx } from "../../uitls/ctx";
import { useCallback, useEffect, useState } from "react";
import { CardCtx, Comm } from "../../uitls/ctx";
import { jsonParse } from "../../uitls";
import { UseListData } from "./hooks";
import { Modal, notification } from "antd";
export type ListCardProps = {
name: string;
@@ -46,12 +54,89 @@ const ListCard: React.FC<ListCardProps> = (props) => {
setLocalList(data);
});
}, [localApi]);
const addService = useCallback(
async (servic: any) => {
const data = jsonParse(servic);
await api.post(data);
},
[api]
);
useEffect(() => {
updateLocalList();
}, [updateLocalList]);
const { dataSource } = UseListData({ name, localList });
const comm = useMemo<Comm>(
() => ({
updateValue: async (id: string, value: any) => {
const data = jsonParse(value);
await api.put(id, data);
},
deleteValue: async (value: any) => {
await api.delete(value.name);
},
addValue: async (json: any) => {
let addName = json.name || `${name}-0`;
const hasName = () => {
return dataSource?.find((item: any) => {
return item.name === addName;
});
};
if (hasName()) {
const confirmed = await new Promise((resolve, reject) => {
Modal.confirm({
title: "name无效",
content: "是否自动分配name",
zIndex: 2000,
onOk: () => resolve(true),
onCancel: () => resolve(false),
});
});
if (!confirmed) throw false;
}
while (hasName()) {
addName = (addName as string).replace(/\d*$/, (a) => {
return String(a == "" ? "-0" : Number(a) + 1);
});
}
await addService(JSON.stringify({ ...json, name: addName }));
(json.name !== addName) &&
notification.info({
description: `新分配 name 为 "${addName}"`,
message: "自动修正提醒",
});
},
dispatch: async (value: any) => {
if (!localApi) return;
await api.delete(value.name);
await localApi.add(value);
updateLocalList?.();
},
enable: async (value: any) => {
if (!localApi) return;
await api.post(value);
await localApi.delete(value.name);
updateLocalList?.();
},
updateLocal: async (key: string, value: any) => {
if (!localApi) return;
const data = jsonParse(value);
await localApi.put(key, { ...data, name: key });
updateLocalList?.();
},
deleteLocal: async (value: any) => {
if (!localApi) return;
await localApi.delete(value.name);
updateLocalList?.();
},
}),
[addService, api, dataSource, localApi, name, updateLocalList]
);
return (
<CardCtx.Provider value={{ localList, updateLocalList }}>
<CardCtx.Provider value={{ localList, updateLocalList, name, comm }}>
<ProCard
boxShadow={boxShadow}
bordered={bordered}
+1 -1
View File
@@ -1,6 +1,6 @@
import { Select } from "antd"
// 快捷操作
const Quicksetup:React.FC = ()=>{
return <Select>
+14 -1
View File
@@ -6,10 +6,23 @@ type GostCtx = {
updateConfig?: () => PromiseLike<object>;
logout?: () => void;
};
export type Comm = {
updateValue: (id: string, value: any) => Promise<void>;
deleteValue: (value: any) => Promise<void>;
addValue: (json: any) => Promise<void>;
dispatch: (value: any) => Promise<void>;
enable: (value: any) => Promise<void>;
updateLocal: (key: string, value: any) => Promise<void>;
deleteLocal: (value: any) => Promise<void>;
};
const Ctx = React.createContext<GostCtx>({});
export default Ctx;
export const CardCtx = React.createContext<{
name: string;
localList: any[];
updateLocalList?: () => void;
}>({localList:[]});
comm?: Comm;
}>({ localList: [], name: "" });
@@ -1,37 +1,37 @@
/* eslint-disable */
import * as monaco from "monaco-editor";
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
// import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
// import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
// import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
// @ts-ignore
// import { language as yamlLanguage } from "monaco-editor/esm/vs/basic-languages/yaml/yaml";
// eslint-disable-next-line
// @ts-ignore
self.MonacoEnvironment = {
getWorker(_: any, label: string) {
console.log('[label]',label);
// setLocaleData(zh_CN.contents);
if (label === "json") {
return new jsonWorker();
}
// if (label === "css" || label === "scss" || label === "less") {
// return new cssWorker();
// }
// if (label === "html" || label === "handlebars" || label === "razor") {
// return new htmlWorker();
// }
// if (label === "typescript" || label === "javascript") {
// return new tsWorker();
// }
return new editorWorker();
},
};
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
allowComments: true,
trailingCommas: 'warning',
})
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
/* eslint-disable */
import * as monaco from "monaco-editor";
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
// import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
// import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
// import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
// @ts-ignore
// import { language as yamlLanguage } from "monaco-editor/esm/vs/basic-languages/yaml/yaml";
// eslint-disable-next-line
// @ts-ignore
self.MonacoEnvironment = {
getWorker(_: any, label: string) {
console.log('[label]',label);
// setLocaleData(zh_CN.contents);
if (label === "json") {
return new jsonWorker();
}
// if (label === "css" || label === "scss" || label === "less") {
// return new cssWorker();
// }
// if (label === "html" || label === "handlebars" || label === "razor") {
// return new htmlWorker();
// }
// if (label === "typescript" || label === "javascript") {
// return new tsWorker();
// }
return new editorWorker();
},
};
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
allowComments: true,
trailingCommas: 'warning',
})
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);