fix:intelligent plugin & browser lang & check monitor config

This commit is contained in:
maggieyyy
2024-08-28 14:07:55 +08:00
parent 31cb70ed02
commit 9c8418ab40
18 changed files with 137 additions and 100 deletions
@@ -242,13 +242,13 @@ const themeToken = {
];
}}
headerTitleRender={() => (
<div className="w-[192px] flex items-center">
<img
className="h-[20px] cursor-pointer "
src={Logo}
onClick={()=> navigator(mainPage)}
/>
</div>
<div className="w-[192px] flex items-center">
<img
className="h-[20px] cursor-pointer "
src={Logo}
onClick={()=> navigator(mainPage)}
/>
</div>
)}
logo={Logo}
pageTitleRender={()=>$t('APIPark - 企业API数据开放平台')}
@@ -27,7 +27,13 @@ const LanguageSetting = ({mode = 'light'}:{mode?:'dark'|'light'}) => {
const langLabel = useMemo(()=>items.find((item) => item?.key === state.language)?.title,[state.language])
useEffect(()=>{
sessionStorage.getItem('i18nextLng') && dispatch({ type: 'UPDATE_LANGUAGE', language: sessionStorage.getItem('i18nextLng') as 'en' | 'cn' });
const savedLang = sessionStorage.getItem('i18nextLng')
const browserLang = navigator.language || navigator.userLanguage
if(savedLang){
dispatch({ type: 'UPDATE_LANGUAGE', language: savedLang.startsWith('cn') ? 'cn' : 'en' });
}else{
dispatch({ type: 'UPDATE_LANGUAGE', language: browserLang.startsWith('zh') ? 'cn' : 'en' });
}
},[
])
return (
@@ -40,7 +46,6 @@ const LanguageSetting = ({mode = 'light'}:{mode?:'dark'|'light'}) => {
const { key } = e;
dispatch({ type: 'UPDATE_LANGUAGE', language: key });
i18n.changeLanguage(key);
// window.location.reload()
}
}}
>
@@ -38,6 +38,12 @@ export const TranslateWord = ()=>{
{$t('鉴权Secret')}
{$t('网络协议')}
{$t('日志等级')}
{$t('单行')}
{$t('小时')}
{$t('天')}
{$t('未发布')}
{$t('待发布')}
{$t('单位:s,最小值:1')}
</>
)
}
@@ -26,7 +26,6 @@ const WithPermission = ({access, tooltip, children,disabled, showDisabled = true
useEffect(()=>{
// 先判断权限,无论权限是否为true,如果disabled为true时则必须为ture
access && setEditAccess(lastAccess)
console.log('editAccess',editAccess, children,children?.type?.displayName,showDisabled, children?.type?.displayName !== 'Button' && showDisabled)
},[lastAccess,disabled])
@@ -48,6 +48,7 @@ import {useFetch} from "@common/hooks/http.ts";
import {App, Descriptions} from "antd";
import { $t } from "@common/locales";
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
import { setValidateLanguage } from '@formily/core'
export const DynamicRender = (props) => {
const {schema} = props
@@ -68,14 +69,12 @@ export const DynamicRender = (props) => {
const translateSchema = (render) =>{
console.log(render)
const res1 = {
...render,
...(render.title ? {title:$t(render.title)} : {}),
...(render.description) ? {description:$t(render.description)} : {},
...(render.label ? {label:$t(render.label)} : {}),
...(render.properties ? {properties: Object.keys(render.properties).reduce((total, cur) => {
console.log(total, cur); // 可选:在生产环境中移除或注释掉
try {
total[cur] = translateSchema(render.properties[cur]);
} catch (error) {
@@ -86,7 +85,7 @@ export const DynamicRender = (props) => {
...(render.items && Array.isArray(render.items) ? {items:render.items.map(x=>translateSchema(x))} : {}),
...(render.items && !Array.isArray(render.items) ? {items:translateSchema(render.items)} : {}),
...(render.additionalProperties ? {additionalProperties: translateSchema(render.additionalProperties)} : {}),
...(render.enum ?render.enum.map(x=>({...x, label:$t(x.label)})) : {}),
...(render.enum ? {enum: render.enum.map(x=>({...x, label:$t(x.label)}))} : {}),
}
return res1
@@ -174,6 +173,11 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
const {fetchData} = useFetch()
const form = createForm({ validateFirst: type === 'edit' })
form.setInitialValues(initFormValue || {})
const { state } = useGlobalContext()
useEffect(()=>{
setValidateLanguage(state.language === 'cn' ? 'zh-CN' : 'en-US')
},[state.language])
const pluginEditSchema = {
type: 'object',
@@ -313,7 +317,7 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
}
return (
<div className="pl-[12px]">
<FormProvider form={form}>
<FormProvider form={form} >
<SchemaField
schema={pluginEditSchema}
scope={{ useAsyncDataSource, getSkillData, form }}
@@ -97,7 +97,7 @@ export default function IntelligentPluginList(){
const [tableListDataSource, setTableListDataSource] = useState<DynamicTableItem[]>([]);
const [tableHttpReload, setTableHttpReload] = useState(true);
const [columns,setColumns] = useState<PageProColumns<DynamicTableItem>[] >([])
const [columns,setColumns] = useState<DynamicTableField[] >([])
const {fetchData} = useFetch()
const pageListRef = useRef<ActionType>(null);
const [publishBtnLoading, setPublishBtnLoading] = useState<boolean>(false)
@@ -133,20 +133,7 @@ export default function IntelligentPluginList(){
message.destroy();
if(res.code === STATUS_CODE.SUCCESS){
getConfig(res.data)
setColumns(res.data.basic.fields.map((field:DynamicTableField, index:number)=>({
title:field.title,
dataIndex:field.name,
fixed:field.name === 'title' ? 'left' : undefined,
ellipsis:true,
width:field.name === 'title' ? 150 : undefined,
...(field.enum?.length > 0 ?{
onFilter: (value: string, record: { [x: string]: string | string[]; }) => record[field.name].indexOf(value) === 0,
filters:field.enum?.map((x:string)=>{return {text:x, value:x}}),
render:(_: unknown, entity: { [x: string]: string; })=> {
return <span className={StatusColorClass[entity[field.name] as keyof typeof StatusColorClass]}>{(entity[field.name] as string)}</span>
},
}:{}),
})))
setColumns(res.data.basic.fields)
setTableListDataSource(res.data.list);
return ({ data: res.data.list, success: true,total:res.data.total });
}else{
@@ -157,7 +144,22 @@ export default function IntelligentPluginList(){
return ({ data: [], success: false });})
}
const translatedCol = useMemo(()=>columns.map(x=>({...x, title:typeof x.title === 'string' ? $t(x.title as string) : x.title})),[columns,state.language])
const translatedCol = useMemo(()=>columns.map((field:DynamicTableField, index:number)=>({
title: typeof field.title === 'string' ? $t(field.title as string): field.title,
dataIndex:field.name,
fixed:field.name === 'title' ? 'left' : undefined,
ellipsis:true,
width:field.name === 'title' ? 150 : undefined,
...(field.enum?.length > 0 ?{
onFilter: (value: string, record: { [x: string]: string | string[]; }) => record[field.name].indexOf(value) === 0,
filters:field.enum?.map((x:string)=>{return {text:$t(x), value:x}}),
render:(_: unknown, entity: { [x: string]: string; })=> {
return <span className={StatusColorClass[entity[field.name] as keyof typeof StatusColorClass]}>{$t(entity[field.name] as string)}</span>
},
}:{}),
})),[state.language,columns])
const getConfig = (data:DynamicTableConfig)=>{
const {basic,list } = data
@@ -331,7 +333,7 @@ export default function IntelligentPluginList(){
onSearchWordChange={(e)=>{setSearchWord(e.target.value);setTableHttpReload(true);setTableHttpReload(true)}}
/>
<DrawerWithFooter title={`${drawerType === 'add' ? $t('添加') : $t('编辑')}${pluginName }`} open={drawerOpen} onClose={()=>{setCurDetail(undefined);setDrawerOpen(false)}} onSubmit={()=>drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} submitAccess=''>
<DrawerWithFooter title={`${drawerType === 'add' ? $t('添加(0)',[$t(pluginName)]) : $t('编辑(0)',[$t(pluginName)])}`} open={drawerOpen} onClose={()=>{setCurDetail(undefined);setDrawerOpen(false)}} onSubmit={()=>drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} submitAccess=''>
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={drawerLoading}>
<IntelligentPluginConfig
ref={drawerFormRef!}
@@ -616,5 +616,30 @@
"K9919285b": "Service Type",
"Kf14d159b": "Times",
"K753e8aeb": "TPS",
"K21ad4a6a": "(0) Payload"
"K21ad4a6a": "(0) Payload",
"Kda249fe8": "Failed Request",
"Kcf2df651": "Failed Forwarding",
"K7e6a859d": "Scope",
"K3a008b34": "Add Entry",
"Ke0599ef7": "Add Address",
"K48d3b5c4": "File Name",
"Kafde0d2a": "Storage Directory",
"Kfb2926ac": "Log Rotation Period",
"Kd96c2c69": "Unit: Days",
"Kc2b776fa": "Output Format",
"K7b7cdac2": "Format Configuration",
"K2f59807a": "Server Address",
"K540488a8": "NSQD Address List",
"K8bc33a11": "Authentication Secret",
"K1cd3002f": "Network Protocol",
"Kdfaa32c8": "Log Level",
"Ka46b9b24": "Data Source Type",
"Kbb0cdcd0": "Data Source Address",
"Kd9dfb884": "Organization",
"Kc0408d9c": "Single line",
"Ke3db239d": "Hour",
"K3509a9f8": "Day",
"Kb3960e83": "Unpublished",
"K8bd1e18": "Pending",
"K225a6c43": "Unit: Seconds, Minimum Value: 1"
}
@@ -1,21 +1,2 @@
{
"Kda249fe8": "请求失败数",
"Kcf2df651": "转发失败数",
"K7e6a859d": "作用范围",
"K3a008b34": "添加条目",
"Ke0599ef7": "添加地址",
"K48d3b5c4": "文件名称",
"Kafde0d2a": "存放目录",
"Kfb2926ac": "日志分割周期",
"Kd96c2c69": "单位:天",
"Kc2b776fa": "输出格式",
"K7b7cdac2": "格式化配置",
"K2f59807a": "服务器地址",
"K540488a8": "NSQD地址列表",
"K8bc33a11": "鉴权Secret",
"K1cd3002f": "网络协议",
"Kdfaa32c8": "日志等级",
"Ka46b9b24": "数据源类型",
"Kbb0cdcd0": "数据源地址",
"Kd9dfb884": "Organization"
}
@@ -1,27 +1,2 @@
{
"K54630fe8": "Kafka日志",
"Kd5c3966e": "NSQ日志",
"K2e3de2c1": "Syslog日志",
"Kda249fe8": "请求失败数",
"Kcf2df651": "转发失败数",
"K7e6a859d": "作用范围",
"K3a008b34": "添加条目",
"Ke0599ef7": "添加地址",
"K48d3b5c4": "文件名称",
"Kafde0d2a": "存放目录",
"Kfb2926ac": "日志分割周期",
"Kd96c2c69": "单位:天",
"Kc2b776fa": "输出格式",
"K7b7cdac2": "格式化配置",
"K2f59807a": "服务器地址",
"Kb1cfa6e7": "Access日志",
"K540488a8": "NSQD地址列表",
"K8bc33a11": "鉴权Secret",
"K1cd3002f": "网络协议",
"Kdfaa32c8": "日志等级",
"Ka46b9b24": "数据源类型",
"Kbb0cdcd0": "数据源地址",
"Kd9dfb884": "Organization",
"K2a49373f": "同步地址",
"K21ad4a6a": "(0)报文量"
}
@@ -613,5 +613,11 @@
"K8dc5c723": "驱动名称",
"Kf14d159b": "次",
"K753e8aeb": "次/秒",
"K21ad4a6a": "(0)报文大小"
"K21ad4a6a": "(0)报文大小",
"Kc0408d9c": "单行",
"Ke3db239d": "小时",
"K3509a9f8": "天",
"Kb3960e83": "未发布",
"K8bd1e18": "待发布",
"K225a6c43": "单位:s,最小值:1"
}
+2 -3
View File
@@ -11,7 +11,6 @@ import { useEffect, useMemo, useState } from 'react';
import 'dayjs/locale/zh-cn';
import dayjs from 'dayjs';
import { useGlobalContext } from '@common/contexts/GlobalStateContext';
import i18next from 'i18next';
import { $t } from '@common/locales';
type Locale = ConfigProviderProps['locale'];
@@ -141,11 +140,11 @@ const antdComponentThemeToken = {
function App() {
const [locale, setLocal] = useState<Locale>(sessionStorage.getItem('i18nextLng') === 'cn'? zhCN : enUS);
dayjs.locale(sessionStorage.getItem('i18nextLng') || 'en');
const [locale, setLocal] = useState<Locale>();
useInitializeMonaco()
const { state} = useGlobalContext()
useEffect(() => {
dayjs.locale(state.language);
setLocal(state.language === 'cn' ? zhCN : enUS);
@@ -39,8 +39,6 @@ const LogSettings = ()=>{
const menuData = useMemo(()=>{
const newMenu = menuItems?.map((x:DynamicMenuItem)=>{
console.log(state.language, $t(x.title))
return getItem(
<Link to={`template/${x.name}`}>{$t(x.title)}</Link>,
x.name,
@@ -49,7 +47,6 @@ const LogSettings = ()=>{
undefined,
'system.devops.log_configuration.view')
})
console.log(newMenu)
return newMenu
},[state.language,menuItems])
@@ -332,10 +332,7 @@ const MemberList = ()=>{
}
})
}
useEffect(()=>{
console.log(roleSelectableList,roleSelectableList?.map((x:{id:string,name:string})=>({label:$t(x.name), value:x.id})) )
},[state.language,roleSelectableList])
const translatedCol = useMemo(
()=> MEMBER_TABLE_COLUMNS.map((x)=>({...x, ...(x.dataIndex === 'roles' ? {
render:(_,entity)=>(
@@ -49,7 +49,6 @@ const LogSettings = ()=>{
undefined,
'system.devops.log_configuration.view')
})
console.log(newMenu)
return newMenu
},[state.language,menuItems])
@@ -165,7 +165,6 @@ const SystemInsideApprovalList:FC = ()=>{
return filteredCol.map(x=>{
if(x.filters &&((x.dataIndex as string[])?.indexOf('applier') !== -1 || (x.dataIndex as string[])?.indexOf('approver') !== -1) ){
const tmpValueEnum :Record<string,{text:string}>= {}
console.log(memberValueEnum)
memberValueEnum?.forEach((x:SimpleMemberItem)=>{
tmpValueEnum[x.name] = {text:$t(x.name)}
})
@@ -31,7 +31,6 @@ const MonitorPieGraph: FC<PieGraphProps> = ({ className,title, pieData, labelNam
tooltip: {
trigger: 'item',
formatter: (params:Array<Record<string,unknown>>) => {
console.log(params)
const startHtml = '<div><section style="align-items: center;display:flex; justify-content: space-between;flex-wrap: nowrap;"><span> ' + $t(title) + '</span></div>'
return startHtml + ($t(params.name || '-') + '&nbsp&nbsp&nbsp </span><span style="font-weight:bold"> ' + params.value + '</span></section></div>')
}
@@ -1,26 +1,62 @@
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
import DashboardPage from "./DashboardTabPage";
import { $t } from "@common/locales";
import { useFetch } from "@common/hooks/http";
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const";
import { App, Spin } from "antd";
import { reject } from "lodash-es";
import { EntityItem } from "@common/const/type";
import { LoadingOutlined } from "@ant-design/icons";
import DashboardInstruction from "./DashboardInstruction";
import cluster from "cluster";
export default function Dashboard(){
const { setBreadcrumb } = useBreadcrumb()
const {fetchData } = useFetch()
const { message } = App.useApp()
const [clusters, setClusters] = useState<Array<{id:string, name:string, enable:boolean}>>([])
const [enabledClusters, setEnabledClusters] = useState<Array<EntityItem>>([])
const [loading, setLoading] = useState(false)
const getClusters = ()=>{
setLoading(true)
fetchData<BasicResponse<{clusters:Array<{id:string, name:string, enable:boolean}>}>>('simple/monitor/clusters',{
method: 'GET'}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
const filteredCluster = data?.clusters?.filter(x=>x.enable)
setClusters(data.cluster || [])
setEnabledClusters(filteredCluster)
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
}
}).catch((errorInfo)=> reject(errorInfo)).finally(()=>setLoading(false))
}
useEffect(() => {
getClusters()
setBreadcrumb([
{
title:$t('运行视图')
},
])
}, []);
return (
<>
<div className="h-full w-full pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B ">
<DashboardPage />
</div>
<Spin wrapperClassName="h-full w-full pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B " indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={loading}>
{
!loading && <>
{
enabledClusters.length > 0 ?
<DashboardPage /> : <DashboardInstruction showClusterIns={clusters.length === 0} showMonitorIns={enabledClusters.length === 0}/>
}
</>
}
</Spin>
</>
)
}
@@ -1,7 +1,7 @@
import { Link } from "react-router-dom";
export default function DashboardInstruction() {
export default function DashboardInstruction({showClusterIns, showMonitorIns}:{showClusterIns:boolean, showMonitorIns:boolean}) {
return (
<div className="h-full w-full overflow-auto">
<div className=" m-auto mt-[10%] flex flex-col items-center p-[20px]">
@@ -10,12 +10,20 @@ export default function DashboardInstruction() {
{/* <p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT mt-[8px]">更多配置问题,请点击帮助中心
{/* <a>查看更多</a> *
</p> */}
<div className="flex mt-[28px]">
<div className="h-[208px] w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px]">
<div className="flex mt-[28px] gap-[20px] w-full justify-center items-center">
{showClusterIns && <div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px]">
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT"></p>
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT"></p>
<p><Link to="/cluster"></Link></p>
</div>
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT"></p>
<p><a href="/cluster" target="_blank"></a></p>
</div>}
{showMonitorIns &&
<div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG ">
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT"></p>
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">API调用统计图表</p>
<p><a href="/dashboardsetting" target="_blank"></a></p>
</div>
}
</div>
</div></div>
)