\n );\n};\n\nexport default SideMenu;\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport { Button, Result } from 'antd';\nimport React from 'react';\nimport { useHistory } from 'react-router';\n\nconst NotFound: React.FC = () => {\n const history = useHistory();\n return (\n
\n history.replace('/')}>\n 回到首页\n \n }\n />\n
\n );\n};\n\nexport default NotFound;\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport { Button, Result } from 'antd';\nimport React from 'react';\nimport { useHistory } from 'react-router';\n\nconst NotFound: React.FC = () => {\n const history = useHistory();\n return (\n
\n history.go(-2)}>\n 返回上一页\n \n }\n />\n
\n );\n};\n\nexport default NotFound;\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { useState, useEffect } from 'react';\nimport { Form, Input, Button, message } from 'antd';\nimport { useHistory, useLocation } from 'react-router-dom';\nimport { UserOutlined, LockOutlined } from '@ant-design/icons';\nimport { getSsoConfig, getRedirectURL, getRedirectURLCAS, getRedirectURLOAuth, authLogin } from '@/services/login';\nimport './login.less';\n\nimport { useTranslation } from 'react-i18next';\nexport interface DisplayName {\n oidc: string;\n cas: string;\n oauth: string;\n}\nexport default function Login() {\n const { t } = useTranslation();\n const [form] = Form.useForm();\n const history = useHistory();\n const location = useLocation();\n const redirect = location.search && new URLSearchParams(location.search).get('redirect');\n const [displayName, setDis] = useState({\n oidc: 'OIDC',\n cas: 'CAS',\n oauth: 'OAuth',\n });\n\n useEffect(() => {\n getSsoConfig().then((res) => {\n if (res.dat) {\n setDis({\n oidc: res.dat.oidcDisplayName,\n cas: res.dat.casDisplayName,\n oauth: res.dat.oauthDisplayName,\n });\n }\n });\n }, []);\n\n const handleSubmit = async () => {\n try {\n await form.validateFields();\n login();\n } catch {\n console.log(t('输入有误'));\n }\n };\n\n const login = async () => {\n let { username, password } = form.getFieldsValue();\n authLogin(username, password).then((res) => {\n const { dat, err } = res;\n const { access_token, refresh_token } = dat;\n localStorage.setItem('access_token', access_token);\n localStorage.setItem('refresh_token', refresh_token);\n if (!err) {\n window.location.href = redirect || '/metric/explorer';\n }\n });\n };\n\n return (\n
\n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { useState, useEffect, useRef } from 'react';\n\nexport default function Overview() {\n return ;\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { useEffect, useState } from 'react';\nimport { useLocation } from 'react-router';\nimport queryString from 'query-string';\nimport { authCallback } from '@/services/login';\n\nexport default function index() {\n const location = useLocation();\n const query = queryString.parse(location.search);\n const [err, setErr] = useState();\n\n useEffect(() => {\n authCallback({\n code: query.code,\n state: query.state,\n redirect: query.redirect || '/',\n })\n .then((res) => {\n if (res.err === '') {\n if (res.dat && res.dat.access_token && res.dat.refresh_token) {\n localStorage.setItem('access_token', res.dat.access_token);\n localStorage.setItem('refresh_token', res.dat.refresh_token);\n window.location.href = res.dat.redirect;\n } else {\n console.log(res.dat);\n }\n } else {\n setErr(res.err);\n }\n })\n .catch((res) => {\n setErr(res.message);\n });\n }, []);\n if (err === undefined) return null;\n return (\n
\n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { useEffect, useState } from 'react';\nimport { useLocation } from 'react-router';\nimport queryString from 'query-string';\nimport { authCallbackCAS } from '@/services/login';\n\nexport default function index() {\n const location = useLocation();\n const query = queryString.parse(location.search);\n const [err, setErr] = useState();\n\n useEffect(() => {\n authCallbackCAS({\n ticket: query.ticket,\n state: localStorage.getItem(\"CAS_state\"),\n redirect: query.redirect || '/',\n })\n .then((res) => {\n if (res.err === '') {\n if (res.dat && res.dat.access_token && res.dat.refresh_token) {\n localStorage.setItem('access_token', res.dat.access_token);\n localStorage.setItem('refresh_token', res.dat.refresh_token);\n window.location.href = res.dat.redirect;\n localStorage.removeItem(\"CAS_state\");\n } else {\n console.log(res.dat);\n }\n } else {\n setErr(res.err);\n }\n })\n .catch((res) => {\n setErr(res.message);\n });\n }, []);\n if (err === undefined) return null;\n return (\n
\n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { useEffect, useState } from 'react';\nimport { useLocation } from 'react-router';\nimport queryString from 'query-string';\nimport { authCallbackOAuth } from '@/services/login';\n\nexport default function index() {\n const location = useLocation();\n const query = queryString.parse(location.search);\n const [err, setErr] = useState();\n\n useEffect(() => {\n authCallbackOAuth({\n code: query.code,\n state: query.state,\n redirect: query.redirect || '/',\n })\n .then((res) => {\n if (res.err === '') {\n if (res.dat && res.dat.access_token && res.dat.refresh_token) {\n localStorage.setItem('access_token', res.dat.access_token);\n localStorage.setItem('refresh_token', res.dat.refresh_token);\n window.location.href = res.dat.redirect;\n } else {\n console.log(res.dat);\n }\n } else {\n setErr(res.err);\n }\n })\n .catch((res) => {\n setErr(res.message);\n });\n }, []);\n if (err === undefined) return null;\n return (\n
\n );\n}\n","const en_US = {\n profile: 'Profile',\n logout: 'Logout',\n docs: 'Docs',\n};\nexport default en_US;\n","const zh_CN = {\n profile: '个人信息',\n logout: '退出',\n docs: '文档',\n};\nexport default zh_CN;\n","const zh_HK = {\n profile: '個人信息',\n logout: '退出',\n docs: '文檔',\n};\nexport default zh_HK;\n","import i18next from 'i18next';\nimport en_US from './en_US';\nimport zh_CN from './zh_CN';\nimport zh_HK from './zh_HK';\n\ni18next.addResourceBundle('en_US', 'pageLayout', en_US);\ni18next.addResourceBundle('zh_CN', 'pageLayout', zh_CN);\ni18next.addResourceBundle('zh_HK', 'pageLayout', zh_HK);\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { ReactNode, useContext } from 'react';\nimport { useHistory } from 'react-router-dom';\nimport Icon, { RollbackOutlined } from '@ant-design/icons';\nimport { useTranslation } from 'react-i18next';\nimport { Menu, Dropdown } from 'antd';\nimport { DownOutlined } from '@ant-design/icons';\nimport { Logout } from '@/services/login';\nimport AdvancedWrap, { License } from '@/components/AdvancedWrap';\nimport { CommonStateContext } from '@/App';\nimport './index.less';\nimport './locale';\n\ninterface IPageLayoutProps {\n icon?: ReactNode;\n title?: String | JSX.Element;\n children?: ReactNode;\n introIcon?: ReactNode;\n rightArea?: ReactNode;\n customArea?: ReactNode;\n showBack?: Boolean;\n backPath?: string;\n docFn?: Function;\n}\n\nconst PageLayout: React.FC = ({ icon, title, rightArea, introIcon, children, customArea, showBack, backPath, docFn }) => {\n const { t, i18n } = useTranslation('pageLayout');\n const history = useHistory();\n const { profile } = useContext(CommonStateContext);\n\n const menu = (\n \n );\n\n return (\n
\n {\n setRefreshFlag(_.uniqueId('refreshFlag_'));\n }}\n />\n \n );\n};\n\nexport default Targets;\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React from 'react';\nimport { Link } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { InfoCircleOutlined } from '@ant-design/icons';\ninterface Props {\n text: string;\n}\nexport default function BlankBusinessPlaceholder(props: Props) {\n const { t } = useTranslation();\n const { text } = props;\n\n return (\n
\n
\n {t('提示信息')}\n
\n
\n {text}需要归属某个业务组,请先 \n 创建业务组\n
\n
\n );\n}\n","import React, { useContext } from 'react';\nimport { Space, Select } from 'antd';\nimport _ from 'lodash';\nimport { useTranslation } from 'react-i18next';\nimport { getAuthorizedDatasourceCates } from '@/components/AdvancedWrap';\nimport { CommonStateContext } from '@/App';\n\ninterface IProps {\n datasourceCate?: string;\n onDatasourceCateChange?: (val: string) => void;\n datasourceValue?: number | number[];\n datasourceValueMode?: 'multiple';\n onDatasourceValueChange?: (val: number | number[]) => void;\n defaultDatasourceValue?: number;\n filterCates?: (cates: { value: string; label: string; type: string }[]) => { value: string; label: string; type: string }[];\n}\n\nexport default function Pure(props: IProps) {\n const { t } = useTranslation('datasourceSelect');\n const { groupedDatasourceList } = useContext(CommonStateContext);\n const { datasourceCate, onDatasourceCateChange, datasourceValue, datasourceValueMode, onDatasourceValueChange, defaultDatasourceValue } = props;\n let cates = getAuthorizedDatasourceCates();\n cates = props.filterCates ? props.filterCates(cates) : cates;\n\n return (\n \n \n \n \n );\n}\n","const en_US = {\n type: 'Datasource type',\n id: 'Datasource',\n};\nexport default en_US;\n","const zh_CN = {\n type: '数据源类型',\n id: '关联数据源',\n};\nexport default zh_CN;\n","import i18next from 'i18next';\nimport en_US from './en_US';\nimport zh_CN from './zh_CN';\n\ni18next.addResourceBundle('en_US', 'datasourceSelect', en_US);\ni18next.addResourceBundle('zh_CN', 'datasourceSelect', zh_CN);\n","export interface AlertRuleType {\n id: number;\n group_id: number;\n name: string;\n disabled: AlertRuleStatus;\n append_tags: string[];\n rule_config: T;\n cate: string;\n datasource_ids: number[];\n prom_ql: string;\n prom_eval_interval: number;\n prom_for_duration: number;\n runbook_url: string;\n enable_status: boolean;\n enable_days_of_weekss: number[][];\n enable_stimes: number[];\n enable_etimes: number[];\n\n notify_channels: string[];\n notify_groups: string[];\n notify_recovered: number;\n recover_duration: number;\n notify_repeat_step: number;\n notify_max_number: number;\n callbacks: string[];\n annotations: any;\n prod: string;\n severities: number[];\n}\n\nexport enum AlertRuleStatus {\n Enable = 0,\n UnEnable = 1,\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React from 'react';\nimport { Form, Select } from 'antd';\nimport { useTranslation } from 'react-i18next';\nimport _ from 'lodash';\nexport const DATASOURCE_ALL = 0;\n\ninterface IProps {\n setFieldsValue: any;\n cate: string;\n datasourceList: { id: number; name: string }[];\n mode?: 'multiple';\n required?: boolean;\n}\n\nexport default function index({ setFieldsValue, cate, datasourceList, mode, required = true }: IProps) {\n const { t } = useTranslation();\n const handleClusterChange = (v: number[] | number) => {\n if (_.isArray(v)) {\n const curVal = _.last(v);\n if (curVal === DATASOURCE_ALL) {\n setFieldsValue({ datasource_ids: [DATASOURCE_ALL] });\n } else if (v.includes(DATASOURCE_ALL)) {\n setFieldsValue({ datasource_ids: _.without(v, DATASOURCE_ALL) });\n }\n }\n };\n\n if (cate === 'prometheus') {\n datasourceList = [\n {\n id: DATASOURCE_ALL,\n name: '$all',\n },\n ...datasourceList,\n ];\n }\n\n return (\n \n \n \n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { useState, useContext } from 'react';\nimport _ from 'lodash';\nimport { useTranslation } from 'react-i18next';\nimport { Modal, Input, Form, Table, Button, Divider, message, Select, Row, Col, Switch } from 'antd';\nimport { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons';\nimport ModalHOC, { ModalWrapProps } from '@/components/ModalHOC';\nimport { importStrategy } from '@/services/warning';\nimport { getAuthorizedDatasourceCates } from '@/components/AdvancedWrap';\nimport DatasourceValueSelect from '@/pages/alertRules/Form/components/DatasourceValueSelect';\n\ninterface IProps {\n busiId: number;\n refreshList: () => void;\n groupedDatasourceList: any;\n}\n\nfunction Import(props: IProps & ModalWrapProps) {\n const { t } = useTranslation('alertRules');\n const { visible, destroy, busiId, refreshList, groupedDatasourceList } = props;\n const [importResult, setImportResult] = useState<{ name: string; msg: string }[]>();\n const datasourceCates = _.filter(getAuthorizedDatasourceCates(), (item) => item.type === 'metric');\n\n return (\n {\n refreshList();\n destroy();\n }}\n footer={null}\n >\n \n \n \n \n \n \n \n {importResult && (\n <>\n \n
{\n return !data ? : ;\n },\n },\n {\n title: t('batch.import.errmsg'),\n dataIndex: 'msg',\n },\n ]}\n pagination={false}\n size='small'\n />\n >\n )}\n \n );\n}\n\nexport default ModalHOC(Import);\n","import _ from 'lodash';\n\nexport const getDefaultDatasourceValue = (datasourceCate: string, datasourceList: { [index: string]: { id: number; name: string }[] }) => {\n const localValue = localStorage.getItem(`datasourceValue_${datasourceCate}`);\n let defaultValue = _.get(datasourceList, [datasourceCate, 0, 'id']);\n if (!localValue) {\n return defaultValue;\n }\n const valueToNumber = _.toNumber(localValue);\n const isExist = _.find(datasourceList[datasourceCate], (item) => item.id === valueToNumber);\n if (isExist) {\n return valueToNumber;\n }\n return defaultValue;\n};\n\nexport const setDefaultDatasourceValue = (datasourceCate, value) => {\n localStorage.setItem(`datasourceValue_${datasourceCate}`, value);\n};\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport { message } from 'antd';\nimport React, { ReactNode, Component } from 'react';\nimport { IStore } from '@/store/common';\nimport { useLocation } from 'react-router-dom';\nexport { getDefaultDatasourceValue, setDefaultDatasourceValue } from './datasource';\n\nexport const isPromise = (obj) => {\n return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';\n};\n\nexport const download = function (stringList: Array | string, name: string = 'download.txt') {\n const element = document.createElement('a');\n const file = new Blob([Array.isArray(stringList) ? stringList.join('\\r\\n') : stringList], { type: 'text/plain' });\n element.href = URL.createObjectURL(file);\n element.download = name;\n document.body.appendChild(element);\n element.click();\n};\n\n/**\n * 将文本添加到剪贴板\n */\nexport const copyToClipBoard = (text: string, t, spliter?: string): boolean => {\n const fakeElem = document.createElement('textarea');\n fakeElem.style.border = '0';\n fakeElem.style.padding = '0';\n fakeElem.style.margin = '0';\n fakeElem.style.position = 'absolute';\n fakeElem.style.left = '-9999px';\n const yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElem.style.top = `${yPosition}px`;\n fakeElem.setAttribute('readonly', '');\n fakeElem.value = text;\n\n document.body.appendChild(fakeElem);\n fakeElem.select();\n let succeeded;\n try {\n succeeded = document.execCommand('copy');\n if (spliter && text.includes(spliter)) {\n message.success(`${t('复制')}${text.split('\\n').length}${t('条数据到剪贴板')}`);\n } else {\n message.success(t('复制到剪贴板'));\n }\n } catch (err) {\n message.error(t('复制失败'));\n succeeded = false;\n }\n if (succeeded) {\n document.body.removeChild(fakeElem);\n }\n return succeeded;\n};\n\nexport const copy2ClipBoard = (text: string, silent = false): boolean => {\n const fakeElem = document.createElement('textarea');\n fakeElem.style.border = '0';\n fakeElem.style.padding = '0';\n fakeElem.style.margin = '0';\n fakeElem.style.position = 'absolute';\n fakeElem.style.left = '-9999px';\n const yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElem.style.top = `${yPosition}px`;\n fakeElem.setAttribute('readonly', '');\n fakeElem.value = text;\n\n document.body.appendChild(fakeElem);\n fakeElem.select();\n let succeeded;\n try {\n succeeded = document.execCommand('copy');\n !silent && message.success('复制到剪贴板');\n } catch (err) {\n message.error('复制失败');\n succeeded = false;\n }\n if (succeeded) {\n document.body.removeChild(fakeElem);\n }\n return succeeded;\n};\n\nexport function formatTrim(s: string) {\n out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (s[i]) {\n case '.':\n i0 = i1 = i;\n break;\n\n case '0':\n if (i0 === 0) i0 = i;\n i1 = i;\n break;\n\n default:\n if (i0 > 0) {\n if (!+s[i]) break out;\n i0 = 0;\n }\n break;\n }\n }\n return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\ninterface Route {\n path: string;\n component: JSX.Element | Component;\n}\nexport interface Entry {\n menu?: {\n weight?: number;\n content: ReactNode;\n };\n routes: Route[];\n module?: IStore;\n}\n\nexport const dynamicPackages = (): Entry[] => {\n const Packages = import.meta.globEager('../Packages/*/entry.tsx');\n return Object.values(Packages).map((obj) => obj.default);\n};\n\nexport const generateID = (): string => {\n return `_${Math.random().toString(36).substr(2, 9)}`;\n};\n\n// https://github.com/n9e/fe-v5/issues/72 修改 withByte 默认为 false\nexport const sizeFormatter = (\n val,\n fixedCount = 2,\n { withUnit = true, withByte = false, trimZero = false, convertNum = 1024 } = {\n withUnit: true,\n withByte: false,\n trimZero: false,\n convertNum: 1024 | 1000,\n },\n) => {\n const size = val ? Number(val) : 0;\n let result;\n let unit = '';\n\n if (size < 0) {\n result = 0;\n } else if (size < convertNum) {\n result = size.toFixed(fixedCount);\n } else if (size < convertNum * convertNum) {\n result = (size / convertNum).toFixed(fixedCount);\n unit = 'K';\n } else if (size < convertNum * convertNum * convertNum) {\n result = (size / convertNum / convertNum).toFixed(fixedCount);\n unit = 'M';\n } else if (size < convertNum * convertNum * convertNum * convertNum) {\n result = (size / convertNum / convertNum / convertNum).toFixed(fixedCount);\n unit = 'G';\n } else if (size < convertNum * convertNum * convertNum * convertNum * convertNum) {\n result = (size / convertNum / convertNum / convertNum / convertNum).toFixed(fixedCount);\n unit = 'T';\n }\n\n trimZero && (result = parseFloat(result));\n withUnit && (result = `${result}${unit}`);\n withByte && (result = `${result}B`);\n return result;\n};\n\nexport function useQuery() {\n const { search } = useLocation();\n return React.useMemo(() => new URLSearchParams(search), [search]);\n}\n\nexport function warning(message: string) {\n // Support uglify\n if (process.env.NODE_ENV !== 'production' && console !== undefined) {\n console.error(`Warning: ${message}`);\n }\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Modal, Input } from 'antd';\nimport { CopyOutlined } from '@ant-design/icons';\nimport ModalHOC, { ModalWrapProps } from '@/components/ModalHOC';\nimport { download, copyToClipBoard } from '@/utils';\n\ninterface IProps {\n data: string;\n}\n\nfunction Export(props: IProps & ModalWrapProps) {\n const { t } = useTranslation('alertRules');\n const { visible, destroy } = props;\n const [data, setData] = useState(props.data);\n return (\n {\n destroy();\n }}\n footer={null}\n >\n
item.id),\n onChange: (selectedRowKeys: React.Key[], selectedRows: AlertRuleType[]) => {\n setSelectRowKeys(selectedRowKeys);\n setSelectedRows(selectedRows);\n },\n }}\n columns={columns}\n />\n \n );\n}\n","export const priorityColor = ['red', 'orange', 'blue'];\nexport const pageSizeOptionsDefault = ['30', '50', '100', '300'];\nexport const panelBaseProps: any = {\n size: 'small',\n bodyStyle: { padding: '24px 24px 8px 24px' },\n};\nexport const daysOfWeek = [0, 1, 2, 3, 4, 5, 6];\nexport const DATASOURCE_ALL = 0;\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Form, Input, Select, Card, Row, Col, Tag, Tooltip } from 'antd';\nimport { panelBaseProps } from '../constants';\n\n// 校验单个标签格式是否正确\nfunction isTagValid(tag) {\n const contentRegExp = /^[a-zA-Z_][\\w]*={1}[^=]+$/;\n return {\n isCorrectFormat: contentRegExp.test(tag.toString()),\n isLengthAllowed: tag.toString().length <= 64,\n };\n}\n\nexport default function Base() {\n const { t } = useTranslation('alertRules');\n // 渲染标签\n function tagRender(content) {\n const { isCorrectFormat, isLengthAllowed } = isTagValid(content.value);\n return isCorrectFormat && isLengthAllowed ? (\n \n {content.value}\n \n ) : (\n \n \n {content.value}\n \n \n );\n }\n\n // 校验所有标签格式\n function isValidFormat() {\n return {\n validator(_, value) {\n const isInvalid =\n value &&\n value.some((tag) => {\n const { isCorrectFormat, isLengthAllowed } = isTagValid(tag);\n if (!isCorrectFormat || !isLengthAllowed) {\n return true;\n }\n });\n return isInvalid ? Promise.reject(new Error(t('append_tags_msg'))) : Promise.resolve();\n },\n };\n }\n return (\n \n \n
\n \n \n \n \n
\n \n \n \n \n
\n \n \n \n \n \n \n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React from 'react';\nimport { Space, Form, Radio } from 'antd';\nimport { useTranslation } from 'react-i18next';\n\nexport default function index({ field }) {\n const { t } = useTranslation('alertRules');\n return (\n \n {t('severity_label')}:\n \n \n {t('common:severity.1')}\n {t('common:severity.2')}\n {t('common:severity.3')}\n \n \n \n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React from 'react';\nimport { Form, Space, Switch } from 'antd';\nimport { useTranslation } from 'react-i18next';\n\ninterface IProps {\n triggersKey: string;\n}\n\nexport default function index(props: IProps) {\n const { t } = useTranslation('alertRules');\n const { triggersKey } = props;\n\n return (\n \n {({ getFieldValue, setFieldsValue }) => {\n const triggers = getFieldValue(['rule_config', triggersKey]);\n if (triggers && triggers.length > 1) {\n return (\n \n {t('inhibit')}\n {\n setFieldsValue({\n rule_config: {\n inhibit: checked,\n },\n });\n }}\n />\n \n );\n }\n }}\n \n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nimport React from 'react';\nimport { Form, Row, Col, InputNumber } from 'antd';\nimport { useTranslation } from 'react-i18next';\n\ninterface IProps {\n intervalTip?: (value?: number) => string;\n durationTip?: (value?: number) => string;\n}\n\nexport default function index({ intervalTip, durationTip }: IProps) {\n const { t } = useTranslation('alertRules');\n return (\n prevValues.cate !== curValues.cate} noStyle>\n {({ getFieldValue }) => {\n const cate = getFieldValue('cate');\n return (\n \n
{\n return _.map(val, (item) => {\n return (\n \n {item}\n \n );\n });\n },\n },\n {\n title: t('common:business_group'),\n dataIndex: 'group_obj',\n render(groupObj) {\n return groupObj ? groupObj.name : t('not_grouped');\n },\n },\n ]}\n dataSource={data}\n pagination={{\n current: page,\n pageSize: limit,\n total,\n showSizeChanger: true,\n onChange: (p, l) => {\n setPage(p);\n setLimit(l);\n },\n }}\n />\n \n \n \n );\n}\n","/*\n * Copyright 2022 Nightingale Team\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport React from 'react';\nimport { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';\nimport { Form, InputNumber, Space, Select, Card } from 'antd';\nimport { useTranslation } from 'react-i18next';\nimport Severity from '@/pages/alertRules/Form/components/Severity';\nimport Inhibit from '@/pages/alertRules/Form/components/Inhibit';\nimport IntervalAndDuration from '@/pages/alertRules/Form/components/IntervalAndDuration';\nimport ValuesSelect from './ValuesSelect';\nimport Preview from './Preview';\nimport './style.less';\n\nconst queryKeyOptions = [{ value: 'all_hosts' }, { value: 'group_ids' }, { value: 'tags' }, { value: 'hosts' }];\nconst triggerTypeOptions = [{ value: 'target_miss' }, { value: 'pct_target_miss' }, { value: 'offset' }];\n\nexport default function index() {\n const { t } = useTranslation('alertRules');\n const form = Form.useFormInstance();\n\n return (\n