diff --git a/apps/ai/eslint.config.js b/apps/ai/eslint.config.js index 80c003f736..e5b6025364 100644 --- a/apps/ai/eslint.config.js +++ b/apps/ai/eslint.config.js @@ -1,7 +1,28 @@ +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + const base = require("../../eslint.config"); const react = require("@ddadaal/eslint-config/react"); -module.export = { +module.exports = [ ...base, ...react, -}; + { + rules: { + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-unsafe-enum-comparison": "off", + "@typescript-eslint/no-misused-promises": "off", + "@typescript-eslint/only-throw-error": "off", + "@typescript-eslint/prefer-promise-reject-errors": "off", + } + } +]; diff --git a/apps/ai/next.config.mjs b/apps/ai/next.config.mjs index 4b7ad49591..da98cda85f 100644 --- a/apps/ai/next.config.mjs +++ b/apps/ai/next.config.mjs @@ -75,9 +75,6 @@ export default async () => { // }); return config; }, - compiler: { - styledComponents: true, - }, skipTrailingSlashRedirect: true, transpilePackages: ["antd", "@ant-design/icons"], }; diff --git a/apps/ai/src/app/(auth)/algorithm/AlgorithmVersionList.tsx b/apps/ai/src/app/(auth)/algorithm/AlgorithmVersionList.tsx index 5501ef83b4..4f25d67c5b 100644 --- a/apps/ai/src/app/(auth)/algorithm/AlgorithmVersionList.tsx +++ b/apps/ai/src/app/(auth)/algorithm/AlgorithmVersionList.tsx @@ -153,7 +153,7 @@ export const AlgorithmVersionList: React.FC = ( versionDescription:r.versionDescription, }} > - 编辑 + 编辑 ); diff --git a/apps/ai/src/app/(auth)/context.ts b/apps/ai/src/app/(auth)/context.ts index d1d96093e6..3967a29da0 100644 --- a/apps/ai/src/app/(auth)/context.ts +++ b/apps/ai/src/app/(auth)/context.ts @@ -26,8 +26,8 @@ export const PublicConfigContext = React.createContext<{ defaultCluster: Cluster; setDefaultCluster: (cluster: Cluster) => void; removeDefaultCluster: () => void; - } - }>(undefined!); + } +}>(undefined!); export const usePublicConfig = () => { return useContext(PublicConfigContext); diff --git a/apps/ai/src/app/(auth)/dataset/CreateEditDSVersionModal.tsx b/apps/ai/src/app/(auth)/dataset/CreateEditDSVersionModal.tsx index 628bf3835c..72b749aa81 100644 --- a/apps/ai/src/app/(auth)/dataset/CreateEditDSVersionModal.tsx +++ b/apps/ai/src/app/(auth)/dataset/CreateEditDSVersionModal.tsx @@ -101,20 +101,25 @@ export const CreateEditDSVersionModal: React.FC = ( const onOk = async () => { form.validateFields(); const { versionName, versionDescription, path } = await form.validateFields(); - isEdit && editData ? editMutation.mutate({ - datasetVersionId: editData.id, - versionName, - versionDescription, - datasetId: editData.datasetId, - }) - : createMutation.mutate({ + + if (isEdit && editData) { + editMutation.mutate({ + datasetVersionId: editData.id, + versionName, + versionDescription, + datasetId: editData.datasetId, + }); + } else { + createMutation.mutate({ versionName, versionDescription, path, datasetId, }); + } }; + return ( = ( }, []); const resetForm = () => { - isEdit && editData ? + if (isEdit && editData) { form.setFieldsValue({ type: editData.type, scene: editData.scene, - }) : form.setFieldsValue({ + }); + } else { + form.setFieldsValue({ type: DatasetType.IMAGE, scene: SceneType.CWS, }); + } }; const createMutation = trpc.dataset.createDataset.useMutation({ @@ -117,20 +120,24 @@ export const CreateEditDatasetModal: React.FC = ( const onOk = async () => { const { name, type, description, scene, cluster } = await form.validateFields(); - (isEdit && editData) ? editMutation.mutate({ - id: editData.id, - name, - type, - scene, - description, - }) - : createMutation.mutate({ + if (isEdit && editData) { + + editMutation.mutate({ + id: editData.id, + name, + type, + scene, + description, + }); + } else { + createMutation.mutate({ name, clusterId: cluster.id, type, description, scene, }); + } }; return ( diff --git a/apps/ai/src/app/(auth)/dataset/DatasetListTable.tsx b/apps/ai/src/app/(auth)/dataset/DatasetListTable.tsx index 27b602fd1e..8c76f53ba8 100644 --- a/apps/ai/src/app/(auth)/dataset/DatasetListTable.tsx +++ b/apps/ai/src/app/(auth)/dataset/DatasetListTable.tsx @@ -41,7 +41,7 @@ interface Props { const FilterType = { ALL: "全部", ...DatasetTypeText, -} as { [key: string]: string }; +} as Record; type FilterTypeKeys = Extract; @@ -52,8 +52,8 @@ interface FilterForm { } interface PageInfo { - page: number; - pageSize?: number; + page: number; + pageSize?: number; } const CreateDatasetModalButton = ModalButton(CreateEditDatasetModal, { type: "primary", icon: }); diff --git a/apps/ai/src/app/(auth)/dataset/DatasetVersionList.tsx b/apps/ai/src/app/(auth)/dataset/DatasetVersionList.tsx index adc1591630..9cddbee6cb 100644 --- a/apps/ai/src/app/(auth)/dataset/DatasetVersionList.tsx +++ b/apps/ai/src/app/(auth)/dataset/DatasetVersionList.tsx @@ -146,7 +146,7 @@ export const DatasetVersionList: React.FC = ( editData={r} refetch={refetch} > - 编辑 + 编辑 @@ -748,7 +748,7 @@ export const LaunchAppForm = (props: Props) => { form.setFieldsValue({ algorithm: { type: undefined, name: undefined, version: undefined } })} > - 算法 + 算法 { form.setFieldsValue({ dataset: { type: undefined, name: undefined, version: undefined } })} > - 数据集 + 数据集 { form.setFieldsValue({ model: { type: undefined, name: undefined, version: undefined } })} > - 模型 + 模型 diff --git a/apps/ai/src/app/(auth)/jobs/[clusterId]/SelectAppTable.tsx b/apps/ai/src/app/(auth)/jobs/[clusterId]/SelectAppTable.tsx index c79273a30a..0938bb65fa 100644 --- a/apps/ai/src/app/(auth)/jobs/[clusterId]/SelectAppTable.tsx +++ b/apps/ai/src/app/(auth)/jobs/[clusterId]/SelectAppTable.tsx @@ -48,9 +48,7 @@ interface Props { isTraining?: boolean, } -interface ImageErrorMap { - [appId: string]: boolean; -} +type ImageErrorMap = Record; export const SelectAppTable: React.FC = ({ publicPath, clusterId, apps, isTraining = false }) => { diff --git a/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/[appId]/page.tsx b/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/[appId]/page.tsx index 216ec248e6..82ea7f6ea3 100644 --- a/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/[appId]/page.tsx +++ b/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/[appId]/page.tsx @@ -20,7 +20,7 @@ import { trpc } from "src/utils/trpc"; import { LaunchAppForm } from "../../LaunchAppForm"; -export default function Page({ params }: {params: {clusterId: string, appId: string}}) { +export default function Page({ params }: { params: { clusterId: string, appId: string } }) { const { appId, clusterId } = params; const searchParams = useSearchParams(); diff --git a/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/page.tsx b/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/page.tsx index 76f0b9c119..658ed5aec2 100644 --- a/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/page.tsx +++ b/apps/ai/src/app/(auth)/jobs/[clusterId]/createApps/page.tsx @@ -25,7 +25,7 @@ const useClusterAppConfigQuery = (clusterId: string) => { return trpc.jobs.listAvailableApps.useQuery({ clusterId }); }; -export default function Page({ params }: {params: {clusterId: string}}) { +export default function Page({ params }: { params: { clusterId: string } }) { const { clusterId } = params; const { publicConfig } = usePublicConfig(); diff --git a/apps/ai/src/app/(auth)/jobs/[clusterId]/historyJobs/page.tsx b/apps/ai/src/app/(auth)/jobs/[clusterId]/historyJobs/page.tsx index fc82b3db05..3ac19651df 100644 --- a/apps/ai/src/app/(auth)/jobs/[clusterId]/historyJobs/page.tsx +++ b/apps/ai/src/app/(auth)/jobs/[clusterId]/historyJobs/page.tsx @@ -18,7 +18,7 @@ import { NotFoundPage } from "src/layouts/error/NotFoundPage"; import { AppSessionsTable, AppTableStatus } from "../AppSessionsTable"; -export default function Page({ params }: {params: {clusterId: string}}) { +export default function Page({ params }: { params: { clusterId: string } }) { const { clusterId } = params; const { publicConfig } = usePublicConfig(); diff --git a/apps/ai/src/app/(auth)/jobs/[clusterId]/hooks.ts b/apps/ai/src/app/(auth)/jobs/[clusterId]/hooks.ts index 897e7e9e44..13f3fe11c8 100644 --- a/apps/ai/src/app/(auth)/jobs/[clusterId]/hooks.ts +++ b/apps/ai/src/app/(auth)/jobs/[clusterId]/hooks.ts @@ -22,11 +22,10 @@ interface Option { value: number; } -type DataType = "dataset" | "algorithm" | "model" +type DataType = "dataset" | "algorithm" | "model"; -interface QueryHookFunction { - (args: TQueryFnData, options?: any): UseQueryResult; -} +type QueryHookFunction = + (args: TQueryFnData, options?: any) => UseQueryResult; export function useDataOptions( form: FormInstance, diff --git a/apps/ai/src/app/(auth)/jobs/[clusterId]/runningJobs/page.tsx b/apps/ai/src/app/(auth)/jobs/[clusterId]/runningJobs/page.tsx index 4cd9ba77b6..d937baa311 100644 --- a/apps/ai/src/app/(auth)/jobs/[clusterId]/runningJobs/page.tsx +++ b/apps/ai/src/app/(auth)/jobs/[clusterId]/runningJobs/page.tsx @@ -18,7 +18,7 @@ import { NotFoundPage } from "src/layouts/error/NotFoundPage"; import { AppSessionsTable, AppTableStatus } from "../AppSessionsTable"; -export default function Page({ params }: {params: {clusterId: string}}) { +export default function Page({ params }: { params: { clusterId: string } }) { const { clusterId } = params; const { publicConfig } = usePublicConfig(); diff --git a/apps/ai/src/app/(auth)/jobs/[clusterId]/trainJobs/page.tsx b/apps/ai/src/app/(auth)/jobs/[clusterId]/trainJobs/page.tsx index a03aa060a0..eb3c2cc99f 100644 --- a/apps/ai/src/app/(auth)/jobs/[clusterId]/trainJobs/page.tsx +++ b/apps/ai/src/app/(auth)/jobs/[clusterId]/trainJobs/page.tsx @@ -20,7 +20,7 @@ import { trpc } from "src/utils/trpc"; import { LaunchAppForm } from "../LaunchAppForm"; -export default function Page({ params }: {params: {clusterId: string}}) { +export default function Page({ params }: { params: { clusterId: string } }) { const { clusterId } = params; diff --git a/apps/ai/src/app/(auth)/model/ModelVersionList.tsx b/apps/ai/src/app/(auth)/model/ModelVersionList.tsx index f3b1630bd1..22d3c86a4d 100644 --- a/apps/ai/src/app/(auth)/model/ModelVersionList.tsx +++ b/apps/ai/src/app/(auth)/model/ModelVersionList.tsx @@ -151,7 +151,7 @@ export const ModelVersionList: React.FC = ( }} > - 编辑 + 编辑 ); diff --git a/apps/ai/src/app/(auth)/profile/page.tsx b/apps/ai/src/app/(auth)/profile/page.tsx index 619abae809..e90ad5fe17 100644 --- a/apps/ai/src/app/(auth)/profile/page.tsx +++ b/apps/ai/src/app/(auth)/profile/page.tsx @@ -61,7 +61,7 @@ export default function Page() { - 用户信息 + 用户信息 & { - url: string; - }) => ({ + url: string; + }) => ({ Icon: !childLink.iconPath ? LinkOutlined : ( = ({ cluster, onChange, value }) = useEffect(() => { - if (data && data.accounts.length) { + if (data?.accounts.length) { if (!value || !data.accounts.includes(value)) { onChange?.(data.accounts[0]); } diff --git a/apps/ai/src/components/ErrorBoundary.tsx b/apps/ai/src/components/ErrorBoundary.tsx index fb478c089c..2791a4aac8 100644 --- a/apps/ai/src/components/ErrorBoundary.tsx +++ b/apps/ai/src/components/ErrorBoundary.tsx @@ -21,9 +21,9 @@ export interface ErrorBoundaryContentProps { type Props = PropsWithChildren<{ Component: React.ComponentType; pathname: string }>; -type State = { - error?: Error; -} +interface State { + error?: Error; +}; export class ErrorBoundary extends React.Component { diff --git a/apps/ai/src/components/MkdirModal.tsx b/apps/ai/src/components/MkdirModal.tsx index 6adb70b17b..6e19a4bc7f 100644 --- a/apps/ai/src/components/MkdirModal.tsx +++ b/apps/ai/src/components/MkdirModal.tsx @@ -69,7 +69,7 @@ export const MkdirModal: React.FC = ({ open, onClose, path, reload, clust {path} - label="目录名" name="newDirName" rules={[{ required: true }]}> + diff --git a/apps/ai/src/components/ModalLink.tsx b/apps/ai/src/components/ModalLink.tsx index b4b6ca0be3..91d6896a10 100644 --- a/apps/ai/src/components/ModalLink.tsx +++ b/apps/ai/src/components/ModalLink.tsx @@ -23,49 +23,49 @@ export interface CommonModalProps { export const ModalLink = ( ModalComponent: React.ComponentType, ) => (props: React.PropsWithChildren>) => { - const [open, setOpen] = useState(false); - const { children, ...rest } = props; + const [open, setOpen] = useState(false); + const { children, ...rest } = props; - return ( - <> - setOpen(true)}> - {children} - - {/** @ts-ignore */} - { - setOpen(false); - }} - {...rest} - /> - - ); + return ( + <> + setOpen(true)}> + {children} + + {/** @ts-ignore */} + { + setOpen(false); + }} + {...rest} + /> + + ); - }; +}; export const ModalButton = ( ModalComponent: React.ComponentType, buttonProps?: ButtonProps, ) => (props: React.PropsWithChildren>) => { - const [open, setOpen] = useState(false); - const { children, ...rest } = props; + const [open, setOpen] = useState(false); + const { children, ...rest } = props; - return ( - <> - - {/** @ts-ignore */} - { - setOpen(false); - }} - {...rest} - /> - - ); + return ( + <> + + {/** @ts-ignore */} + { + setOpen(false); + }} + {...rest} + /> + + ); - }; +}; diff --git a/apps/ai/src/components/UploadModal.tsx b/apps/ai/src/components/UploadModal.tsx index ea9cdfe841..e873b6c029 100644 --- a/apps/ai/src/components/UploadModal.tsx +++ b/apps/ai/src/components/UploadModal.tsx @@ -31,7 +31,7 @@ interface Props { enum FileType { FILE = "file", - DIR = "dir" + DIR = "dir", } export const UploadModal: React.FC = ({ open, onClose, path, reload, clusterId }) => { @@ -101,31 +101,31 @@ export const UploadModal: React.FC = ({ open, onClose, path, reload, clus return Upload.LIST_IGNORE; } - return new Promise(async (resolve, reject) => { - const checkExistRes = await checkFileExist.mutateAsync({ path:join(path, file.name), clusterId }); - - if (checkExistRes.exists) { - modal.confirm({ - title: "文件已存在", - content: `文件: ${file.name}已存在,是否覆盖?`, - okText: "确认", - onOk: async () => { - const fileType = await getFileType.mutateAsync({ path:join(path, file.name), clusterId }); - - if (fileType.type) { - await deleteFileMutation.mutateAsync({ - target: fileType.type === FileType.DIR ? "DIR" : "FILE", - clusterId: clusterId, - path: join(path, file.name), - }).then(() => resolve(file)); - } - - }, - onCancel: () => { reject(file); }, - }); - } else { - resolve(file); - } + return new Promise((resolve, reject) => { + checkFileExist.mutateAsync({ path:join(path, file.name), clusterId }).then(({ exists }) => { + if (exists) { + modal.confirm({ + title: "文件已存在", + content: `文件: ${file.name}已存在,是否覆盖?`, + okText: "确认", + onOk: async () => { + const fileType = await getFileType.mutateAsync({ path:join(path, file.name), clusterId }); + + if (fileType.type) { + await deleteFileMutation.mutateAsync({ + target: fileType.type === FileType.DIR ? "DIR" : "FILE", + clusterId: clusterId, + path: join(path, file.name), + }).then(() => resolve(file)); + } + + }, + onCancel: () => { reject(file); }, + }); + } else { + resolve(file); + } + }); }); }} diff --git a/apps/ai/src/components/shell/JobShell.tsx b/apps/ai/src/components/shell/JobShell.tsx index 7737b06c04..08fa3cab84 100644 --- a/apps/ai/src/components/shell/JobShell.tsx +++ b/apps/ai/src/components/shell/JobShell.tsx @@ -68,13 +68,14 @@ export const JobShell: React.FC = ({ user, cluster, jobId }) => { socket.onmessage = (e) => { const message = JSON.parse(e.data) as ShellOutputData; switch (message.$case) { - case "data": - const data = Buffer.from(message.data.data); - term.write(data); - break; - case "exit": - term.write(`Process exited with code ${message.exit.code} and signal ${message.exit.signal}.`); - break; + case "data": { + const data = Buffer.from(message.data.data); + term.write(data); + break; + } + case "exit": + term.write(`Process exited with code ${message.exit.code} and signal ${message.exit.signal}.`); + break; } }; diff --git a/apps/ai/src/i18n/index.ts b/apps/ai/src/i18n/index.ts index 8f856a8937..92e5a1584b 100644 --- a/apps/ai/src/i18n/index.ts +++ b/apps/ai/src/i18n/index.ts @@ -29,6 +29,7 @@ export const languageInfo = { en: { name: "US English" }, }; +// eslint-disable-next-line @typescript-eslint/unbound-method export const { Localized, Provider, id, prefix, useI18n } = createI18n(languages); export type TextId = TextIdFromLangDict; diff --git a/apps/ai/src/layouts/base/common.tsx b/apps/ai/src/layouts/base/common.tsx index 1ee0a9aad1..5da4425958 100644 --- a/apps/ai/src/layouts/base/common.tsx +++ b/apps/ai/src/layouts/base/common.tsx @@ -40,8 +40,11 @@ export function createMenuItems( if (route.openInNewPage) { window.open(target); } else { - EXTERNAL_URL_PREFIX.some((pref) => target.startsWith(pref)) - ? window.location.href = target : router.push(target); + if (EXTERNAL_URL_PREFIX.some((pref) => target.startsWith(pref))) { + window.location.href = target; + } else { + router.push(target); + } } } : undefined, diff --git a/apps/ai/src/layouts/darkMode.tsx b/apps/ai/src/layouts/darkMode.tsx index c2dfc91164..e2dfab407c 100644 --- a/apps/ai/src/layouts/darkMode.tsx +++ b/apps/ai/src/layouts/darkMode.tsx @@ -20,6 +20,7 @@ import moon from "src/components/icons/moon.svg"; import sun from "src/components/icons/sun.svg"; import sunMoon from "src/components/icons/sun-moon.svg"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars const modes = ["system", "dark", "light"] as const; const icons = { @@ -34,7 +35,7 @@ const DarkModeContext = React.createContext<{ mode: DarkMode; dark: boolean; setMode: (mode: DarkMode) => void; - }>(undefined!); +}>(undefined!); export const useDarkMode = () => React.useContext(DarkModeContext); diff --git a/apps/ai/src/layouts/error/NotAuthorizedPage.tsx b/apps/ai/src/layouts/error/NotAuthorizedPage.tsx index fceb66831b..d29e450adf 100644 --- a/apps/ai/src/layouts/error/NotAuthorizedPage.tsx +++ b/apps/ai/src/layouts/error/NotAuthorizedPage.tsx @@ -14,7 +14,7 @@ import { Button, Result } from "antd"; import Link from "next/link"; import { Head } from "src/utils/head"; -// eslint-disable-next-line @typescript-eslint/no-unused-vars + export const NotAuthorizedPage = () => { return ( diff --git a/apps/ai/src/models/Cluster.ts b/apps/ai/src/models/Cluster.ts index 8e4bad3ef9..7c4f643d46 100644 --- a/apps/ai/src/models/Cluster.ts +++ b/apps/ai/src/models/Cluster.ts @@ -12,17 +12,17 @@ export interface Cluster { name: (string | { - i18n: { - default: string; - en?: string | undefined; - zh_cn?: string | undefined; - }; + i18n: { + default: string; + en?: string | undefined; + zh_cn?: string | undefined; + }; }) & (string | { - i18n: { - default: string; - en?: string | undefined; - zh_cn?: string | undefined; - }; + i18n: { + default: string; + en?: string | undefined; + zh_cn?: string | undefined; + }; } | undefined); id: string; } diff --git a/apps/ai/src/models/Dateset.ts b/apps/ai/src/models/Dateset.ts index bb617851b4..3bf82b5429 100644 --- a/apps/ai/src/models/Dateset.ts +++ b/apps/ai/src/models/Dateset.ts @@ -26,7 +26,7 @@ export enum SceneType { OTHER = "OTHER", } -export const DatasetTypeText: { [key: string]: string } = { +export const DatasetTypeText: Record = { IMAGE: "图像", TEXT: "文本", VIDEO: "视频", @@ -34,7 +34,7 @@ export const DatasetTypeText: { [key: string]: string } = { OTHER: "其他", }; -export const SceneTypeText: { [key: string]: string } = { +export const SceneTypeText: Record = { CWS: "中文分词", DA: "数据增强", IC: "图像分类", diff --git a/apps/ai/src/models/File.ts b/apps/ai/src/models/File.ts index 748f38173a..4627da2460 100644 --- a/apps/ai/src/models/File.ts +++ b/apps/ai/src/models/File.ts @@ -12,10 +12,10 @@ export type FileType = "FILE" | "DIR"; -export type FileInfo = { +export interface FileInfo { name: string, type: FileType, mtime: string, mode: number, size: number, -}; +} diff --git a/apps/ai/src/models/Image.ts b/apps/ai/src/models/Image.ts index 34c98078a9..270b83eeeb 100644 --- a/apps/ai/src/models/Image.ts +++ b/apps/ai/src/models/Image.ts @@ -15,7 +15,7 @@ import { AppRouter } from "src/server/trpc/router"; export type ImageInterface = inferRouterOutputs["image"]["list"]["items"][0]; -export const SourceText: { [key: string]: string } = { +export const SourceText: Record = { INTERNAL: "本地文件", EXTERNAL: "远程镜像", }; @@ -28,5 +28,5 @@ export enum Source { export enum Status { CREATING = "CREATING", CREATED = "CREATED", - FAILURE = "FAILURE" + FAILURE = "FAILURE", } diff --git a/apps/ai/src/models/operationLog.ts b/apps/ai/src/models/operationLog.ts index d727aafe93..8e71a11fa4 100644 --- a/apps/ai/src/models/operationLog.ts +++ b/apps/ai/src/models/operationLog.ts @@ -19,7 +19,7 @@ export const OperationResult = { FAIL: 2, } as const; -export type OperationResult = ValueOf +export type OperationResult = ValueOf; export const OperationType: OperationTypeEnum = { login: "login", diff --git a/apps/ai/src/server/auth/server.ts b/apps/ai/src/server/auth/server.ts index df85815a4b..0c4dd4b544 100644 --- a/apps/ai/src/server/auth/server.ts +++ b/apps/ai/src/server/auth/server.ts @@ -39,7 +39,7 @@ export async function getUserInfo(req: RequestType, res?: NextApiResponse): Prom const result = await validateToken(token); - if (!result || !result.identityId) { + if (!result?.identityId) { deleteUserToken(res); return; } diff --git a/apps/ai/src/server/entities/Algorithm.ts b/apps/ai/src/server/entities/Algorithm.ts index 5c244ed2c8..69ea5b44fb 100644 --- a/apps/ai/src/server/entities/Algorithm.ts +++ b/apps/ai/src/server/entities/Algorithm.ts @@ -43,15 +43,15 @@ export class Algorithm { updateTime?: Date; constructor(init: { - name: string; - owner: string; - framework: Framework; - isShared?: boolean; - description?: string; - clusterId: string; - createTime?: Date; - updateTime?: Date; - }) { + name: string; + owner: string; + framework: Framework; + isShared?: boolean; + description?: string; + clusterId: string; + createTime?: Date; + updateTime?: Date; + }) { this.name = init.name; this.owner = init.owner; diff --git a/apps/ai/src/server/entities/Image.ts b/apps/ai/src/server/entities/Image.ts index 051ba46ec9..06ef079564 100644 --- a/apps/ai/src/server/entities/Image.ts +++ b/apps/ai/src/server/entities/Image.ts @@ -21,7 +21,7 @@ export enum Source { export enum Status { CREATED = "CREATED", CREATING = "CREATING", - FAILURE = "FAILURE" + FAILURE = "FAILURE", } export class Image { diff --git a/apps/ai/src/server/migrations/Migration20240102091246.ts b/apps/ai/src/server/migrations/Migration20240102091246.ts index 72ff73a9cd..4252387108 100644 --- a/apps/ai/src/server/migrations/Migration20240102091246.ts +++ b/apps/ai/src/server/migrations/Migration20240102091246.ts @@ -1,52 +1,66 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/* eslint-disable @stylistic/max-len */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240102091246 extends Migration { async up(): Promise { - this.addSql('create table `algorithm` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `framework` enum(\'TENSORFLOW\', \'PYTORCH\', \'KERAS\', \'MINDSPORE\', \'OTHER\') not null, `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;'); + this.addSql("create table `algorithm` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `framework` enum('TENSORFLOW', 'PYTORCH', 'KERAS', 'MINDSPORE', 'OTHER') not null, `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;"); - this.addSql('create table `algorithm_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `shared_status` varchar(255) not null, `algorithm_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;'); - this.addSql('alter table `algorithm_version` add index `algorithm_version_algorithm_id_index`(`algorithm_id`);'); + this.addSql("create table `algorithm_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `shared_status` varchar(255) not null, `algorithm_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;"); + this.addSql("alter table `algorithm_version` add index `algorithm_version_algorithm_id_index`(`algorithm_id`);"); - this.addSql('create table `dataset` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `type` varchar(255) not null, `is_shared` tinyint(1) not null, `scene` varchar(255) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;'); + this.addSql("create table `dataset` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `type` varchar(255) not null, `is_shared` tinyint(1) not null, `scene` varchar(255) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;"); - this.addSql('create table `dataset_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `is_shared` tinyint(1) not null, `dataset_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;'); - this.addSql('alter table `dataset_version` add index `dataset_version_dataset_id_index`(`dataset_id`);'); + this.addSql("create table `dataset_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `is_shared` tinyint(1) not null, `dataset_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;"); + this.addSql("alter table `dataset_version` add index `dataset_version_dataset_id_index`(`dataset_id`);"); - this.addSql('create table `image` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `source` enum(\'INTERNAL\', \'EXTERNAL\') not null, `tags` varchar(255) not null, `description` varchar(255) null, `cluster_id` varchar(255) null, `source_path` varchar(255) not null, `path` varchar(255) not null, `is_shared` tinyint(1) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;'); + this.addSql("create table `image` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `source` enum('INTERNAL', 'EXTERNAL') not null, `tags` varchar(255) not null, `description` varchar(255) null, `cluster_id` varchar(255) null, `source_path` varchar(255) not null, `path` varchar(255) not null, `is_shared` tinyint(1) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;"); - this.addSql('create table `modal` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `algorithm_framework` varchar(255) null comment \'algorithm algorithmFramework\', `algorithm_name` varchar(255) null comment \'algorithm name\', `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;'); + this.addSql("create table `modal` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `algorithm_framework` varchar(255) null comment 'algorithm algorithmFramework', `algorithm_name` varchar(255) null comment 'algorithm name', `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;"); - this.addSql('create table `modal_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `algorithm_version` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `is_shared` tinyint(1) not null, `modal_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;'); - this.addSql('alter table `modal_version` add index `modal_version_modal_id_index`(`modal_id`);'); + this.addSql("create table `modal_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `algorithm_version` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `is_shared` tinyint(1) not null, `modal_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;"); + this.addSql("alter table `modal_version` add index `modal_version_modal_id_index`(`modal_id`);"); - this.addSql('alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;'); + this.addSql("alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;"); - this.addSql('alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade on delete CASCADE;'); + this.addSql("alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade on delete CASCADE;"); - this.addSql('alter table `modal_version` add constraint `modal_version_modal_id_foreign` foreign key (`modal_id`) references `modal` (`id`) on update cascade;'); + this.addSql("alter table `modal_version` add constraint `modal_version_modal_id_foreign` foreign key (`modal_id`) references `modal` (`id`) on update cascade;"); } async down(): Promise { - this.addSql('alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;'); + this.addSql("alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;"); - this.addSql('alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;'); + this.addSql("alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;"); - this.addSql('alter table `modal_version` drop foreign key `modal_version_modal_id_foreign`;'); + this.addSql("alter table `modal_version` drop foreign key `modal_version_modal_id_foreign`;"); - this.addSql('drop table if exists `algorithm`;'); + this.addSql("drop table if exists `algorithm`;"); - this.addSql('drop table if exists `algorithm_version`;'); + this.addSql("drop table if exists `algorithm_version`;"); - this.addSql('drop table if exists `dataset`;'); + this.addSql("drop table if exists `dataset`;"); - this.addSql('drop table if exists `dataset_version`;'); + this.addSql("drop table if exists `dataset_version`;"); - this.addSql('drop table if exists `image`;'); + this.addSql("drop table if exists `image`;"); - this.addSql('drop table if exists `modal`;'); + this.addSql("drop table if exists `modal`;"); - this.addSql('drop table if exists `modal_version`;'); + this.addSql("drop table if exists `modal_version`;"); } } diff --git a/apps/ai/src/server/migrations/Migration20240103020827.ts b/apps/ai/src/server/migrations/Migration20240103020827.ts index d5cb3cf280..80b19f7875 100644 --- a/apps/ai/src/server/migrations/Migration20240103020827.ts +++ b/apps/ai/src/server/migrations/Migration20240103020827.ts @@ -1,15 +1,27 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240103020827 extends Migration { async up(): Promise { - this.addSql('alter table `modal_version` add `shared_status` varchar(255) not null;'); - this.addSql('alter table `modal_version` drop `is_shared`;'); + this.addSql("alter table `modal_version` add `shared_status` varchar(255) not null;"); + this.addSql("alter table `modal_version` drop `is_shared`;"); } async down(): Promise { - this.addSql('alter table `modal_version` add `is_shared` tinyint(1) not null;'); - this.addSql('alter table `modal_version` drop `shared_status`;'); + this.addSql("alter table `modal_version` add `is_shared` tinyint(1) not null;"); + this.addSql("alter table `modal_version` drop `shared_status`;"); } } diff --git a/apps/ai/src/server/migrations/Migration20240103024536.ts b/apps/ai/src/server/migrations/Migration20240103024536.ts index eb8868608d..de0af458a5 100644 --- a/apps/ai/src/server/migrations/Migration20240103024536.ts +++ b/apps/ai/src/server/migrations/Migration20240103024536.ts @@ -1,13 +1,25 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240103024536 extends Migration { async up(): Promise { - this.addSql('alter table `image` change `tags` `tag` varchar(255) not null;'); + this.addSql("alter table `image` change `tags` `tag` varchar(255) not null;"); } async down(): Promise { - this.addSql('alter table `image` change `tag` `tags` varchar(255) not null;'); + this.addSql("alter table `image` change `tag` `tags` varchar(255) not null;"); } } diff --git a/apps/ai/src/server/migrations/Migration20240103072610.ts b/apps/ai/src/server/migrations/Migration20240103072610.ts index cb891e9107..1a7ab9c903 100644 --- a/apps/ai/src/server/migrations/Migration20240103072610.ts +++ b/apps/ai/src/server/migrations/Migration20240103072610.ts @@ -1,15 +1,27 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240103072610 extends Migration { async up(): Promise { - this.addSql('alter table `dataset_version` add `shared_status` varchar(255) not null;'); - this.addSql('alter table `dataset_version` drop `is_shared`;'); + this.addSql("alter table `dataset_version` add `shared_status` varchar(255) not null;"); + this.addSql("alter table `dataset_version` drop `is_shared`;"); } async down(): Promise { - this.addSql('alter table `dataset_version` add `is_shared` tinyint(1) not null;'); - this.addSql('alter table `dataset_version` drop `shared_status`;'); + this.addSql("alter table `dataset_version` add `is_shared` tinyint(1) not null;"); + this.addSql("alter table `dataset_version` drop `shared_status`;"); } } diff --git a/apps/ai/src/server/migrations/Migration20240112074625.ts b/apps/ai/src/server/migrations/Migration20240112074625.ts index 4fcb0ded4b..0d790a2934 100644 --- a/apps/ai/src/server/migrations/Migration20240112074625.ts +++ b/apps/ai/src/server/migrations/Migration20240112074625.ts @@ -1,43 +1,57 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/* eslint-disable @stylistic/max-len */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240112074625 extends Migration { async up(): Promise { - this.addSql('alter table `modal_version` drop foreign key `modal_version_modal_id_foreign`;'); + this.addSql("alter table `modal_version` drop foreign key `modal_version_modal_id_foreign`;"); - this.addSql('create table `model` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `algorithm_framework` varchar(255) null comment \'algorithm algorithmFramework\', `algorithm_name` varchar(255) null comment \'algorithm name\', `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;'); + this.addSql("create table `model` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `algorithm_framework` varchar(255) null comment 'algorithm algorithmFramework', `algorithm_name` varchar(255) null comment 'algorithm name', `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;"); - this.addSql('create table `model_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `algorithm_version` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `shared_status` varchar(255) not null, `model_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;'); - this.addSql('alter table `model_version` add index `model_version_model_id_index`(`model_id`);'); + this.addSql("create table `model_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `algorithm_version` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `shared_status` varchar(255) not null, `model_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;"); + this.addSql("alter table `model_version` add index `model_version_model_id_index`(`model_id`);"); - this.addSql('alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade on delete CASCADE;'); + this.addSql("alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade on delete CASCADE;"); - this.addSql('drop table if exists `modal`;'); + this.addSql("drop table if exists `modal`;"); - this.addSql('drop table if exists `modal_version`;'); + this.addSql("drop table if exists `modal_version`;"); - this.addSql('alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;'); + this.addSql("alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;"); - this.addSql('alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade on delete CASCADE;'); + this.addSql("alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade on delete CASCADE;"); } async down(): Promise { - this.addSql('alter table `model_version` drop foreign key `model_version_model_id_foreign`;'); + this.addSql("alter table `model_version` drop foreign key `model_version_model_id_foreign`;"); - this.addSql('create table `modal` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `algorithm_framework` varchar(255) null comment \'algorithm algorithmFramework\', `algorithm_name` varchar(255) null comment \'algorithm name\', `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;'); + this.addSql("create table `modal` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `owner` varchar(255) not null, `algorithm_framework` varchar(255) null comment 'algorithm algorithmFramework', `algorithm_name` varchar(255) null comment 'algorithm name', `is_shared` tinyint(1) not null, `description` varchar(255) null, `cluster_id` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6)) default character set utf8mb4 engine = InnoDB;"); - this.addSql('create table `modal_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `algorithm_version` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `shared_status` varchar(255) not null, `modal_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;'); - this.addSql('alter table `modal_version` add index `modal_version_modal_id_index`(`modal_id`);'); + this.addSql("create table `modal_version` (`id` int unsigned not null auto_increment primary key, `version_name` varchar(255) not null, `version_description` varchar(255) null, `algorithm_version` varchar(255) null, `private_path` varchar(255) not null, `path` varchar(255) not null, `create_time` DATETIME(6) not null default current_timestamp(6), `update_time` DATETIME(6) not null default current_timestamp(6), `shared_status` varchar(255) not null, `modal_id` int unsigned not null) default character set utf8mb4 engine = InnoDB;"); + this.addSql("alter table `modal_version` add index `modal_version_modal_id_index`(`modal_id`);"); - this.addSql('alter table `modal_version` add constraint `modal_version_modal_id_foreign` foreign key (`modal_id`) references `modal` (`id`) on update cascade;'); + this.addSql("alter table `modal_version` add constraint `modal_version_modal_id_foreign` foreign key (`modal_id`) references `modal` (`id`) on update cascade;"); - this.addSql('drop table if exists `model`;'); + this.addSql("drop table if exists `model`;"); - this.addSql('drop table if exists `model_version`;'); + this.addSql("drop table if exists `model_version`;"); - this.addSql('alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;'); + this.addSql("alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;"); - this.addSql('alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;'); + this.addSql("alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;"); } } diff --git a/apps/ai/src/server/migrations/Migration20240126070152.ts b/apps/ai/src/server/migrations/Migration20240126070152.ts index dabcebaa8d..d959b257fb 100644 --- a/apps/ai/src/server/migrations/Migration20240126070152.ts +++ b/apps/ai/src/server/migrations/Migration20240126070152.ts @@ -1,17 +1,29 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240126070152 extends Migration { async up(): Promise { - this.addSql('alter table `image` add `status` enum(\'CREATED\', \'CREATING\', \'FAILURE\') not null;'); - this.addSql('alter table `image` modify `path` varchar(255) null;'); - this.addSql('alter table `image` add unique `unique_name_tag_owner`(`name`, `tag`, `owner`);'); + this.addSql("alter table `image` add `status` enum('CREATED', 'CREATING', 'FAILURE') not null;"); + this.addSql("alter table `image` modify `path` varchar(255) null;"); + this.addSql("alter table `image` add unique `unique_name_tag_owner`(`name`, `tag`, `owner`);"); } async down(): Promise { - this.addSql('alter table `image` modify `path` varchar(255) not null;'); - this.addSql('alter table `image` drop index `unique_name_tag_owner`;'); - this.addSql('alter table `image` drop `status`;'); + this.addSql("alter table `image` modify `path` varchar(255) not null;"); + this.addSql("alter table `image` drop index `unique_name_tag_owner`;"); + this.addSql("alter table `image` drop `status`;"); } } diff --git a/apps/ai/src/server/migrations/Migration20240129034339.ts b/apps/ai/src/server/migrations/Migration20240129034339.ts index 87736bd5b3..135b6f1546 100644 --- a/apps/ai/src/server/migrations/Migration20240129034339.ts +++ b/apps/ai/src/server/migrations/Migration20240129034339.ts @@ -1,33 +1,47 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/* eslint-disable @stylistic/max-len */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240129034339 extends Migration { async up(): Promise { - this.addSql('alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;'); + this.addSql("alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;"); - this.addSql('alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;'); + this.addSql("alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;"); - this.addSql('alter table `model_version` drop foreign key `model_version_model_id_foreign`;'); + this.addSql("alter table `model_version` drop foreign key `model_version_model_id_foreign`;"); - this.addSql('alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;'); + this.addSql("alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;"); - this.addSql('alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade;'); + this.addSql("alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade;"); - this.addSql('alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade;'); + this.addSql("alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade;"); } async down(): Promise { - this.addSql('alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;'); + this.addSql("alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;"); - this.addSql('alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;'); + this.addSql("alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;"); - this.addSql('alter table `model_version` drop foreign key `model_version_model_id_foreign`;'); + this.addSql("alter table `model_version` drop foreign key `model_version_model_id_foreign`;"); - this.addSql('alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade on delete CASCADE;'); + this.addSql("alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade on delete CASCADE;"); - this.addSql('alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade on delete CASCADE;'); + this.addSql("alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade on delete CASCADE;"); - this.addSql('alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade on delete CASCADE;'); + this.addSql("alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade on delete CASCADE;"); } } diff --git a/apps/ai/src/server/migrations/Migration20240131083455.ts b/apps/ai/src/server/migrations/Migration20240131083455.ts index 8dbaacc85b..dbdd51fc6e 100644 --- a/apps/ai/src/server/migrations/Migration20240131083455.ts +++ b/apps/ai/src/server/migrations/Migration20240131083455.ts @@ -1,33 +1,47 @@ -import { Migration } from '@mikro-orm/migrations'; +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/* eslint-disable @stylistic/max-len */ + +import { Migration } from "@mikro-orm/migrations"; export class Migration20240131083455 extends Migration { async up(): Promise { - this.addSql('alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;'); + this.addSql("alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;"); - this.addSql('alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;'); + this.addSql("alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;"); - this.addSql('alter table `model_version` drop foreign key `model_version_model_id_foreign`;'); + this.addSql("alter table `model_version` drop foreign key `model_version_model_id_foreign`;"); - this.addSql('alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade on delete cascade;'); + this.addSql("alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade on delete cascade;"); - this.addSql('alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade on delete cascade;'); + this.addSql("alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade on delete cascade;"); - this.addSql('alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade on delete cascade;'); + this.addSql("alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade on delete cascade;"); } async down(): Promise { - this.addSql('alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;'); + this.addSql("alter table `algorithm_version` drop foreign key `algorithm_version_algorithm_id_foreign`;"); - this.addSql('alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;'); + this.addSql("alter table `dataset_version` drop foreign key `dataset_version_dataset_id_foreign`;"); - this.addSql('alter table `model_version` drop foreign key `model_version_model_id_foreign`;'); + this.addSql("alter table `model_version` drop foreign key `model_version_model_id_foreign`;"); - this.addSql('alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;'); + this.addSql("alter table `algorithm_version` add constraint `algorithm_version_algorithm_id_foreign` foreign key (`algorithm_id`) references `algorithm` (`id`) on update cascade;"); - this.addSql('alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade;'); + this.addSql("alter table `dataset_version` add constraint `dataset_version_dataset_id_foreign` foreign key (`dataset_id`) references `dataset` (`id`) on update cascade;"); - this.addSql('alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade;'); + this.addSql("alter table `model_version` add constraint `model_version_model_id_foreign` foreign key (`model_id`) references `model` (`id`) on update cascade;"); } } diff --git a/apps/ai/src/server/migrations/index.ts b/apps/ai/src/server/migrations/index.ts index 94b21e8bfa..baa8669da4 100644 --- a/apps/ai/src/server/migrations/index.ts +++ b/apps/ai/src/server/migrations/index.ts @@ -11,12 +11,12 @@ */ import { Migration20240102091246 } from "./Migration20240102091246"; +import { Migration20240103020827 } from "./Migration20240103020827"; import { Migration20240103024536 } from "./Migration20240103024536"; -import { Migration20240103020827 } from './Migration20240103020827' import { Migration20240103072610 } from "./Migration20240103072610"; import { Migration20240112074625 } from "./Migration20240112074625"; import { Migration20240126070152 } from "./Migration20240126070152"; -import { Migration20240129034339 } from "./Migration20240129034339" +import { Migration20240129034339 } from "./Migration20240129034339"; import { Migration20240131083455 } from "./Migration20240131083455"; @@ -29,5 +29,5 @@ export const migrations = Migration20240112074625, Migration20240126070152, Migration20240129034339, - Migration20240131083455 + Migration20240131083455, ].map((x) => ({ name: x.name, class: x })); diff --git a/apps/ai/src/server/setup/jobShell.ts b/apps/ai/src/server/setup/jobShell.ts index 63f1378034..dcd7b98fbf 100644 --- a/apps/ai/src/server/setup/jobShell.ts +++ b/apps/ai/src/server/setup/jobShell.ts @@ -24,12 +24,12 @@ import { BASE_PATH } from "src/utils/processEnv"; import { PassThrough } from "stream"; import { WebSocket, WebSocketServer } from "ws"; -export type ShellQuery = { +export interface ShellQuery { cluster: string; cols?: string; rows?: string; -} +}; export type ShellInputData = | { $case: "resize", resize: { cols: number; rows: number } } @@ -150,7 +150,7 @@ wss.on("connection", async (ws: AliveCheckedWebSocket, req) => { ws.isAlive = true; ws.on("pong", () => { // 使用箭头函数确保this上下文为AliveCheckedWebSocket - heartbeat.call(ws as AliveCheckedWebSocket); + heartbeat.call(ws); }); ws.ping(); @@ -207,19 +207,20 @@ wss.on("connection", async (ws: AliveCheckedWebSocket, req) => { // 监听来自客户端WebSocket的消息并写入stdinStream ws.on("message", (data) => { + // eslint-disable-next-line @typescript-eslint/no-base-to-string const message = JSON.parse(data.toString()); switch (message.$case) { - case "data": - stdinStream.write(message.data.data); - break; - case "resize": - stdinStream.write( - `stty cols ${message.resize.cols} rows ${message.resize.rows}\n`); - break; - case "disconnect": - stdinStream.end(); - break; + case "data": + stdinStream.write(message.data.data); + break; + case "resize": + stdinStream.write( + `stty cols ${message.resize.cols} rows ${message.resize.rows}\n`); + break; + case "disconnect": + stdinStream.end(); + break; } }); diff --git a/apps/ai/src/server/trpc/context.ts b/apps/ai/src/server/trpc/context.ts index 77cf5f0895..c67c97e5ed 100644 --- a/apps/ai/src/server/trpc/context.ts +++ b/apps/ai/src/server/trpc/context.ts @@ -15,16 +15,16 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { ClientUserInfo } from "src/server/trpc/route/auth"; -export type Context = object +export type Context = object; export type SSRContext = Context & { req: NextApiRequest res: NextApiResponse user?: ClientUserInfo [key: string]: unknown -} +}; -export type GlobalContext = SSRContext +export type GlobalContext = SSRContext; export function isSSRContext( ctx: GlobalContext, diff --git a/apps/ai/src/server/trpc/route/algorithm/algorithm.ts b/apps/ai/src/server/trpc/route/algorithm/algorithm.ts index 0916579b8d..86b1ff4ac0 100644 --- a/apps/ai/src/server/trpc/route/algorithm/algorithm.ts +++ b/apps/ai/src/server/trpc/route/algorithm/algorithm.ts @@ -63,7 +63,7 @@ export const getAlgorithms = procedure const [items, count] = await em.findAndCount(Algorithm, { $and:[ isPublic ? { isShared:true } : - { owner: user!.identityId }, + { owner: user.identityId }, framework ? { framework } : {}, clusterId ? { clusterId } : {}, nameOrDesc ? @@ -123,7 +123,7 @@ export const createAlgorithm = procedure } const em = await forkEntityManager(); - const algorithmExist = await em.findOne(Algorithm, { name:input.name, owner: user!.identityId }); + const algorithmExist = await em.findOne(Algorithm, { name:input.name, owner: user.identityId }); if (algorithmExist) { throw new TRPCError({ code: "CONFLICT", @@ -131,7 +131,7 @@ export const createAlgorithm = procedure }); } - const algorithm = new Algorithm({ ...input, owner: user!.identityId }); + const algorithm = new Algorithm({ ...input, owner: user.identityId }); await em.persistAndFlush(algorithm); return algorithm.id; }); diff --git a/apps/ai/src/server/trpc/route/algorithm/algorithmVersion.ts b/apps/ai/src/server/trpc/route/algorithm/algorithmVersion.ts index c43437eb23..95cbcaf002 100644 --- a/apps/ai/src/server/trpc/route/algorithm/algorithmVersion.ts +++ b/apps/ai/src/server/trpc/route/algorithm/algorithmVersion.ts @@ -532,7 +532,7 @@ export const copyPublicAlgorithmVersion = procedure console.log(err); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", - message: `Copy Error ${err}`, + message: `Copy Error ${err as any}`, }); } diff --git a/apps/ai/src/server/trpc/route/auth.ts b/apps/ai/src/server/trpc/route/auth.ts index 9953851494..7eeaa4283e 100644 --- a/apps/ai/src/server/trpc/route/auth.ts +++ b/apps/ai/src/server/trpc/route/auth.ts @@ -151,7 +151,7 @@ export const auth = router({ password: oldPassword, }, console); - if (!checkRes || !checkRes.success) { + if (!checkRes?.success) { throw new TRPCError({ message: ErrorCode.OLD_PASSWORD_IS_WRONG, code: "CONFLICT", diff --git a/apps/ai/src/server/trpc/route/dataset/dataset.ts b/apps/ai/src/server/trpc/route/dataset/dataset.ts index 037caed99f..52eb7d384b 100644 --- a/apps/ai/src/server/trpc/route/dataset/dataset.ts +++ b/apps/ai/src/server/trpc/route/dataset/dataset.ts @@ -138,7 +138,7 @@ export const createDataset = procedure const em = await forkEntityManager(); - const datesetExist = await em.findOne(Dataset, { name:input.name, owner: user!.identityId }); + const datesetExist = await em.findOne(Dataset, { name:input.name, owner: user.identityId }); if (datesetExist) { throw new TRPCError({ code: "CONFLICT", @@ -146,7 +146,7 @@ export const createDataset = procedure }); } - const dataset = new Dataset({ ...input, owner: user!.identityId }); + const dataset = new Dataset({ ...input, owner: user.identityId }); await em.persistAndFlush(dataset); return dataset.id; }); diff --git a/apps/ai/src/server/trpc/route/dataset/datasetVersion.ts b/apps/ai/src/server/trpc/route/dataset/datasetVersion.ts index 8211372133..5502d41f0e 100644 --- a/apps/ai/src/server/trpc/route/dataset/datasetVersion.ts +++ b/apps/ai/src/server/trpc/route/dataset/datasetVersion.ts @@ -561,7 +561,7 @@ export const copyPublicDatasetVersion = procedure } catch (err) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", - message: `Copy Error ${err}`, + message: `Copy Error ${err as any}`, }); } diff --git a/apps/ai/src/server/trpc/route/file.ts b/apps/ai/src/server/trpc/route/file.ts index f5f46fad58..56332490b0 100644 --- a/apps/ai/src/server/trpc/route/file.ts +++ b/apps/ai/src/server/trpc/route/file.ts @@ -237,7 +237,7 @@ export const file = router({ throw new TRPCError({ code: "PRECONDITION_FAILED", message: `${path} is not accessible` }); }); - if (!stat || !stat.isDirectory()) { + if (!stat?.isDirectory()) { throw new TRPCError({ code: "UNPROCESSABLE_CONTENT", message: `${path} is not directory or not exists` }); } @@ -406,7 +406,7 @@ export const file = router({ } }; - return await sshConnect(host, user!.identityId, logger, async (ssh) => { + return await sshConnect(host, user.identityId, logger, async (ssh) => { const sftp = await ssh.requestSFTP(); const stat = await sftpStat(sftp)(filePath).catch((e) => { diff --git a/apps/ai/src/server/trpc/route/image/image.ts b/apps/ai/src/server/trpc/route/image/image.ts index da2caf8358..90eca5c5cd 100644 --- a/apps/ai/src/server/trpc/route/image/image.ts +++ b/apps/ai/src/server/trpc/route/image/image.ts @@ -353,7 +353,7 @@ export const deleteImage = procedure } try { const errorBody = JSON.parse(errorText); // 尝试解析为 JSON - const errorMessage = errorBody.errors.map((i: {message?: string}) => i.message).join(); + const errorMessage = errorBody.errors.map((i: { message?: string }) => i.message).join(); logger.error("Failed to get image reference url %s: %s", getReferenceUrl, errorMessage); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", @@ -408,7 +408,7 @@ export const deleteImage = procedure if (!deleteArtifact.ok) { const errorBody = await deleteArtifact.json(); // 来自harbor的错误信息 - const errorMessage = errorBody.errors.map((i: {message?: string}) => i.message).join(); + const errorMessage = errorBody.errors.map((i: { message?: string }) => i.message).join(); logger.error("Failed to delete image artifact url %s", deleteArtifactUrl); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", @@ -434,7 +434,7 @@ export const deleteImage = procedure if (!deleteRes.ok) { const errorBody = await deleteRes.json(); // 来自harbor的错误信息 - const errorMessage = errorBody.errors.map((i: {message?: string}) => i.message).join(); + const errorMessage = errorBody.errors.map((i: { message?: string }) => i.message).join(); logger.error("Failed to delete image tag url %s", deleteUrl); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", diff --git a/apps/ai/src/server/trpc/route/jobs/apps.ts b/apps/ai/src/server/trpc/route/jobs/apps.ts index 9804e180f9..2b60f287f1 100644 --- a/apps/ai/src/server/trpc/route/jobs/apps.ts +++ b/apps/ai/src/server/trpc/route/jobs/apps.ts @@ -59,7 +59,7 @@ const ImageSchema = z.object({ tag: z.string().optional(), }); -export type Image = z.infer +export type Image = z.infer; const JobTypeSchema = z.nativeEnum(JobType); @@ -146,6 +146,7 @@ const AppCustomAttributeSchema = z.object({ export type AppCustomAttribute = z.infer; +// eslint-disable-next-line @typescript-eslint/no-unused-vars const AttributeTypeSchema = z.enum(["TEXT", "NUMBER", "SELECT"]); export type AttributeType = z.infer; @@ -286,39 +287,39 @@ export const createAppSession = procedure } switch (attribute.type) { - case "number": - if (customAttributes[attribute.name] && Number.isNaN(Number(customAttributes[attribute.name]))) { - throw new TRPCError({ - code: "BAD_REQUEST", - message: `custom form attribute ${ - attribute.name} should be of type number, but of type ${typeof customAttributes[attribute.name]}`, - }); - } - break; + case "number": + if (customAttributes[attribute.name] && Number.isNaN(Number(customAttributes[attribute.name]))) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: `custom form attribute ${ + attribute.name} should be of type number, but of type ${typeof customAttributes[attribute.name]}`, + }); + } + break; - case "text": - break; + case "text": + break; - case "select": + case "select": // check the option selected by user is in select attributes as the config defined - if (customAttributes[attribute.name] + if (customAttributes[attribute.name] && !(attribute.select!.some((optionItem) => optionItem.value === customAttributes[attribute.name]))) { - throw new TRPCError({ - code: "BAD_REQUEST", - message: ` + throw new TRPCError({ + code: "BAD_REQUEST", + message: ` the option value of ${attribute.name} selected by user should be one of select attributes as the ${appId} config defined, but is ${customAttributes[attribute.name]}`, - }); - } - break; + }); + } + break; - default: - throw new TRPCError({ - code: "BAD_REQUEST", - message: `the custom form attributes type in ${appId} config should be one of number, text or select, - but the type of ${attribute.name} is ${attribute.type}`, - }); + default: + throw new TRPCError({ + code: "BAD_REQUEST", + message: `the custom form attributes type in ${appId} config should be one of number, text or select, + but the type of ${attribute.name} is ${attribute.type as string}`, + }); } }); @@ -395,8 +396,8 @@ export const createAppSession = procedure if (app.type === "web") { for (const key in app.web!.connect.formData) { const texts = getPlaceholderKeys(app.web!.connect.formData[key]); - for (const i in texts) { - customForm += `,\\\"${texts[i]}\\\":\\\"$${texts[i]}\\\"`; + for (const i of texts) { + customForm += `,\\"${i}\\":\\"$${i}\\"`; } } } @@ -426,7 +427,7 @@ export const createAppSession = procedure } else { throw new TRPCError({ code: "NOT_FOUND", - message: `Unknown app type ${app.type} of app id ${appId}`, + message: `Unknown app type ${app.type as string} of app id ${appId}`, }); } @@ -849,7 +850,7 @@ procedure } else { return { ok: false }; } - } catch (_) { + } catch { return { ok: false }; } }, @@ -957,36 +958,36 @@ procedure } switch (app.type) { - case AppType.vnc: - return { - host: reply.host, - port: reply.port, - password: reply.password, - type: "vnc", - vnc: {}, - }; - break; - case AppType.web: - return { - host: reply.host, - port: reply.port, - password: reply.password, - type: "web", - connect : { - method:app.web!.connect.method, - query: app.web!.connect.query ?? {}, - formData: app.web!.connect.formData ?? {}, - path: app.web!.connect.path, - }, - proxyType: app.web!.proxyType === "absolute" - ? "absolute" - : "relative", - }; - default: - throw new TRPCError({ - code: "NOT_FOUND", - message: `Unknown app type ${app.type} of app id ${reply.appId}`, - }); + case AppType.vnc: + return { + host: reply.host, + port: reply.port, + password: reply.password, + type: "vnc", + vnc: {}, + }; + break; + case AppType.web: + return { + host: reply.host, + port: reply.port, + password: reply.password, + type: "web", + connect : { + method:app.web!.connect.method, + query: app.web!.connect.query ?? {}, + formData: app.web!.connect.formData ?? {}, + path: app.web!.connect.path, + }, + proxyType: app.web!.proxyType === "absolute" + ? "absolute" + : "relative", + }; + default: + throw new TRPCError({ + code: "NOT_FOUND", + message: `Unknown app type ${app.type as string} of app id ${reply.appId}`, + }); } }); diff --git a/apps/ai/src/server/trpc/route/jobs/jobs.ts b/apps/ai/src/server/trpc/route/jobs/jobs.ts index 16c9702e08..1153adf3a9 100644 --- a/apps/ai/src/server/trpc/route/jobs/jobs.ts +++ b/apps/ai/src/server/trpc/route/jobs/jobs.ts @@ -34,12 +34,13 @@ import { z } from "zod"; const SESSION_METADATA_NAME = "session.json"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars const ImageSchema = z.object({ name: z.string(), tag: z.string().optional(), }); -export type Image = z.infer +export type Image = z.infer; interface SessionMetadata { sessionId: string; diff --git a/apps/ai/src/server/trpc/route/model/modelVersion.ts b/apps/ai/src/server/trpc/route/model/modelVersion.ts index 38e7a5c49c..15627606cc 100644 --- a/apps/ai/src/server/trpc/route/model/modelVersion.ts +++ b/apps/ai/src/server/trpc/route/model/modelVersion.ts @@ -110,7 +110,7 @@ export const createModelVersion = procedure throw new TRPCError({ code: "NOT_FOUND", message: `Model ${input.modelId} not found` }); } - if (model.owner !== user!.identityId) { + if (model.owner !== user.identityId) { throw new TRPCError({ code: "FORBIDDEN", message: `Model ${input.modelId} not accessible` }); } @@ -163,7 +163,7 @@ export const updateModelVersion = procedure throw new TRPCError({ code: "NOT_FOUND", message: `Model ${modelId} not found` }); } - if (model.owner !== user!.identityId) { + if (model.owner !== user.identityId) { throw new TRPCError({ code: "FORBIDDEN", message: `Model ${modelId} not accessible` }); } @@ -203,7 +203,7 @@ export const updateModelVersion = procedure modelVersion.versionName = versionName; modelVersion.versionDescription = versionDescription; - modelVersion.algorithmVersion = algorithmVersion, + modelVersion.algorithmVersion = algorithmVersion; await em.flush(); return { id: modelVersion.id }; @@ -237,7 +237,7 @@ export const deleteModelVersion = procedure throw new TRPCError({ code: "NOT_FOUND", message: `Model ${input.modelId} not found` }); } - if (model.owner !== user!.identityId) { + if (model.owner !== user.identityId) { throw new TRPCError({ code: "FORBIDDEN", message: `Model ${input.modelId} not accessible` }); } @@ -551,7 +551,7 @@ export const copyPublicModelVersion = procedure console.log(err); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", - message: `Copy Error ${err}`, + message: `Copy Error ${err as any}`, }); } diff --git a/apps/ai/src/server/trpc/router.ts b/apps/ai/src/server/trpc/router.ts index bf93c9418a..c56073a0b0 100644 --- a/apps/ai/src/server/trpc/router.ts +++ b/apps/ai/src/server/trpc/router.ts @@ -36,6 +36,6 @@ export const appRouter = trpc.router({ jobs: jobsRouter, }); -export type AppRouter = typeof appRouter +export type AppRouter = typeof appRouter; -export type Caller = ReturnType +export type Caller = ReturnType; diff --git a/apps/ai/src/server/utils/app.ts b/apps/ai/src/server/utils/app.ts index 355a4e8f6c..fd2db61c0b 100644 --- a/apps/ai/src/server/utils/app.ts +++ b/apps/ai/src/server/utils/app.ts @@ -156,7 +156,7 @@ export const fetchJobInputParams = async ( return schema.parse(parsedContent); } catch (e) { - logger.error(`Failed to parse input params file ${inputParamsPath}: ${e}`); + logger.error(`Failed to parse input params file ${inputParamsPath}: ${e as any}`); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Failed to parse input params file ${inputParamsPath}`, @@ -167,7 +167,7 @@ export const fetchJobInputParams = async ( export const validateUniquePaths = (paths: (string | undefined)[]) => { // 移除尾随斜杠并返回规范化的路径 - const normalizedPaths = paths.map((path) => path && path.replace(/\/+$/, "")); + const normalizedPaths = paths.map((path) => path?.replace(/\/+$/, "")); const pathSet = new Set(); for (const path of normalizedPaths) { diff --git a/apps/ai/src/server/utils/errors.ts b/apps/ai/src/server/utils/errors.ts index be794cd451..dbed2da146 100644 --- a/apps/ai/src/server/utils/errors.ts +++ b/apps/ai/src/server/utils/errors.ts @@ -13,9 +13,9 @@ import { TRPCError } from "@trpc/server"; export const clusterNotFound = (cluster: string) => { - return { code: "NOT_FOUND", message: `cluster ${cluster} is not found` }; + return { code: "NOT_FOUND", message: `cluster ${cluster} is not found` } as TRPCError; }; export const loginNodeNotFound = (loginNode: string) => { - return { code: "NOT_FOUND", message: `login node ${loginNode} is not found` }; + return { code: "NOT_FOUND", message: `login node ${loginNode} is not found` } as TRPCError; }; diff --git a/apps/ai/src/server/utils/image.ts b/apps/ai/src/server/utils/image.ts index a2fa30de40..74913e6847 100644 --- a/apps/ai/src/server/utils/image.ts +++ b/apps/ai/src/server/utils/image.ts @@ -32,7 +32,7 @@ export function createHarborImageUrl(imageName: string, imageTag: string, userId export enum k8sRuntime { docker = "docker", - containerd = "containerd" + containerd = "containerd", } const runtimeCommands = { @@ -76,7 +76,7 @@ export async function getLoadedImage({ const command = getRuntimeCommand(runtime); const loadedResp = await loggedExec(ssh, logger, true, command, ["load", "-i", sourcePath]); - const match = loadedResp.stdout.match(loadedImageRegex); + const match = loadedImageRegex.exec(loadedResp.stdout); return match && match.length > 1 ? match[1] : undefined; } diff --git a/apps/ai/src/server/utils/share.ts b/apps/ai/src/server/utils/share.ts index 9811ff86f6..fd78a95b95 100644 --- a/apps/ai/src/server/utils/share.ts +++ b/apps/ai/src/server/utils/share.ts @@ -123,16 +123,16 @@ export async function shareFileOrDir( const cpAndChmodCmd = `nohup cp -r --preserve=links ${sourceFilePath} ${targetFullDir} && chmod -R 555 ${targetTopDir}`; await ssh.execCommand(cpAndChmodCmd).catch((e) => { - failureCallback && failureCallback(); + failureCallback?.(); logger.info("Failed to share %s to %s with error %s", sourceFilePath, targetFullDir, e); }); - successCallback && successCallback(targetFullDir); + successCallback?.(targetFullDir); }); } catch (err) { logger.info("share file failed", err); - failureCallback && failureCallback(); + failureCallback?.(); } } @@ -155,10 +155,10 @@ export async function unShareFileOrDir({ const sftp = await ssh.requestSFTP(); await sftpExists(sftp, sharedPath); await sshRmrf(ssh, sharedPath); - successCallback && successCallback(); + successCallback?.(); }).catch((err) => { logger.info("unShare file failed", err); - failureCallback && failureCallback(); + failureCallback?.(); }); } diff --git a/apps/ai/src/utils/array.ts b/apps/ai/src/utils/array.ts index bfe295d10e..744be45e3f 100644 --- a/apps/ai/src/utils/array.ts +++ b/apps/ai/src/utils/array.ts @@ -18,7 +18,7 @@ export function range(start = 1, end = 0, step = 1): number[] { return r; } -export function flatten(nestedArray: Array>): T[] { +export function flatten(nestedArray: (T | T[])[]): T[] { const result = [] as T[]; for (const item of nestedArray) { if (Array.isArray(item)) { diff --git a/apps/ai/src/utils/common.ts b/apps/ai/src/utils/common.ts index e4accb581e..e0638b0994 100644 --- a/apps/ai/src/utils/common.ts +++ b/apps/ai/src/utils/common.ts @@ -15,16 +15,16 @@ import { SharedStatus } from "src/models/common"; export const getSharedStatusText = (status: SharedStatus) => { switch (status) { - case SharedStatus.SHARED: - return "取消分享"; + case SharedStatus.SHARED: + return "取消分享"; - case SharedStatus.UNSHARING: - return "取消分享中"; + case SharedStatus.UNSHARING: + return "取消分享中"; - case SharedStatus.SHARING: - return "分享中"; + case SharedStatus.SHARING: + return "分享中"; - default: - return "分享"; + default: + return "分享"; } }; diff --git a/apps/ai/src/utils/form.ts b/apps/ai/src/utils/form.ts index f09b7699ea..f42653b62b 100644 --- a/apps/ai/src/utils/form.ts +++ b/apps/ai/src/utils/form.ts @@ -35,7 +35,7 @@ export const validateNoChinese = (_: RuleObject, value: any) => { export const imageNameValidation = (_: RuleObject, value: any) => { // 由字母(小写)、数字、"_"、"-"和"."组成,不能以符号开始或结束, 小于128字符 - if (/^[a-z0-9]([a-z0-9_\-\.]{0,126}[a-z0-9])?$/.test(value)) { + if (/^[a-z0-9]([a-z0-9_\-.]{0,126}[a-z0-9])?$/.test(value)) { return Promise.resolve(); } @@ -44,7 +44,7 @@ export const imageNameValidation = (_: RuleObject, value: any) => { export const imageTagValidation = (_: RuleObject, value: any) => { // 由字母、数字、"_"、"-"和"."组成,不能以符号开始或结束, 小于128字符 - if (/^[a-zA-Z0-9]([a-zA-Z0-9_\-\.]{0,126}[a-zA-Z0-9])?$/.test(value)) { + if (/^[a-zA-Z0-9]([a-zA-Z0-9_\-.]{0,126}[a-zA-Z0-9])?$/.test(value)) { return Promise.resolve(); } diff --git a/apps/ai/src/utils/head.tsx b/apps/ai/src/utils/head.tsx index a79f5a894a..5b12de678a 100644 --- a/apps/ai/src/utils/head.tsx +++ b/apps/ai/src/utils/head.tsx @@ -14,7 +14,7 @@ import NextHead from "next/head"; type Props = React.PropsWithChildren<{ title: string; -}> +}>; export const Head: React.FC = ({ title, children }) => { return ( diff --git a/apps/ai/src/utils/parse.ts b/apps/ai/src/utils/parse.ts index 43e4f3abe9..9e82b326dc 100644 --- a/apps/ai/src/utils/parse.ts +++ b/apps/ai/src/utils/parse.ts @@ -36,7 +36,7 @@ export function parseKeyValue(input: string): Record { * @returns replaced string */ export function parsePlaceholder(str: string, valueObj: Record) { - return str.replace(/\{\{\ ([a-zA-Z0-9_]+)\ \}\}/g, (_, p1: string) => valueObj[p1] ?? ""); + return str.replace(/\{\{ ([a-zA-Z0-9_]+) \}\}/g, (_, p1: string) => valueObj[p1] ?? ""); } /** diff --git a/apps/ai/src/utils/url.ts b/apps/ai/src/utils/url.ts index 9340b1125e..48594c9a46 100644 --- a/apps/ai/src/utils/url.ts +++ b/apps/ai/src/utils/url.ts @@ -12,7 +12,7 @@ import { normalize } from "path"; -export const toHref = ({ pathname = "", query }: { pathname?: string, query?: Record}) => { +export const toHref = ({ pathname = "", query }: { pathname?: string, query?: Record }) => { if (!query) { return pathname; } diff --git a/apps/mis-web/eslint.config.js b/apps/mis-web/eslint.config.js index 80c003f736..4cea25ff4a 100644 --- a/apps/mis-web/eslint.config.js +++ b/apps/mis-web/eslint.config.js @@ -1,7 +1,27 @@ +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + const base = require("../../eslint.config"); const react = require("@ddadaal/eslint-config/react"); -module.export = { +module.exports = [ ...base, ...react, -}; + { + rules: { + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-unsafe-enum-comparison": "off", + "@typescript-eslint/no-misused-promises": "off", + "@typescript-eslint/only-throw-error": "off", + } + } +]; diff --git a/apps/mis-web/package.json b/apps/mis-web/package.json index 473194f19a..4377f8169c 100644 --- a/apps/mis-web/package.json +++ b/apps/mis-web/package.json @@ -24,6 +24,7 @@ "license": "Mulan PSL v2", "repository": "https://github.com/PKUHPC/SCOW", "dependencies": { + "@ant-design/cssinjs": "1.21.0", "@ant-design/icons": "5.3.7", "@ddadaal/next-typed-api-routes-runtime": "0.8.2", "@ddadaal/tsgrpc-client": "0.17.7", @@ -37,10 +38,11 @@ "@scow/lib-web": "workspace:*", "@scow/protos": "workspace:*", "@scow/rich-error-model": "workspace:*", + "@scow/utils": "workspace:*", "@sinclair/typebox": "0.32.34", "antd": "5.18.3", + "csv-stringify": "6.5.0", "dayjs": "1.11.11", - "@scow/utils": "workspace:*", "google-protobuf": "3.21.2", "http-proxy": "1.18.1", "iconv-lite": "^0.6.3", @@ -54,14 +56,12 @@ "react-async": "10.0.1", "react-dom": "18.3.1", "react-is": "18.3.1", + "react-typed-i18n": "2.3.0", "recharts": "^2.7.3", "simstate": "3.0.1", "styled-components": "6.1.11", "tslib": "2.6.3", - "typescript": "5.5.2", - "@ant-design/cssinjs": "1.21.0", - "react-typed-i18n": "2.3.0", - "csv-stringify": "6.5.0" + "typescript": "5.5.2" }, "devDependencies": { "@ddadaal/next-typed-api-routes-cli": "0.9.1", diff --git a/apps/mis-web/src/apis/api.mock.ts b/apps/mis-web/src/apis/api.mock.ts index 137875c6ef..f207ebbe5f 100644 --- a/apps/mis-web/src/apis/api.mock.ts +++ b/apps/mis-web/src/apis/api.mock.ts @@ -17,7 +17,7 @@ import { JobInfo } from "@scow/protos/build/common/ended_job"; import type { RunningJob } from "@scow/protos/build/common/job"; import { type Account } from "@scow/protos/build/server/account"; import type { AccountUserInfo, GetUserStatusResponse } from "@scow/protos/build/server/user"; -import { api } from "src/apis/api"; +import { type api } from "src/apis/api"; import { ClusterConnectionStatus } from "src/models/cluster"; import { OperationResult } from "src/models/operationLog"; import { AccountState, ClusterAccountInfo_ImportStatus, DisplayedAccountState, PlatformRole, @@ -26,15 +26,15 @@ import { DEFAULT_TENANT_NAME } from "src/utils/constants"; export type MockApi JsonFetchResultPromiseLike> - > = { [key in keyof TApi]: null | ( + (...args: any[]) => JsonFetchResultPromiseLike>, +> = {[key in keyof TApi]: null | ( (...args: Parameters) => Promise< ReturnType extends PromiseLike - ? TSuc - : never + ? TSuc + : never >) - }; +}; diff --git a/apps/mis-web/src/apis/api.ts b/apps/mis-web/src/apis/api.ts index b0f14d1d98..5dfbb0b58e 100644 --- a/apps/mis-web/src/apis/api.ts +++ b/apps/mis-web/src/apis/api.ts @@ -10,7 +10,7 @@ * See the Mulan PSL v2 for more details. */ -/* eslint-disable max-len */ +/* eslint-disable @stylistic/max-len */ import { apiClient } from "src/apis/client"; import type { GetClusterConfigFilesSchema } from "src/pages/api//clusterConfigsInfo"; @@ -93,7 +93,7 @@ import type { GetOperationLogsSchema } from "src/pages/api/log/getOperationLog"; import type { ChangeEmailSchema } from "src/pages/api/profile/changeEmail"; import type { ChangePasswordSchema } from "src/pages/api/profile/changePassword"; import type { CheckPasswordSchema } from "src/pages/api/profile/checkPassword"; -import { GetSimpleClustersInfoFromConfigFilesSchema } from "src/pages/api/simpleClustersInfo"; +import type { GetSimpleClustersInfoFromConfigFilesSchema } from "src/pages/api/simpleClustersInfo"; import type { DewhitelistAccountSchema } from "src/pages/api/tenant/accountWhitelist/dewhitelistAccount"; import type { GetWhitelistedAccountsSchema } from "src/pages/api/tenant/accountWhitelist/getWhitelistedAccounts"; import type { WhitelistAccountSchema } from "src/pages/api/tenant/accountWhitelist/whitelistAccount"; diff --git a/apps/mis-web/src/apis/index.ts b/apps/mis-web/src/apis/index.ts index 91b85a3f8f..d578b3f2c2 100644 --- a/apps/mis-web/src/apis/index.ts +++ b/apps/mis-web/src/apis/index.ts @@ -47,7 +47,7 @@ class MockPromise implements PromiseLike { } catch(onrejected?: ((reason: any) => TResult | PromiseLike) | null | undefined): - PromiseLike { + PromiseLike { return this.then(undefined, onrejected); } diff --git a/apps/mis-web/src/auth/requireAuth.tsx b/apps/mis-web/src/auth/requireAuth.tsx index ee735da050..df4cc2bbcf 100644 --- a/apps/mis-web/src/auth/requireAuth.tsx +++ b/apps/mis-web/src/auth/requireAuth.tsx @@ -20,7 +20,7 @@ import { User, UserStore } from "src/stores/UserStore"; type UserStoreType = ReturnType; export interface RequireAuthProps { - userStore: UserStoreType & { user: User }, + userStore: UserStoreType & { user: User } } export type Check = (info: UserInfo) => boolean; @@ -43,7 +43,7 @@ export const requireAuth = ( } if (extraCheck) { - const node = extraCheck(userStore.user!); + const node = extraCheck(userStore.user); if (node) { return node; } diff --git a/apps/mis-web/src/components/ChangePasswordModal.tsx b/apps/mis-web/src/components/ChangePasswordModal.tsx index 336286a0e8..61939123e9 100644 --- a/apps/mis-web/src/components/ChangePasswordModal.tsx +++ b/apps/mis-web/src/components/ChangePasswordModal.tsx @@ -17,16 +17,16 @@ import { prefix, useI18n, useI18nTranslateToString } from "src/i18n"; import { confirmPasswordFormItemProps, passwordRule } from "src/utils/form"; interface Props { - name: string; - userId: string; - onClose: () => void; - onComplete: (newPassword: string) => Promise; - open: boolean; + name: string; + userId: string; + onClose: () => void; + onComplete: (newPassword: string) => Promise; + open: boolean; } interface FormProps { - newPassword: string; - confirm: string; + newPassword: string; + confirm: string; } const p = prefix("component.others."); diff --git a/apps/mis-web/src/components/DeactivateClusterModal.tsx b/apps/mis-web/src/components/DeactivateClusterModal.tsx index 6aa11bfe9d..2fd43d053c 100644 --- a/apps/mis-web/src/components/DeactivateClusterModal.tsx +++ b/apps/mis-web/src/components/DeactivateClusterModal.tsx @@ -17,11 +17,11 @@ import { ModalLink } from "src/components/ModalLink"; import { prefix, useI18n, useI18nTranslate } from "src/i18n"; interface Props { - clusterId: string; - clusterName: string; - onClose: () => void; - onComplete: (confirmedClusterId: string, comment: string) => Promise; - open: boolean; + clusterId: string; + clusterName: string; + onClose: () => void; + onComplete: (confirmedClusterId: string, comment: string) => Promise; + open: boolean; } interface FormProps { diff --git a/apps/mis-web/src/components/JobBillingTable.tsx b/apps/mis-web/src/components/JobBillingTable.tsx index b30a14d2ff..adc32d20b7 100644 --- a/apps/mis-web/src/components/JobBillingTable.tsx +++ b/apps/mis-web/src/components/JobBillingTable.tsx @@ -63,8 +63,8 @@ export const JobBillingTable: React.FC = ({ data, loading, isUserPartitio const { activatedClusters } = useStore(ClusterInfoStore); - const clusterTotalQosCounts = data && data.length ? - data.reduce((totalQosCounts: { [cluster: string]: number }, item) => { + const clusterTotalQosCounts = data?.length ? + data.reduce((totalQosCounts: Record, item) => { const { cluster } = item; if (!totalQosCounts[cluster]) { totalQosCounts[cluster] = 1; diff --git a/apps/mis-web/src/components/ModalLink.tsx b/apps/mis-web/src/components/ModalLink.tsx index 90024a468b..53203773e3 100644 --- a/apps/mis-web/src/components/ModalLink.tsx +++ b/apps/mis-web/src/components/ModalLink.tsx @@ -14,56 +14,56 @@ import { Button, ButtonProps } from "antd"; import React, { useState } from "react"; export interface CommonModalProps { - open: boolean; - onClose: () => void; + open: boolean; + onClose: () => void; } export const ModalLink = ( ModalComponent: React.ComponentType, ) => (props: React.PropsWithChildren>) => { - const [open, setOpen] = useState(false); - const { children, ...rest } = props; + const [open, setOpen] = useState(false); + const { children, ...rest } = props; - return ( - <> - setOpen(true)}> - {children} - - {/** @ts-ignore */} - { - setOpen(false); - }} - {...rest} - /> - - ); + return ( + <> + setOpen(true)}> + {children} + + {/** @ts-ignore */} + { + setOpen(false); + }} + {...rest} + /> + + ); - }; +}; export const ModalButton = ( ModalComponent: React.ComponentType, buttonProps?: ButtonProps, ) => (props: React.PropsWithChildren>) => { - const [open, setOpen] = useState(false); - const { children, ...rest } = props; + const [open, setOpen] = useState(false); + const { children, ...rest } = props; - return ( - <> - - {/** @ts-ignore */} - { - setOpen(false); - }} - {...rest} - /> - - ); + return ( + <> + + {/** @ts-ignore */} + { + setOpen(false); + }} + {...rest} + /> + + ); - }; +}; diff --git a/apps/mis-web/src/components/OperationLogTable.tsx b/apps/mis-web/src/components/OperationLogTable.tsx index d6e6a320b5..9344bebfd9 100644 --- a/apps/mis-web/src/components/OperationLogTable.tsx +++ b/apps/mis-web/src/components/OperationLogTable.tsx @@ -164,8 +164,8 @@ export const OperationLogTable: React.FC = ({ user, queryType, accountNam return results.map((data) => { return { ...data, - operationCode: data.operationEvent?.["$case"] ? OperationCodeMap[data.operationEvent?.["$case"]] : "000000", - operationType: data.operationEvent?.["$case"] || "unknown", + operationCode: data.operationEvent?.$case ? OperationCodeMap[data.operationEvent?.$case] : "000000", + operationType: data.operationEvent?.$case || "unknown", operationDetail: getOperationDetail(data.operationEvent, t, tArgs, languageId), }; }); @@ -236,7 +236,7 @@ export const OperationLogTable: React.FC = ({ user, queryType, accountNam let customEventType: string | undefined; let formatOperationType: string | undefined; - if (operationType && operationType.startsWith("customEvent-")) { + if (operationType?.startsWith("customEvent-")) { formatOperationType = "customEvent"; customEventType = operationType.split("customEvent-")[1]; } else { diff --git a/apps/mis-web/src/components/errorPages/ForbiddenPage.tsx b/apps/mis-web/src/components/errorPages/ForbiddenPage.tsx index 6ede5a3bec..b56dc7c624 100644 --- a/apps/mis-web/src/components/errorPages/ForbiddenPage.tsx +++ b/apps/mis-web/src/components/errorPages/ForbiddenPage.tsx @@ -15,7 +15,7 @@ import React from "react"; import { prefix, useI18nTranslateToString } from "src/i18n"; import { Head } from "src/utils/head"; -// eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Props { title?: "notAllowedPage"; diff --git a/apps/mis-web/src/components/errorPages/NotAuthorizedPage.tsx b/apps/mis-web/src/components/errorPages/NotAuthorizedPage.tsx index 9da3edda90..8b617b44e5 100644 --- a/apps/mis-web/src/components/errorPages/NotAuthorizedPage.tsx +++ b/apps/mis-web/src/components/errorPages/NotAuthorizedPage.tsx @@ -17,7 +17,7 @@ import { Head } from "src/utils/head"; const p = prefix("component.errorPages."); -// eslint-disable-next-line @typescript-eslint/no-unused-vars + export const NotAuthorizedPage = () => { const t = useI18nTranslateToString(); diff --git a/apps/mis-web/src/components/errorPages/UnifiedErrorPage.tsx b/apps/mis-web/src/components/errorPages/UnifiedErrorPage.tsx index 09883b0d26..c25f369a85 100644 --- a/apps/mis-web/src/components/errorPages/UnifiedErrorPage.tsx +++ b/apps/mis-web/src/components/errorPages/UnifiedErrorPage.tsx @@ -21,7 +21,7 @@ import { ServerErrorPage } from "./ServerErrorPage"; interface Props { code: number; - customComponents?: { [code: number]: React.ReactElement }; + customComponents?: Record; } export const UnifiedErrorPage: React.FC = ({ @@ -38,13 +38,13 @@ export const UnifiedErrorPage: React.FC = ({ }, []); switch (code) { - case 401: - return customComponents[401] ?? ; - case 403: - return customComponents[403] ?? ; - case 404: - return customComponents[404] ?? ; - default: - return customComponents[code] ?? ; + case 401: + return customComponents[401] ?? ; + case 403: + return customComponents[403] ?? ; + case 404: + return customComponents[404] ?? ; + default: + return customComponents[code] ?? ; } }; diff --git a/apps/mis-web/src/i18n/index.ts b/apps/mis-web/src/i18n/index.ts index 7b75cd46f3..ee22f69edd 100644 --- a/apps/mis-web/src/i18n/index.ts +++ b/apps/mis-web/src/i18n/index.ts @@ -31,6 +31,7 @@ export const languageInfo = { en: { name: "US English" }, }; +// eslint-disable-next-line @typescript-eslint/unbound-method export const { Localized, Provider, id, prefix, useI18n } = createI18n(languages); export type TextId = TextIdFromLangDict; @@ -73,17 +74,17 @@ export async function getTArgs(languageId: string) { export function getI18nCurrentText( i18nObject: I18nObject | undefined, languageId: string | undefined): string { - if (!i18nObject || !i18nObject.i18n) { + if (!i18nObject?.i18n) { return ""; } // 当语言id或者对应的配置文本中某种语言不存在时,显示default的值 if (!languageId) return i18nObject.i18n.default; switch (languageId) { - case SYSTEM_VALID_LANGUAGES.EN: - return i18nObject.i18n.en || i18nObject.i18n.default; - case SYSTEM_VALID_LANGUAGES.ZH_CN: - return i18nObject.i18n.zhCn || i18nObject.i18n.default; - default: - return i18nObject.i18n.default; + case SYSTEM_VALID_LANGUAGES.EN: + return i18nObject.i18n.en || i18nObject.i18n.default; + case SYSTEM_VALID_LANGUAGES.ZH_CN: + return i18nObject.i18n.zhCn || i18nObject.i18n.default; + default: + return i18nObject.i18n.default; } }; diff --git a/apps/mis-web/src/layouts/AntdConfigProvider.tsx b/apps/mis-web/src/layouts/AntdConfigProvider.tsx index f2ff770c1c..42bc7f4786 100644 --- a/apps/mis-web/src/layouts/AntdConfigProvider.tsx +++ b/apps/mis-web/src/layouts/AntdConfigProvider.tsx @@ -65,11 +65,11 @@ export const AntdConfigProvider: React.FC = ({ children, color, locale }) function getAntdLocale(langId: string): Locale { switch (langId) { - case SYSTEM_VALID_LANGUAGES.ZH_CN: - return zhCNlocale; - case SYSTEM_VALID_LANGUAGES.EN: - default: - return enUSlocale; + case SYSTEM_VALID_LANGUAGES.ZH_CN: + return zhCNlocale; + case SYSTEM_VALID_LANGUAGES.EN: + default: + return enUSlocale; } } diff --git a/apps/mis-web/src/models/User.ts b/apps/mis-web/src/models/User.ts index 576d618a8e..4677126c97 100644 --- a/apps/mis-web/src/models/User.ts +++ b/apps/mis-web/src/models/User.ts @@ -164,11 +164,11 @@ export const ChargesSortBy = Type.Union([ Type.Literal("type"), ]); -export type ChargesSortBy = Static +export type ChargesSortBy = Static; export const ChargesSortOrder = Type.Union([ Type.Literal("descend"), Type.Literal("ascend"), ]); -export type ChargesSortOrder = Static +export type ChargesSortOrder = Static; diff --git a/apps/mis-web/src/models/job.ts b/apps/mis-web/src/models/job.ts index db7d97e46b..ec53f70ac5 100644 --- a/apps/mis-web/src/models/job.ts +++ b/apps/mis-web/src/models/job.ts @@ -65,7 +65,7 @@ export enum AmountStrategy { MAX_CPUSALLOC_MEM = "max-cpusAlloc-mem", MAX_GPU_CPUSALLOC = "max-gpu-cpusAlloc", GPU = "gpu", - CPUS_ALLOC = "cpusAlloc" + CPUS_ALLOC = "cpusAlloc", } // export const AmountStrategyText = "计量方式"; @@ -113,7 +113,7 @@ export const JobSortOrder = Type.Union([ Type.Literal("descend"), Type.Literal("ascend"), ]); -export type JobSortOrder = Static +export type JobSortOrder = Static; export const JobSortBy = Type.Union( [ Type.Literal("idJob"), @@ -128,4 +128,4 @@ export const JobSortBy = Type.Union( Type.Literal("Price"), ], ); -export type JobSortBy = Static +export type JobSortBy = Static; diff --git a/apps/mis-web/src/models/operationLog.ts b/apps/mis-web/src/models/operationLog.ts index ba3947c28d..6c1e82a444 100644 --- a/apps/mis-web/src/models/operationLog.ts +++ b/apps/mis-web/src/models/operationLog.ts @@ -25,7 +25,7 @@ export const OperationResult = { FAIL: 2, } as const; -export type OperationResult = ValueOf +export type OperationResult = ValueOf; export const OperationType: OperationTypeEnum = { login: "login", @@ -118,13 +118,13 @@ export const OperationSortBy = Type.Union( Type.Literal("operatorIp"), Type.Literal("operatorUserId")], ); -export type OperationSortBy = Static +export type OperationSortBy = Static; export const OperationSortOrder = Type.Union([ Type.Literal("descend"), Type.Literal("ascend"), ]); -export type OperationSortOrder = Static +export type OperationSortOrder = Static; @@ -143,7 +143,7 @@ export const getOperationResultTexts = (t: OperationTextsTransType) => { }; -export const getOperationTypeTexts = (t: OperationTextsTransType): { [key in LibOperationType]: string } => { +export const getOperationTypeTexts = (t: OperationTextsTransType): {[key in LibOperationType]: string } => { return { login: t(pTypes("login")), @@ -211,7 +211,7 @@ export const getOperationTypeTexts = (t: OperationTextsTransType): { [key in Lib }; -export const OperationCodeMap: { [key in LibOperationType]: string } = { +export const OperationCodeMap: {[key in LibOperationType]: string } = { login: "000001", logout: "000002", submitJob: "010101", @@ -292,197 +292,198 @@ export const getOperationDetail = ( const logEvent = operationEvent.$case; switch (logEvent) { - case "login": - return t(pDetails("login")); - case "logout": - return t(pDetails("logout")); - case "submitJob": - return t(pDetails("submitJob"), [operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].jobId || "-"]); - case "endJob": - return t(pDetails("endJob"), [operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].jobId || "-"]); - case "addJobTemplate": - return t(pDetails("addJobTemplate"), [operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].jobTemplateId]); - case "deleteJobTemplate": - return t(pDetails("deleteJobTemplate"), [operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].jobTemplateId]); - case "updateJobTemplate": - return t(pDetails("updateJobTemplate"), - [ + case "login": + return t(pDetails("login")); + case "logout": + return t(pDetails("logout")); + case "submitJob": + return t(pDetails("submitJob"), [operationEvent[logEvent].clusterId || "unknown", + operationEvent[logEvent].jobId || "-"]); + case "endJob": + return t(pDetails("endJob"), [operationEvent[logEvent].clusterId || "unknown", + operationEvent[logEvent].jobId || "-"]); + case "addJobTemplate": + return t(pDetails("addJobTemplate"), [operationEvent[logEvent].clusterId || "unknown", + operationEvent[logEvent].jobTemplateId]); + case "deleteJobTemplate": + return t(pDetails("deleteJobTemplate"), [operationEvent[logEvent].clusterId || "unknown", + operationEvent[logEvent].jobTemplateId]); + case "updateJobTemplate": + return t(pDetails("updateJobTemplate"), + [ + operationEvent[logEvent].clusterId || "unknown", + operationEvent[logEvent].jobTemplateId, + operationEvent[logEvent].newJobTemplateId, + ]); + case "shellLogin": + return t(pDetails("shellLogin"), [operationEvent[logEvent].clusterId, operationEvent[logEvent].loginNode]); + case "createDesktop": + return t(pDetails("createDesktop"), [ operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].jobTemplateId, - operationEvent[logEvent].newJobTemplateId, + operationEvent[logEvent].loginNode || "unknown", + operationEvent[logEvent].desktopName, + operationEvent[logEvent].wm, ]); - case "shellLogin": - return t(pDetails("shellLogin"), [operationEvent[logEvent].clusterId, operationEvent[logEvent].loginNode]); - case "createDesktop": - return t(pDetails("createDesktop"), [ - operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].loginNode || "unknown", - operationEvent[logEvent].desktopName, - operationEvent[logEvent].wm, - ]); - case "deleteDesktop": - return t(pDetails("deleteDesktop"), - [ - operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].loginNode, - operationEvent[logEvent].desktopId, - ]); - case "createApp": - return t(pDetails("createApp"), [operationEvent[logEvent].clusterId, operationEvent[logEvent].jobId || "-"]); - case "createFile": - return t(pDetails("createFile"), [operationEvent[logEvent].path]); - case "deleteFile": - return t(pDetails("deleteFile"), [operationEvent[logEvent].path]); - case "uploadFile": - return t(pDetails("uploadFile"), [operationEvent[logEvent].path]); - case "createDirectory": - return t(pDetails("createDirectory"), [operationEvent[logEvent].path]); - case "deleteDirectory": - return t(pDetails("deleteDirectory"), [operationEvent[logEvent].path]); - case "moveFileItem": - return t(pDetails("moveFileItem"), [operationEvent[logEvent].fromPath, operationEvent[logEvent].toPath]); - case "copyFileItem": - return t(pDetails("copyFileItem"), [operationEvent[logEvent].fromPath, operationEvent[logEvent].toPath]); - case "setJobTimeLimit": - return t(pDetails("setJobTimeLimit"), - [operationEvent[logEvent].clusterId || "unknown", - operationEvent[logEvent].jobId, Math.abs(operationEvent[logEvent].limitMinutes)]); - case "createUser": - return t(pDetails("createUser"), [operationEvent[logEvent].userId]); - case "addUserToAccount": - return t(pDetails("addUserToAccount"), - [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); - case "removeUserFromAccount": - return t(pDetails("removeUserFromAccount"), - [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); - case "setAccountAdmin": - return t(pDetails("setAccountAdmin"), - [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); - case "unsetAccountAdmin": - return t(pDetails("unsetAccountAdmin"), - [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); - case "blockUser": - return t(pDetails("blockUser"), [operationEvent[logEvent].accountName, operationEvent[logEvent].userId]); - case "unblockUser": - return t(pDetails("unblockUser"), [operationEvent[logEvent].accountName, operationEvent[logEvent].userId]); - case "accountSetChargeLimit": - return t(pDetails("accountSetChargeLimit"), - [operationEvent[logEvent].accountName, - operationEvent[logEvent].userId, - nullableMoneyToString(operationEvent[logEvent].limit)]); - case "accountUnsetChargeLimit": - return t(pDetails("accountUnsetChargeLimit"), - [operationEvent[logEvent].accountName, operationEvent[logEvent].userId]); - case "setTenantBilling": - return t(pDetails("setTenantBilling"), - [operationEvent[logEvent].tenantName, - operationEvent[logEvent].path, - nullableMoneyToString(operationEvent[logEvent].price)]); - case "setTenantAdmin": - return t(pDetails("setTenantAdmin"), [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); - case "unsetTenantAdmin": - return t(pDetails("unsetTenantAdmin"), - [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); - case "setTenantFinance": - return t(pDetails("setTenantFinance"), - [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); - case "unsetTenantFinance": - return t(pDetails("unsetTenantFinance"), - [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); - case "tenantChangePassword": - return t(pDetails("tenantChangePassword"), [operationEvent[logEvent].userId]); - case "createAccount": - return t(pDetails("createAccount"), - [operationEvent[logEvent].accountName, operationEvent[logEvent].accountOwner]); - case "addAccountToWhitelist": - return t(pDetails("addAccountToWhitelist"), - [operationEvent[logEvent].accountName, operationEvent[logEvent].tenantName]); - case "removeAccountFromWhitelist": - return t(pDetails("removeAccountFromWhitelist"), - [operationEvent[logEvent].accountName, operationEvent[logEvent].tenantName]); - case "accountPay": - return t(pDetails("accountPay"), - [operationEvent[logEvent].accountName, nullableMoneyToString(operationEvent[logEvent].amount)]); - case "blockAccount": - return t(pDetails("blockAccount"), - [operationEvent[logEvent].tenantName, operationEvent[logEvent].accountName]); - case "unblockAccount": - return t(pDetails("unblockAccount"), - [operationEvent[logEvent].tenantName, operationEvent[logEvent].accountName]); - case "importUsers": - return `${t(pDetails("importUsers1"), - [operationEvent[logEvent].tenantName])}${operationEvent[logEvent].importAccounts.map( - (account: { accountName: string; userIds: string[]; }) => - (tArgs(pDetails("importUsers2"), [account.accountName, account.userIds.join("、")])), - ).join(", ")}`; - case "setPlatformAdmin": - return t(pDetails("setPlatformAdmin"), [operationEvent[logEvent].userId]); - case "unsetPlatformAdmin": - return t(pDetails("unsetPlatformAdmin"), [operationEvent[logEvent].userId]); - case "setPlatformFinance": - return t(pDetails("setPlatformFinance"), [operationEvent[logEvent].userId]); - case "unsetPlatformFinance": - return t(pDetails("unsetPlatformFinance"), [operationEvent[logEvent].userId]); - case "platformChangePassword": - return t(pDetails("platformChangePassword"), [operationEvent[logEvent].userId]); - case "createTenant": - return t(pDetails("createTenant"), - [operationEvent[logEvent].tenantName, operationEvent[logEvent].tenantAdmin]); - case "tenantPay": - return t(pDetails("tenantPay"), - [operationEvent[logEvent].tenantName, nullableMoneyToString(operationEvent[logEvent].amount)]); - case "setPlatformBilling": - return t(pDetails("setPlatformBilling"), - [operationEvent[logEvent].path, nullableMoneyToString(operationEvent[logEvent].price)]); - case "submitFileItemAsJob": - return t(pDetails("submitFileItemAsJob"), [operationEvent[logEvent].clusterId, operationEvent[logEvent].path]); - case "exportUser": - return operationEvent[logEvent].tenantName - ? t(pDetails("tenantExportUser"), [operationEvent[logEvent].tenantName]) - : t(pDetails("adminExportUser")); - case "exportAccount": - return operationEvent[logEvent].tenantName - ? t(pDetails("tenantExportAccount"), [operationEvent[logEvent].tenantName]) - : t(pDetails("adminExportUser")); - case "exportChargeRecord": - return getExportChargeRecordDetail(operationEvent[logEvent], t); - case "exportPayRecord": - return getExportPayRecordDetail(operationEvent[logEvent], t); - case "exportOperationLog": - return getExportOperationLogDetail(operationEvent[logEvent], t); - case "setAccountBlockThreshold": - return operationEvent[logEvent].thresholdAmount - ? t(pDetails("setAccountBlockThreshold"), - [operationEvent[logEvent].accountName, moneyToString(operationEvent[logEvent].thresholdAmount!) ]) - : t(pDetails("unsetAccountBlockThreshold"), [operationEvent[logEvent].accountName]); - case "setAccountDefaultBlockThreshold": - return t(pDetails("setAccountDefaultBlockThreshold"), - [operationEvent[logEvent].tenantName, - nullableMoneyToString(operationEvent[logEvent].thresholdAmount)]); - case "userChangeTenant": - return t(pDetails("userChangeTenant"), - [operationEvent[logEvent].userId, - operationEvent[logEvent].previousTenantName, - operationEvent[logEvent].newTenantName]); - case "activateCluster": - return t(pDetails("activateCluster"), - [operationEvent[logEvent].userId, - operationEvent[logEvent].clusterId]); - case "deactivateCluster": - return t(pDetails("deactivateCluster"), - [operationEvent[logEvent].userId, - operationEvent[logEvent].clusterId]); - case "customEvent": - const c = operationEvent[logEvent]?.content; - return getI18nCurrentText(c, languageId); - default: - return "-"; + case "deleteDesktop": + return t(pDetails("deleteDesktop"), + [ + operationEvent[logEvent].clusterId || "unknown", + operationEvent[logEvent].loginNode, + operationEvent[logEvent].desktopId, + ]); + case "createApp": + return t(pDetails("createApp"), [operationEvent[logEvent].clusterId, operationEvent[logEvent].jobId || "-"]); + case "createFile": + return t(pDetails("createFile"), [operationEvent[logEvent].path]); + case "deleteFile": + return t(pDetails("deleteFile"), [operationEvent[logEvent].path]); + case "uploadFile": + return t(pDetails("uploadFile"), [operationEvent[logEvent].path]); + case "createDirectory": + return t(pDetails("createDirectory"), [operationEvent[logEvent].path]); + case "deleteDirectory": + return t(pDetails("deleteDirectory"), [operationEvent[logEvent].path]); + case "moveFileItem": + return t(pDetails("moveFileItem"), [operationEvent[logEvent].fromPath, operationEvent[logEvent].toPath]); + case "copyFileItem": + return t(pDetails("copyFileItem"), [operationEvent[logEvent].fromPath, operationEvent[logEvent].toPath]); + case "setJobTimeLimit": + return t(pDetails("setJobTimeLimit"), + [operationEvent[logEvent].clusterId || "unknown", + operationEvent[logEvent].jobId, Math.abs(operationEvent[logEvent].limitMinutes)]); + case "createUser": + return t(pDetails("createUser"), [operationEvent[logEvent].userId]); + case "addUserToAccount": + return t(pDetails("addUserToAccount"), + [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); + case "removeUserFromAccount": + return t(pDetails("removeUserFromAccount"), + [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); + case "setAccountAdmin": + return t(pDetails("setAccountAdmin"), + [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); + case "unsetAccountAdmin": + return t(pDetails("unsetAccountAdmin"), + [operationEvent[logEvent].userId, operationEvent[logEvent].accountName]); + case "blockUser": + return t(pDetails("blockUser"), [operationEvent[logEvent].accountName, operationEvent[logEvent].userId]); + case "unblockUser": + return t(pDetails("unblockUser"), [operationEvent[logEvent].accountName, operationEvent[logEvent].userId]); + case "accountSetChargeLimit": + return t(pDetails("accountSetChargeLimit"), + [operationEvent[logEvent].accountName, + operationEvent[logEvent].userId, + nullableMoneyToString(operationEvent[logEvent].limit)]); + case "accountUnsetChargeLimit": + return t(pDetails("accountUnsetChargeLimit"), + [operationEvent[logEvent].accountName, operationEvent[logEvent].userId]); + case "setTenantBilling": + return t(pDetails("setTenantBilling"), + [operationEvent[logEvent].tenantName, + operationEvent[logEvent].path, + nullableMoneyToString(operationEvent[logEvent].price)]); + case "setTenantAdmin": + return t(pDetails("setTenantAdmin"), [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); + case "unsetTenantAdmin": + return t(pDetails("unsetTenantAdmin"), + [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); + case "setTenantFinance": + return t(pDetails("setTenantFinance"), + [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); + case "unsetTenantFinance": + return t(pDetails("unsetTenantFinance"), + [operationEvent[logEvent].userId, operationEvent[logEvent].tenantName]); + case "tenantChangePassword": + return t(pDetails("tenantChangePassword"), [operationEvent[logEvent].userId]); + case "createAccount": + return t(pDetails("createAccount"), + [operationEvent[logEvent].accountName, operationEvent[logEvent].accountOwner]); + case "addAccountToWhitelist": + return t(pDetails("addAccountToWhitelist"), + [operationEvent[logEvent].accountName, operationEvent[logEvent].tenantName]); + case "removeAccountFromWhitelist": + return t(pDetails("removeAccountFromWhitelist"), + [operationEvent[logEvent].accountName, operationEvent[logEvent].tenantName]); + case "accountPay": + return t(pDetails("accountPay"), + [operationEvent[logEvent].accountName, nullableMoneyToString(operationEvent[logEvent].amount)]); + case "blockAccount": + return t(pDetails("blockAccount"), + [operationEvent[logEvent].tenantName, operationEvent[logEvent].accountName]); + case "unblockAccount": + return t(pDetails("unblockAccount"), + [operationEvent[logEvent].tenantName, operationEvent[logEvent].accountName]); + case "importUsers": + return `${t(pDetails("importUsers1"), + [operationEvent[logEvent].tenantName])}${operationEvent[logEvent].importAccounts.map( + (account: { accountName: string; userIds: string[]; }) => + (tArgs(pDetails("importUsers2"), [account.accountName, account.userIds.join("、")])), + ).join(", ")}`; + case "setPlatformAdmin": + return t(pDetails("setPlatformAdmin"), [operationEvent[logEvent].userId]); + case "unsetPlatformAdmin": + return t(pDetails("unsetPlatformAdmin"), [operationEvent[logEvent].userId]); + case "setPlatformFinance": + return t(pDetails("setPlatformFinance"), [operationEvent[logEvent].userId]); + case "unsetPlatformFinance": + return t(pDetails("unsetPlatformFinance"), [operationEvent[logEvent].userId]); + case "platformChangePassword": + return t(pDetails("platformChangePassword"), [operationEvent[logEvent].userId]); + case "createTenant": + return t(pDetails("createTenant"), + [operationEvent[logEvent].tenantName, operationEvent[logEvent].tenantAdmin]); + case "tenantPay": + return t(pDetails("tenantPay"), + [operationEvent[logEvent].tenantName, nullableMoneyToString(operationEvent[logEvent].amount)]); + case "setPlatformBilling": + return t(pDetails("setPlatformBilling"), + [operationEvent[logEvent].path, nullableMoneyToString(operationEvent[logEvent].price)]); + case "submitFileItemAsJob": + return t(pDetails("submitFileItemAsJob"), [operationEvent[logEvent].clusterId, operationEvent[logEvent].path]); + case "exportUser": + return operationEvent[logEvent].tenantName + ? t(pDetails("tenantExportUser"), [operationEvent[logEvent].tenantName]) + : t(pDetails("adminExportUser")); + case "exportAccount": + return operationEvent[logEvent].tenantName + ? t(pDetails("tenantExportAccount"), [operationEvent[logEvent].tenantName]) + : t(pDetails("adminExportUser")); + case "exportChargeRecord": + return getExportChargeRecordDetail(operationEvent[logEvent], t); + case "exportPayRecord": + return getExportPayRecordDetail(operationEvent[logEvent], t); + case "exportOperationLog": + return getExportOperationLogDetail(operationEvent[logEvent], t); + case "setAccountBlockThreshold": + return operationEvent[logEvent].thresholdAmount + ? t(pDetails("setAccountBlockThreshold"), + [operationEvent[logEvent].accountName, moneyToString(operationEvent[logEvent].thresholdAmount) ]) + : t(pDetails("unsetAccountBlockThreshold"), [operationEvent[logEvent].accountName]); + case "setAccountDefaultBlockThreshold": + return t(pDetails("setAccountDefaultBlockThreshold"), + [operationEvent[logEvent].tenantName, + nullableMoneyToString(operationEvent[logEvent].thresholdAmount)]); + case "userChangeTenant": + return t(pDetails("userChangeTenant"), + [operationEvent[logEvent].userId, + operationEvent[logEvent].previousTenantName, + operationEvent[logEvent].newTenantName]); + case "activateCluster": + return t(pDetails("activateCluster"), + [operationEvent[logEvent].userId, + operationEvent[logEvent].clusterId]); + case "deactivateCluster": + return t(pDetails("deactivateCluster"), + [operationEvent[logEvent].userId, + operationEvent[logEvent].clusterId]); + case "customEvent": { + const c = operationEvent[logEvent]?.content; + return getI18nCurrentText(c, languageId); + } + default: + return "-"; } - } catch (e) { + } catch { return "-"; } }; @@ -494,47 +495,50 @@ const getExportChargeRecordDetail = (exportChargeRecord: ExportChargeRecord, t: } const exportChargeCase = exportChargeTarget.$case; switch (exportChargeCase) { - case "accountOfTenant": - const accountOfTenant = exportChargeTarget[exportChargeCase]; - return t(pDetails("exportAccountChargeRecordOfTenant"), - [accountOfTenant.tenantName, accountOfTenant.accountName]); - case "accountsOfTenant": - { - const accountsOfTenant = exportChargeTarget[exportChargeCase]; - const { accountNames } = accountsOfTenant; - if (accountNames.length === 0) { - return t(pDetails("exportAllAccountsChargeRecordOfTenant"), - [accountsOfTenant.tenantName]); - } else if (accountNames.length === 1) { + case "accountOfTenant": { + const accountOfTenant = exportChargeTarget[exportChargeCase]; return t(pDetails("exportAccountChargeRecordOfTenant"), - [accountsOfTenant.tenantName, accountNames[0]]); - } else { - const accountStr = accountNames.join("、"); - const resultStr = accountStr.length > 25 ? accountStr.slice(0, 25) + "…" : accountStr; - return t(pDetails("exportAccountsChargeRecordOfTenant"), - [accountsOfTenant.tenantName, resultStr]); + [accountOfTenant.tenantName, accountOfTenant.accountName]); } - } - case "accountsOfAllTenants": - const accountsOfAllTenants = exportChargeTarget[exportChargeCase]; - const { accountNames } = accountsOfAllTenants; - if (accountNames.length === 0) { - return t(pDetails("exportAllAccountsChargeRecordOfAdmin")); - } else if (accountNames.length === 1) { - return t(pDetails("exportAccountChargeRecordOfAdmin"), accountNames); - } else { - const accountStr = accountNames.join("、"); - const resultStr = accountStr.length > 25 ? accountStr.slice(0, 25) + "…" : accountStr; - return t(pDetails("exportAccountsChargeRecordOfAdmin"), - [resultStr]); + case "accountsOfTenant": + { + const accountsOfTenant = exportChargeTarget[exportChargeCase]; + const { accountNames } = accountsOfTenant; + if (accountNames.length === 0) { + return t(pDetails("exportAllAccountsChargeRecordOfTenant"), + [accountsOfTenant.tenantName]); + } else if (accountNames.length === 1) { + return t(pDetails("exportAccountChargeRecordOfTenant"), + [accountsOfTenant.tenantName, accountNames[0]]); + } else { + const accountStr = accountNames.join("、"); + const resultStr = accountStr.length > 25 ? accountStr.slice(0, 25) + "…" : accountStr; + return t(pDetails("exportAccountsChargeRecordOfTenant"), + [accountsOfTenant.tenantName, resultStr]); + } } - case "tenant": - const tenant = exportChargeTarget[exportChargeCase]; - return t(pDetails("exportTenantChargeRecord"), [tenant.tenantName]); - case "allTenants": - return t(pDetails("exportTenantsChargeRecordOfAdmin")); - default: - return "-"; + case "accountsOfAllTenants": { + const accountsOfAllTenants = exportChargeTarget[exportChargeCase]; + const { accountNames } = accountsOfAllTenants; + if (accountNames.length === 0) { + return t(pDetails("exportAllAccountsChargeRecordOfAdmin")); + } else if (accountNames.length === 1) { + return t(pDetails("exportAccountChargeRecordOfAdmin"), accountNames); + } else { + const accountStr = accountNames.join("、"); + const resultStr = accountStr.length > 25 ? accountStr.slice(0, 25) + "…" : accountStr; + return t(pDetails("exportAccountsChargeRecordOfAdmin"), + [resultStr]); + } + } + case "tenant": { + const tenant = exportChargeTarget[exportChargeCase]; + return t(pDetails("exportTenantChargeRecord"), [tenant.tenantName]); + } + case "allTenants": + return t(pDetails("exportTenantsChargeRecordOfAdmin")); + default: + return "-"; } }; @@ -546,28 +550,30 @@ const getExportPayRecordDetail = (exportPayRecord: ExportPayRecord, t: Operation } const exportPayCase = exportPayTarget.$case; switch (exportPayCase) { - case "accountsOfTenant": - const accountsOfTenant = exportPayTarget[exportPayCase]; - const { accountNames } = accountsOfTenant; - if (accountNames.length === 0) { - return t(pDetails("exportAllAccountsPayRecordOfTenant"), - [accountsOfTenant.tenantName]); - } else if (accountNames.length === 1) { - return t(pDetails("exportAccountPayRecordOfTenant"), - [accountsOfTenant.tenantName, accountNames[0]]); - } else { - const accountStr = accountNames.join("、"); - const resultStr = accountStr.length > 25 ? accountStr.slice(0, 25) + "…" : accountStr; - return t(pDetails("exportAccountsPayRecordOfTenant"), - [accountsOfTenant.tenantName, resultStr]); + case "accountsOfTenant": { + const accountsOfTenant = exportPayTarget[exportPayCase]; + const { accountNames } = accountsOfTenant; + if (accountNames.length === 0) { + return t(pDetails("exportAllAccountsPayRecordOfTenant"), + [accountsOfTenant.tenantName]); + } else if (accountNames.length === 1) { + return t(pDetails("exportAccountPayRecordOfTenant"), + [accountsOfTenant.tenantName, accountNames[0]]); + } else { + const accountStr = accountNames.join("、"); + const resultStr = accountStr.length > 25 ? accountStr.slice(0, 25) + "…" : accountStr; + return t(pDetails("exportAccountsPayRecordOfTenant"), + [accountsOfTenant.tenantName, resultStr]); + } } - case "tenant": - const tenant = exportPayTarget[exportPayCase]; - return t(pDetails("exportTenantPayRecord"), [tenant.tenantName]); - case "allTenants": - return t(pDetails("exportTenantsPayRecordOfAdmin")); - default: - return "-"; + case "tenant": { + const tenant = exportPayTarget[exportPayCase]; + return t(pDetails("exportTenantPayRecord"), [tenant.tenantName]); + } + case "allTenants": + return t(pDetails("exportTenantsPayRecordOfAdmin")); + default: + return "-"; } }; @@ -578,22 +584,25 @@ const getExportOperationLogDetail = (exportOperationLog: ExportOperationLog, t: } const sourceCase = exportOperationLogSource.$case; switch (sourceCase) { - case "user": - const user = exportOperationLogSource.user; - return t(pDetails("exportOperationLogFromUser"), - [user.userId]); - case "account": - const account = exportOperationLogSource.account; - return t(pDetails("exportOperationLogFromAccount"), - [account.accountName]); - case "tenant": - const tenant = exportOperationLogSource.tenant; - return t(pDetails("exportOperationLogFromTenant"), - [tenant.tenantName]); - case "admin": - return t(pDetails("exportOperationLogFromAdmin")); - default: - return "-"; + case "user": { + const user = exportOperationLogSource.user; + return t(pDetails("exportOperationLogFromUser"), + [user.userId]); + } + case "account": { + const account = exportOperationLogSource.account; + return t(pDetails("exportOperationLogFromAccount"), + [account.accountName]); + } + case "tenant": { + const tenant = exportOperationLogSource.tenant; + return t(pDetails("exportOperationLogFromTenant"), + [tenant.tenantName]); + } + case "admin": + return t(pDetails("exportOperationLogFromAdmin")); + default: + return "-"; } }; diff --git a/apps/mis-web/src/pageComponents/admin/AllAlarmLogsTable.tsx b/apps/mis-web/src/pageComponents/admin/AllAlarmLogsTable.tsx index d84ac040c6..ed5961fda6 100644 --- a/apps/mis-web/src/pageComponents/admin/AllAlarmLogsTable.tsx +++ b/apps/mis-web/src/pageComponents/admin/AllAlarmLogsTable.tsx @@ -14,7 +14,7 @@ import { Static } from "@sinclair/typebox"; import { Table, Tag } from "antd"; import dayjs from "dayjs"; import { prefix, useI18nTranslateToString } from "src/i18n"; -import { GetAlarmLogsSchema } from "src/pages/api/admin/monitor/getAlarmLogs"; +import { type GetAlarmLogsSchema } from "src/pages/api/admin/monitor/getAlarmLogs"; interface Pagination { current: number; @@ -73,7 +73,7 @@ export const AllAlarmLogsTable: React.FC = ({ data, isLoading, pagination return (current - 1) * (pageSize || 0) + index + 1; }} /> - dataIndex="fingerprint" title={t(p("fingerPrint"))} /> + dataIndex="status" title={t(p("status"))} @@ -84,7 +84,7 @@ export const AllAlarmLogsTable: React.FC = ({ data, isLoading, pagination title={t(p("alarmLevel"))} render={(s: string) => severityTexts[s]} /> - dataIndex="description" title={t(p("description"))} /> + dataIndex="startsAt" title={t(p("firingTime"))} diff --git a/apps/mis-web/src/pageComponents/admin/AllTenantsTable.tsx b/apps/mis-web/src/pageComponents/admin/AllTenantsTable.tsx index 14f6e894dd..5d27ed59d4 100644 --- a/apps/mis-web/src/pageComponents/admin/AllTenantsTable.tsx +++ b/apps/mis-web/src/pageComponents/admin/AllTenantsTable.tsx @@ -21,7 +21,7 @@ import React, { useCallback } from "react"; import { useAsync } from "react-async"; import { api } from "src/apis"; import { prefix, useI18nTranslateToString } from "src/i18n"; -import { GetAllTenantsSchema } from "src/pages/api/admin/getAllTenants"; +import { type GetAllTenantsSchema } from "src/pages/api/admin/getAllTenants"; import { moneyToString } from "src/utils/money"; interface Props { diff --git a/apps/mis-web/src/pageComponents/admin/AllUsersTable.tsx b/apps/mis-web/src/pageComponents/admin/AllUsersTable.tsx index 2de4f245e7..f4a1cdf475 100644 --- a/apps/mis-web/src/pageComponents/admin/AllUsersTable.tsx +++ b/apps/mis-web/src/pageComponents/admin/AllUsersTable.tsx @@ -26,7 +26,7 @@ import { Encoding } from "src/models/exportFile"; import { PlatformRole, SortDirectionType, UsersSortFieldType } from "src/models/User"; import { ExportFileModaLButton } from "src/pageComponents/common/exportFileModal"; import { MAX_EXPORT_COUNT, urlToExport } from "src/pageComponents/file/apis"; -import { GetAllUsersSchema } from "src/pages/api/admin/getAllUsers"; +import { type GetAllUsersSchema } from "src/pages/api/admin/getAllUsers"; import { User } from "src/stores/UserStore"; import { getRuntimeI18nConfigText } from "src/utils/config"; @@ -283,7 +283,7 @@ const UserInfoTable: React.FC = ({ sortDirections={["ascend", "descend"]} sortOrder={sortInfo.sortField === "name" ? sortInfo.sortOrder : null} /> - dataIndex="tenantName" ellipsis title={t(p("tenant"))} /> + dataIndex="availableAccounts" width="25%" diff --git a/apps/mis-web/src/pageComponents/admin/ChangeTenantModal.tsx b/apps/mis-web/src/pageComponents/admin/ChangeTenantModal.tsx index c218ef5419..60853f7471 100644 --- a/apps/mis-web/src/pageComponents/admin/ChangeTenantModal.tsx +++ b/apps/mis-web/src/pageComponents/admin/ChangeTenantModal.tsx @@ -17,12 +17,12 @@ import { ModalLink } from "src/components/ModalLink"; import { prefix, useI18nTranslateToString } from "src/i18n"; interface Props { - tenantName: string; - name: String - userId: string; - open: boolean; - onClose: () => void; - reload: () => void; + tenantName: string; + name: string + userId: string; + open: boolean; + onClose: () => void; + reload: () => void; } interface FormProps { @@ -49,20 +49,20 @@ const ChangePasswordModal: React.FC = ({ tenantName, name, userId, onClos } }) .httpError(404, (e) => { switch (e.code) { - case "USER_NOT_FOUND": - message.error(t(p("userNotFound"))); - break; - case "TENANT_NOT_FOUND": - message.error(t(p("tenantNotFound"))); - break; - case "USER_STILL_MAINTAINS_ACCOUNT_RELATIONSHIP": - message.error(t(p("userStillMaintainsAccountRelationship"))); - break; - case "USER_ALREADY_EXIST_IN_THIS_TENANT": - message.error(t(p("userAlreadyExistInThisTenant"))); - break; - default: - message.error(t(pCommon("changeFail"))); + case "USER_NOT_FOUND": + message.error(t(p("userNotFound"))); + break; + case "TENANT_NOT_FOUND": + message.error(t(p("tenantNotFound"))); + break; + case "USER_STILL_MAINTAINS_ACCOUNT_RELATIONSHIP": + message.error(t(p("userStillMaintainsAccountRelationship"))); + break; + case "USER_ALREADY_EXIST_IN_THIS_TENANT": + message.error(t(p("userAlreadyExistInThisTenant"))); + break; + default: + message.error(t(pCommon("changeFail"))); } }) .then(() => { message.success(t(pCommon("changeSuccess"))); diff --git a/apps/mis-web/src/pageComponents/admin/DataBarChart.tsx b/apps/mis-web/src/pageComponents/admin/DataBarChart.tsx index e2fc99a131..a0415f7670 100644 --- a/apps/mis-web/src/pageComponents/admin/DataBarChart.tsx +++ b/apps/mis-web/src/pageComponents/admin/DataBarChart.tsx @@ -20,7 +20,7 @@ import { styled } from "styled-components"; interface Props { isLoading: boolean title: string - data: {x: string, y: string | number}[] + data: { x: string, y: string | number }[] xLabel?: string toolTipFormatter?: Formatter } diff --git a/apps/mis-web/src/pageComponents/admin/DataLineChart.tsx b/apps/mis-web/src/pageComponents/admin/DataLineChart.tsx index 6099d55a80..01e1310ee1 100644 --- a/apps/mis-web/src/pageComponents/admin/DataLineChart.tsx +++ b/apps/mis-web/src/pageComponents/admin/DataLineChart.tsx @@ -20,7 +20,7 @@ import { styled } from "styled-components"; interface Props { isLoading: boolean title: string - data: {x: string, y: string | number}[] + data: { x: string, y: string | number }[] lineType?: CurveType toolTipFormatter?: Formatter } diff --git a/apps/mis-web/src/pageComponents/admin/ImportUsersTable.tsx b/apps/mis-web/src/pageComponents/admin/ImportUsersTable.tsx index a74ce204d5..d8e9c65db5 100644 --- a/apps/mis-web/src/pageComponents/admin/ImportUsersTable.tsx +++ b/apps/mis-web/src/pageComponents/admin/ImportUsersTable.tsx @@ -52,7 +52,7 @@ export const ImportUsersTable: React.FC = () => { return ; } - const [form] = Form.useForm<{ whitelist: boolean}>(); + const [form] = Form.useForm<{ whitelist: boolean }>(); const [loading, setLoading] = useState(false); @@ -177,7 +177,7 @@ export const ImportUsersTable: React.FC = () => { rowKey="accountName" bordered > - dataIndex="accountName" title={t(pCommon("accountName"))} /> + dataIndex="owner" title={t(pCommon("owner"))} @@ -234,7 +234,7 @@ export const ImportUsersTable: React.FC = () => { - dataIndex="userId" title={t(pCommon("userId"))} /> +
diff --git a/apps/mis-web/src/pageComponents/common/PaymentTable.tsx b/apps/mis-web/src/pageComponents/common/PaymentTable.tsx index 97704ae64f..adf9b17a1b 100644 --- a/apps/mis-web/src/pageComponents/common/PaymentTable.tsx +++ b/apps/mis-web/src/pageComponents/common/PaymentTable.tsx @@ -244,7 +244,7 @@ export const PaymentTable: React.FC = ({ accountNames, searchType }) => { } + dataSource={data?.results as TableProps[]} loading={isLoading} pagination={{ showSizeChanger: true, diff --git a/apps/mis-web/src/pageComponents/file/apis.ts b/apps/mis-web/src/pageComponents/file/apis.ts index f2a60ea3d2..ea25deb6d9 100644 --- a/apps/mis-web/src/pageComponents/file/apis.ts +++ b/apps/mis-web/src/pageComponents/file/apis.ts @@ -24,12 +24,12 @@ export const urlToExport = ({ query, encoding, }: { - exportApi: string - columns: string[], - count: number, - query: {[key: string]: string | number | boolean | string[] | undefined} - encoding: Encoding - }, + exportApi: string + columns: string[], + count: number, + query: Record + encoding: Encoding +}, ) => { const params = new URLSearchParams(); columns.forEach((column) => { diff --git a/apps/mis-web/src/pageComponents/finance/AccountMultiSelector.tsx b/apps/mis-web/src/pageComponents/finance/AccountMultiSelector.tsx index 36ecd80b7e..65bd780d5e 100644 --- a/apps/mis-web/src/pageComponents/finance/AccountMultiSelector.tsx +++ b/apps/mis-web/src/pageComponents/finance/AccountMultiSelector.tsx @@ -20,7 +20,7 @@ import { prefix, useI18nTranslateToString } from "src/i18n"; import type { AdminAccountInfo } from "src/pages/api/tenant/getAccounts"; import { UserStore } from "src/stores/UserStore"; -type Props = { +interface Props { value: string[]; onChange?: (value: string[]) => void; placeholder?: string; @@ -40,7 +40,7 @@ type Props = { * 如果为真,则从所有租户下获取账户 */ fromAllTenants?: boolean; -} +}; const p = prefix("pageComp.finance.AccountSelector."); diff --git a/apps/mis-web/src/pageComponents/finance/AccountSelector.tsx b/apps/mis-web/src/pageComponents/finance/AccountSelector.tsx index 48f6135889..14b819aea3 100644 --- a/apps/mis-web/src/pageComponents/finance/AccountSelector.tsx +++ b/apps/mis-web/src/pageComponents/finance/AccountSelector.tsx @@ -20,7 +20,7 @@ import { prefix, useI18nTranslateToString } from "src/i18n"; import type { AdminAccountInfo } from "src/pages/api/tenant/getAccounts"; import { UserStore } from "src/stores/UserStore"; -type Props = { +interface Props { value?: string; onChange?: (value: string) => void; placeholder?: string; @@ -40,7 +40,7 @@ type Props = { * 如果为真,则从所有租户下获取账户 */ fromAllTenants?: boolean; -} +}; const p = prefix("pageComp.finance.AccountSelector."); diff --git a/apps/mis-web/src/pageComponents/finance/ChargeTable.tsx b/apps/mis-web/src/pageComponents/finance/ChargeTable.tsx index b70444d0ce..35aa164eef 100644 --- a/apps/mis-web/src/pageComponents/finance/ChargeTable.tsx +++ b/apps/mis-web/src/pageComponents/finance/ChargeTable.tsx @@ -305,12 +305,12 @@ export const ChargeTable: React.FC = ({ > { showAccountName && ( - dataIndex="accountName" title={t(pCommon("account"))} /> + ) } { showTenantName && ( - dataIndex="tenantName" title={t("common.tenant")} /> + ) } diff --git a/apps/mis-web/src/pageComponents/init/InitAdminForm.tsx b/apps/mis-web/src/pageComponents/init/InitAdminForm.tsx index c5fc4cfb6d..9553b6aa03 100644 --- a/apps/mis-web/src/pageComponents/init/InitAdminForm.tsx +++ b/apps/mis-web/src/pageComponents/init/InitAdminForm.tsx @@ -96,13 +96,16 @@ export const InitAdminForm: React.FC = () => { }); }) .then((createdInAuth) => { - !createdInAuth.createdInAuth ? + if (createdInAuth.createdInAuth) { + message.success(t(p("addFinish"))); + } else { modal.info({ title: t(p("addSuccess")), content: t(p("addDb")), okText: t(pCommon("ok")), - }) - : message.success(t(p("addFinish"))); }) + }); + } + }) .catch(() => { modal.error({ title: t(p("addFail")), diff --git a/apps/mis-web/src/pageComponents/init/InitLayout.tsx b/apps/mis-web/src/pageComponents/init/InitLayout.tsx index b5b87e322c..1d675a614d 100644 --- a/apps/mis-web/src/pageComponents/init/InitLayout.tsx +++ b/apps/mis-web/src/pageComponents/init/InitLayout.tsx @@ -20,9 +20,9 @@ import { prefix, useI18nTranslateToString } from "src/i18n"; import { Head } from "src/utils/head"; import { styled } from "styled-components"; -type DrawerProps = { +interface DrawerProps { children: React.ReactNode; -} +}; const Title = styled(Centered)` position: relative; diff --git a/apps/mis-web/src/pageComponents/init/InitUsersAndAccountsTable.tsx b/apps/mis-web/src/pageComponents/init/InitUsersAndAccountsTable.tsx index af23783da4..77efe8a1f7 100644 --- a/apps/mis-web/src/pageComponents/init/InitUsersAndAccountsTable.tsx +++ b/apps/mis-web/src/pageComponents/init/InitUsersAndAccountsTable.tsx @@ -24,7 +24,7 @@ import { PlatformRoleSelector } from "src/components/PlatformRoleSelector"; import { TenantRoleSelector } from "src/components/TenantRoleSelector"; import { prefix, useI18nTranslateToString } from "src/i18n"; import { UserRole } from "src/models/User"; -import { InitGetAccountsSchema } from "src/pages/api/init/getAccounts"; +import { type InitGetAccountsSchema } from "src/pages/api/init/getAccounts"; interface UserTableFilterForm { idOrName: string | undefined; @@ -91,8 +91,8 @@ const UserTable: React.FC> = ({ data, loading, reload }) => bordered rowKey="userId" > - dataIndex="userId" title={t(pCommon("userId"))} /> - dataIndex="name" title={t(pCommon("name"))} /> + + dataIndex="platformRoles" title={t(p("platformRole"))} @@ -124,7 +124,7 @@ const UserTable: React.FC> = ({ data, loading, reload }) => }; const AccountTable: - React.FC>> +React.FC>> = ({ data, loading }) => { const t = useI18nTranslateToString(); @@ -141,7 +141,7 @@ const AccountTable: rowKey="accountName" bordered > - dataIndex="accountName" title={t(pCommon("accountName"))} /> + dataIndex="ownerName" title={t(pCommon("owner"))} diff --git a/apps/mis-web/src/pageComponents/job/ChangeJobTimeLimitModal.tsx b/apps/mis-web/src/pageComponents/job/ChangeJobTimeLimitModal.tsx index cbee96f094..86e95b380e 100644 --- a/apps/mis-web/src/pageComponents/job/ChangeJobTimeLimitModal.tsx +++ b/apps/mis-web/src/pageComponents/job/ChangeJobTimeLimitModal.tsx @@ -197,7 +197,7 @@ export const ChangeJobTimeLimitModal: React.FC = ({ open, onClose, data, arrayContainsElement(completionStatus?.current?.failed) ? ( - {completionStatus.current!.failed.map((x) => x.jobId).join(", ")} + {completionStatus.current.failed.map((x) => x.jobId).join(", ")} ) : undefined } diff --git a/apps/mis-web/src/pageComponents/job/EditableJobBillingTable.tsx b/apps/mis-web/src/pageComponents/job/EditableJobBillingTable.tsx index 8a3ad9a528..406766a6e9 100644 --- a/apps/mis-web/src/pageComponents/job/EditableJobBillingTable.tsx +++ b/apps/mis-web/src/pageComponents/job/EditableJobBillingTable.tsx @@ -106,8 +106,8 @@ export const EditableJobBillingTable: React.FC = ({ data, loading, tenant const { publicConfigClusters } = useStore(ClusterInfoStore); - const clusterTotalQosCounts = data && data.length ? - data.reduce((totalQosCounts: { [cluster: string]: number }, item) => { + const clusterTotalQosCounts = data?.length ? + data.reduce((totalQosCounts: Record, item) => { const { cluster } = item; if (!totalQosCounts[cluster]) { totalQosCounts[cluster] = 1; diff --git a/apps/mis-web/src/pageComponents/job/HistoryJobDrawer.tsx b/apps/mis-web/src/pageComponents/job/HistoryJobDrawer.tsx index 7f9fe4678b..9e7f425dfe 100644 --- a/apps/mis-web/src/pageComponents/job/HistoryJobDrawer.tsx +++ b/apps/mis-web/src/pageComponents/job/HistoryJobDrawer.tsx @@ -68,7 +68,7 @@ export const HistoryJobDrawer: React.FC = (props) => { moneyToString, (pr: Props) => pr.showedPrices.includes("tenant")], ] as ( | [string | ((pr: Props) => string), keyof JobInfo, (v: any) => string, (pr: Props) => boolean] -)[]; + )[]; const { item, onClose, open } = props; diff --git a/apps/mis-web/src/pageComponents/job/HistoryJobTable.tsx b/apps/mis-web/src/pageComponents/job/HistoryJobTable.tsx index f8c74089f1..fbb95f92ba 100644 --- a/apps/mis-web/src/pageComponents/job/HistoryJobTable.tsx +++ b/apps/mis-web/src/pageComponents/job/HistoryJobTable.tsx @@ -175,7 +175,7 @@ export const JobTable: React.FC = ({ } placeholder={t("common.selectAccount")} filterOption={(inputValue, option) => - option!.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1 + option!.value.toUpperCase().includes(inputValue.toUpperCase()) } onChange={(value) => { setSelectedAccountName(value || undefined); diff --git a/apps/mis-web/src/pageComponents/job/JobBillingManagementTable.tsx b/apps/mis-web/src/pageComponents/job/JobBillingManagementTable.tsx index b286486554..85f09b4a1d 100644 --- a/apps/mis-web/src/pageComponents/job/JobBillingManagementTable.tsx +++ b/apps/mis-web/src/pageComponents/job/JobBillingManagementTable.tsx @@ -31,8 +31,8 @@ export const JobBillingManagementTable: React.FC = ({ data, loading }) => return (
- title={t(p("path"))} dataIndex={"path"} /> - title={t(p("tenant"))} dataIndex={"tenant"} /> + + title={t(pCommon("createTime"))} dataIndex={"createTime"} diff --git a/apps/mis-web/src/pageComponents/job/ManageJobBillingTable.tsx b/apps/mis-web/src/pageComponents/job/ManageJobBillingTable.tsx index 04c4cd41dc..bad69ab120 100644 --- a/apps/mis-web/src/pageComponents/job/ManageJobBillingTable.tsx +++ b/apps/mis-web/src/pageComponents/job/ManageJobBillingTable.tsx @@ -276,7 +276,7 @@ const EditPriceModal: React.FC ({ label: AmountStrategyDescriptions[x], value: x })), - ...(publicConfig.CUSTOM_AMOUNT_STRATEGIES || [])?.map((i) => ({ label: i.name || i.id, value: i.id })), + ...(publicConfig.CUSTOM_AMOUNT_STRATEGIES || []).map((i) => ({ label: i.name || i.id, value: i.id })), ]} dropdownMatchSelectWidth={false} diff --git a/apps/mis-web/src/pageComponents/job/PlatformOrTenantRadio.tsx b/apps/mis-web/src/pageComponents/job/PlatformOrTenantRadio.tsx index 7f8fefd47b..0761aeee02 100644 --- a/apps/mis-web/src/pageComponents/job/PlatformOrTenantRadio.tsx +++ b/apps/mis-web/src/pageComponents/job/PlatformOrTenantRadio.tsx @@ -16,10 +16,10 @@ import { prefix, useI18nTranslateToString } from "src/i18n"; import { TenantSelector } from "../tenant/TenantSelector"; -type Props = { +interface Props { value?: string | null; // value will be null when selecting platform onChange?: (value: string | null) => void; -} +}; const pCommon = prefix("common."); diff --git a/apps/mis-web/src/pageComponents/job/RunningJobTable.tsx b/apps/mis-web/src/pageComponents/job/RunningJobTable.tsx index 00e78e1a35..d59906576f 100644 --- a/apps/mis-web/src/pageComponents/job/RunningJobTable.tsx +++ b/apps/mis-web/src/pageComponents/job/RunningJobTable.tsx @@ -205,7 +205,7 @@ export const RunningJobQueryTable: React.FC = ({ -type JobInfoTableProps = { +interface JobInfoTableProps { data: RunningJobInfo[] | undefined; isLoading: boolean; showAccount: boolean; @@ -216,7 +216,7 @@ type JobInfoTableProps = { selected: RunningJobInfo[]; setSelected: (d: RunningJobInfo[]) => void; } -}; +} const ChangeJobTimeLimitModalLink = ModalLink(ChangeJobTimeLimitModal); diff --git a/apps/mis-web/src/pageComponents/profile/ChangeEmailModal.tsx b/apps/mis-web/src/pageComponents/profile/ChangeEmailModal.tsx index f096299af5..be7e66d466 100644 --- a/apps/mis-web/src/pageComponents/profile/ChangeEmailModal.tsx +++ b/apps/mis-web/src/pageComponents/profile/ChangeEmailModal.tsx @@ -52,7 +52,7 @@ export const ChangeEmailModal: React.FC = ({ const { newEmail } = await form.validateFields(); setLoading(true); - await api.changeEmail({ body: { userId:userStore.user?.identityId as string, newEmail } }) + await api.changeEmail({ body: { userId: userStore.user!.identityId, newEmail } }) .httpError(404, () => { message.error(t(p("userNotExist"))); }) .httpError(500, () => { message.error(t(p("changeEmailFail"))); }) .httpError(501, () => { message.error(t(p("unavailable"))); }) diff --git a/apps/mis-web/src/pageComponents/tenant/AccountWhitelistTable.tsx b/apps/mis-web/src/pageComponents/tenant/AccountWhitelistTable.tsx index ff8557a7bd..873353099f 100644 --- a/apps/mis-web/src/pageComponents/tenant/AccountWhitelistTable.tsx +++ b/apps/mis-web/src/pageComponents/tenant/AccountWhitelistTable.tsx @@ -184,8 +184,8 @@ export const AccountWhitelistTable: React.FC = ({ title={t(p("expirationTime"))} render={(time: string | undefined) => time ? formatDateTime(time) : "永久有效"} /> - dataIndex="comment" title={t(pCommon("comment"))} /> - dataIndex="operatorId" title={t(p("operatorId"))} /> + + title={t(pCommon("operation"))} render={(_, r) => ( diff --git a/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx b/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx index 986b872aac..a23cae224f 100644 --- a/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx +++ b/apps/mis-web/src/pageComponents/tenant/AddWhitelistedAccountButton.tsx @@ -41,7 +41,7 @@ interface PickExpDateProps { // 过期时间选择组件 const PickExpDate: React.FC = (props) => { - const { id, value = dayjs(), onChange } = props; + const { id, onChange } = props; const t = useI18nTranslateToString(); @@ -70,34 +70,34 @@ const PickExpDate: React.FC = (props) => { let newDate: dayjs.Dayjs | string; switch (selectedOption) { - // 一周 - case "oneWeek": - newDate = dayjs().add(1, "week").endOf("day"); - break; + // 一周 + case "oneWeek": + newDate = dayjs().add(1, "week").endOf("day"); + break; // 一个礼拜 - case "oneMonth": - newDate = dayjs().add(1, "month").endOf("day"); - break; + case "oneMonth": + newDate = dayjs().add(1, "month").endOf("day"); + break; - // 一年 - case "oneYear": - newDate = dayjs().add(1, "year").endOf("day"); - break; + // 一年 + case "oneYear": + newDate = dayjs().add(1, "year").endOf("day"); + break; // 永久生效 - case "permanent": - newDate = dayjs("2099-12-31").endOf("day"); - break; + case "permanent": + newDate = dayjs("2099-12-31").endOf("day"); + break; // 自定义时间 - case "custom": - newDate = expirationTime ?? dayjs().add(1, "day").endOf("day"); - break; + case "custom": + newDate = expirationTime ?? dayjs().add(1, "day").endOf("day"); + break; - default: - newDate = dayjs().add(1, "day").endOf("day"); - break; + default: + newDate = dayjs().add(1, "day").endOf("day"); + break; } // 传递值 onChange?.(newDate); diff --git a/apps/mis-web/src/pageComponents/tenant/AdminJobTable.tsx b/apps/mis-web/src/pageComponents/tenant/AdminJobTable.tsx index defc149d9d..d97c4f4588 100644 --- a/apps/mis-web/src/pageComponents/tenant/AdminJobTable.tsx +++ b/apps/mis-web/src/pageComponents/tenant/AdminJobTable.tsx @@ -271,18 +271,18 @@ const JobInfoTable: React.FC = ({ tableLayout="fixed" scroll={{ x: data?.jobs?.length ? 1800 : true }} > - dataIndex="idJob" width="5.2%" title={t(pCommon("clusterWorkId"))} /> - dataIndex="jobName" ellipsis title={t(pCommon("workName"))} /> - dataIndex="account" ellipsis title={t(pCommon("account"))} /> - dataIndex="user" ellipsis title={t(pCommon("user"))} /> + + + + dataIndex="cluster" ellipsis title={t(pCommon("cluster"))} render={(cluster) => getClusterName(cluster, languageId, publicConfigClusters)} /> - dataIndex="partition" width="6.7%" ellipsis title={t(pCommon("partition"))} /> - dataIndex="qos" width="6.7%" ellipsis title="QOS" /> + + dataIndex="timeSubmit" width="8.9%" diff --git a/apps/mis-web/src/pageComponents/tenant/AdminUserTable.tsx b/apps/mis-web/src/pageComponents/tenant/AdminUserTable.tsx index 04518b39a9..789a2d7bb7 100644 --- a/apps/mis-web/src/pageComponents/tenant/AdminUserTable.tsx +++ b/apps/mis-web/src/pageComponents/tenant/AdminUserTable.tsx @@ -25,7 +25,7 @@ import { Encoding } from "src/models/exportFile"; import { FullUserInfo, TenantRole } from "src/models/User"; import { ExportFileModaLButton } from "src/pageComponents/common/exportFileModal"; import { MAX_EXPORT_COUNT, urlToExport } from "src/pageComponents/file/apis"; -import { GetTenantUsersSchema } from "src/pages/api/admin/getTenantUsers"; +import { type GetTenantUsersSchema } from "src/pages/api/admin/getTenantUsers"; import { User } from "src/stores/UserStore"; import { getRuntimeI18nConfigText } from "src/utils/config"; @@ -85,15 +85,15 @@ export const AdminUserTable: React.FC = ({ const getUsersRoleCount = useCallback((role: FilteredRole): number => { switch (role) { - case "TENANT_ADMIN": - return searchData - ? searchData.filter((user) => user.tenantRoles.includes(TenantRole.TENANT_ADMIN)).length : 0; - case "TENANT_FINANCE": - return searchData - ? searchData.filter((user) => user.tenantRoles.includes(TenantRole.TENANT_FINANCE)).length : 0; - case "ALL_USERS": - default: - return searchData ? searchData.length : 0; + case "TENANT_ADMIN": + return searchData + ? searchData.filter((user) => user.tenantRoles.includes(TenantRole.TENANT_ADMIN)).length : 0; + case "TENANT_FINANCE": + return searchData + ? searchData.filter((user) => user.tenantRoles.includes(TenantRole.TENANT_FINANCE)).length : 0; + case "ALL_USERS": + default: + return searchData ? searchData.length : 0; } }, [searchData]); diff --git a/apps/mis-web/src/pageComponents/tenant/JobPriceChangeModal.tsx b/apps/mis-web/src/pageComponents/tenant/JobPriceChangeModal.tsx index 1f4f095a43..fe8313a895 100644 --- a/apps/mis-web/src/pageComponents/tenant/JobPriceChangeModal.tsx +++ b/apps/mis-web/src/pageComponents/tenant/JobPriceChangeModal.tsx @@ -75,10 +75,10 @@ export const JobPriceChangeModal: React.FC = ({ open, onClose, jobCount, {jobCount} - label={`${t(p("newJob"))}${text[target]}`} name="price" rules={[{ required: true }]}> + - name="reason" label={t(p("reason"))} rules={[{ required: true }]}> + diff --git a/apps/mis-web/src/pageComponents/tenant/TenantSelector.tsx b/apps/mis-web/src/pageComponents/tenant/TenantSelector.tsx index 10dd112618..033375fd6d 100644 --- a/apps/mis-web/src/pageComponents/tenant/TenantSelector.tsx +++ b/apps/mis-web/src/pageComponents/tenant/TenantSelector.tsx @@ -19,7 +19,7 @@ import { api } from "src/apis"; import { prefix, useI18nTranslateToString } from "src/i18n"; import { UserStore } from "src/stores/UserStore"; -type Props = { +interface Props { value?: string; onChange?: (value: string) => void; placeholder?: string; @@ -34,7 +34,7 @@ type Props = { * @param tenants all tenants */ onTenantsFetched?: (tenants: string[]) => void; -} +}; const p = prefix("pageComp.tenant.tenantSelector."); export const TenantSelector: React.FC = ({ diff --git a/apps/mis-web/src/pageComponents/users/AddUserButton.tsx b/apps/mis-web/src/pageComponents/users/AddUserButton.tsx index 49aa2350c5..91227dd8d0 100644 --- a/apps/mis-web/src/pageComponents/users/AddUserButton.tsx +++ b/apps/mis-web/src/pageComponents/users/AddUserButton.tsx @@ -128,10 +128,10 @@ export const AddUserButton: React.FC = ({ refresh, accountName, token, ca ), TIMEOUT_SECONDS, () => { window.open( - publicConfig.CREATE_USER_CONFIG.misConfig.external!.url + "?" + addUserToAccountParams( + publicConfig.CREATE_USER_CONFIG.misConfig.external!.url + "?" + addUserToAccountParams( accountName, identityId, name, token, ), - "_blank", + "_blank", ); setModalShow(false); }); diff --git a/apps/mis-web/src/pageComponents/users/JobChargeLimitModal.tsx b/apps/mis-web/src/pageComponents/users/JobChargeLimitModal.tsx index 3371f37b9e..6e7d87635b 100644 --- a/apps/mis-web/src/pageComponents/users/JobChargeLimitModal.tsx +++ b/apps/mis-web/src/pageComponents/users/JobChargeLimitModal.tsx @@ -39,7 +39,7 @@ interface FormFields { } interface FormFieldsConfirm { - unblock: Boolean; + unblock: boolean; } const p = prefix("pageComp.user.jobChargeLimitModal."); diff --git a/apps/mis-web/src/pageComponents/users/UserTable.tsx b/apps/mis-web/src/pageComponents/users/UserTable.tsx index a331f57774..211d6289bd 100644 --- a/apps/mis-web/src/pageComponents/users/UserTable.tsx +++ b/apps/mis-web/src/pageComponents/users/UserTable.tsx @@ -22,7 +22,7 @@ import { DisabledA } from "src/components/DisabledA"; import { prefix, useI18nTranslateToString } from "src/i18n"; import { DisplayedUserState, UserRole, UserStateInAccount } from "src/models/User"; import { SetJobChargeLimitLink } from "src/pageComponents/users/JobChargeLimitModal"; -import { GetAccountUsersSchema } from "src/pages/api/users"; +import { type GetAccountUsersSchema } from "src/pages/api/users"; import { moneyToString } from "src/utils/money"; interface Props { @@ -69,8 +69,8 @@ export const UserTable: React.FC = ({ defaultPageSize: DEFAULT_PAGE_SIZE, }} > - dataIndex="userId" title={t(pCommon("userId"))} /> - dataIndex="name" title={t(pCommon("name"))} /> + + dataIndex="role" title={t(p("role"))} diff --git a/apps/mis-web/src/pages/_app.tsx b/apps/mis-web/src/pages/_app.tsx index 1226687396..985c964c29 100644 --- a/apps/mis-web/src/pages/_app.tsx +++ b/apps/mis-web/src/pages/_app.tsx @@ -46,7 +46,6 @@ import { } from "src/stores/UserStore"; import { Cluster, getPublicConfigClusters } from "src/utils/cluster"; import { publicConfig, runtimeConfig } from "src/utils/config"; -import { queryIfInitialized } from "src/utils/init"; const languagesMap = { "zh_cn": zh_cn, @@ -73,7 +72,7 @@ const FailEventHandler: React.FC = () => { if (e.data?.code === "CLUSTEROPS_ERROR") { modal.error({ title: tArgs("page._app.multiClusterOpErrorTitle"), - content: `${tArgs("page._app.multiClusterOpErrorContent")}(${ + content: `${tArgs("page._app.multiClusterOpErrorContent") as string}(${ e.data.details })`, }); @@ -85,7 +84,7 @@ const FailEventHandler: React.FC = () => { (publicConfigClusters[clusterId]?.name ?? clusterId) : undefined; message.error(`${tArgs("page._app.adapterConnErrorContent", - [getI18nConfigCurrentText(clusterName, languageId)])}(${ + [getI18nConfigCurrentText(clusterName, languageId)]) as string}(${ e.data.details })`); return; @@ -101,7 +100,7 @@ const FailEventHandler: React.FC = () => { message.error(tArgs("page._app.notExistInActivatedClusters")); const currentActivatedClusterIds = e.data.currentActivatedClusterIds; - const newActivatedClusters: {[clusterId: string]: Cluster} = {}; + const newActivatedClusters: Record = {}; currentActivatedClusterIds.forEach((id: string) => { if (publicConfigClusters[id]) { newActivatedClusters[id] = publicConfigClusters[id]; @@ -116,7 +115,7 @@ const FailEventHandler: React.FC = () => { return; } - message.error(`${tArgs("page._app.effectErrorMessage")}(${e.status}, ${e.data?.code}))`); + message.error(`${tArgs("page._app.effectErrorMessage") as string}(${e.status}, ${e.data?.code}))`); }); }, []); @@ -155,7 +154,10 @@ function MyApp({ Component, pageProps, extra }: Props) { }); const clusterInfoStore = useConstant(() => { - return createStore(ClusterInfoStore, extra.clusterConfigs, extra.initialActivatedClusters, extra.initialSimpleClustersInfo); + return createStore( + ClusterInfoStore, + extra.clusterConfigs, extra.initialActivatedClusters, extra.initialSimpleClustersInfo, + ); }); const uiExtensionStore = useConstant(() => createStore(UiExtensionStore, publicConfig.UI_EXTENSION)); diff --git a/apps/mis-web/src/pages/accounts/[accountName]/info.tsx b/apps/mis-web/src/pages/accounts/[accountName]/info.tsx index dc3f56b375..563e3a9ecc 100644 --- a/apps/mis-web/src/pages/accounts/[accountName]/info.tsx +++ b/apps/mis-web/src/pages/accounts/[accountName]/info.tsx @@ -34,7 +34,7 @@ type Props = SSRProps<{ blocked: boolean; displayedState: DisplayedAccountState; blockThresholdAmount: number -}, 404> +}, 404>; export const AccountInfoPage: NextPage = requireAuth( (u) => u.accountAffiliations.length > 0, diff --git a/apps/mis-web/src/pages/accounts/index.tsx b/apps/mis-web/src/pages/accounts/index.tsx index b9bd0d542e..aae941bd55 100644 --- a/apps/mis-web/src/pages/accounts/index.tsx +++ b/apps/mis-web/src/pages/accounts/index.tsx @@ -18,10 +18,10 @@ import { useI18nTranslateToString } from "src/i18n"; import { accountAdminRoutes } from "src/layouts/routes"; import { AccountAffiliation, UserRole } from "src/models/User"; -type Props = { +interface Props { error: AuthResultError; adminAccounts?: AccountAffiliation[] -}; +} export const FinanceIndexPage: NextPage = ({ error, adminAccounts }) => { diff --git a/apps/mis-web/src/pages/admin/info.tsx b/apps/mis-web/src/pages/admin/info.tsx index f061c25164..b2f117ae66 100644 --- a/apps/mis-web/src/pages/admin/info.tsx +++ b/apps/mis-web/src/pages/admin/info.tsx @@ -25,13 +25,13 @@ import { PlatformRole } from "src/models/User"; import { getClient } from "src/utils/client"; import { Head } from "src/utils/head"; -type Info = GetAdminInfoResponse +type Info = GetAdminInfoResponse; -type Props = SSRProps +type Props = SSRProps; -export const PlatformInfoPage: NextPage = -requireAuth((u) => u.platformRoles.includes(PlatformRole.PLATFORM_ADMIN)) -((props: Props) => { +export const PlatformInfoPage: NextPage = requireAuth( + (u) => u.platformRoles.includes(PlatformRole.PLATFORM_ADMIN), +)((props: Props) => { const t = useI18nTranslateToString(); diff --git a/apps/mis-web/src/pages/admin/resource/clusterManagement.tsx b/apps/mis-web/src/pages/admin/resource/clusterManagement.tsx index 4f5ad78bae..33e8785ae7 100644 --- a/apps/mis-web/src/pages/admin/resource/clusterManagement.tsx +++ b/apps/mis-web/src/pages/admin/resource/clusterManagement.tsx @@ -57,7 +57,7 @@ export const ClusterManagementPage: NextPage = ]); const combinedClusterList: CombinedClusterInfo[] = []; - const currentActivatedClusters: {[clusterId: string]: Cluster} = {}; + const currentActivatedClusters: Record = {}; // sort by cluster's priority const sortedConnectionClustersData = connectionClustersData.results.sort((a, b) => { const sortedIds = clusterSortedIdList; diff --git a/apps/mis-web/src/pages/admin/statistic.tsx b/apps/mis-web/src/pages/admin/statistic.tsx index e67c99c09b..707af6b742 100644 --- a/apps/mis-web/src/pages/admin/statistic.tsx +++ b/apps/mis-web/src/pages/admin/statistic.tsx @@ -36,15 +36,15 @@ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; const p = prefix("page.admin.statistic."); -const formateData = (data: Array<{ +const formateData = (data: { date: { year: number, month: number, day: number }, count: number -}>, dateRange: [dayjs.Dayjs, dayjs.Dayjs]) => { +}[], dateRange: [dayjs.Dayjs, dayjs.Dayjs]) => { const input = data.map((d) => ({ date: dateMessageToDayjs(d.date), count: d.count, })); - const countData: {date: dayjs.Dayjs, count: number}[] = []; + const countData: { date: dayjs.Dayjs, count: number }[] = []; const [startDate, endDate] = dateRange; const days = endDate.diff(startDate, "day") + 1; let curDate = startDate.clone(); @@ -73,9 +73,9 @@ const TitleText = styled.span` font-weight: bold; `; -export const PlatformStatisticsPage: NextPage = -requireAuth((u) => u.platformRoles.includes(PlatformRole.PLATFORM_ADMIN)) -(() => { +export const PlatformStatisticsPage: NextPage = requireAuth( + (u) => u.platformRoles.includes(PlatformRole.PLATFORM_ADMIN), +)(() => { const t = useI18nTranslateToString(); const languageId = useI18n().currentLanguage.id; @@ -83,7 +83,7 @@ requireAuth((u) => u.platformRoles.includes(PlatformRole.PLATFORM_ADMIN)) const OperationTypeTexts = getOperationTypeTexts(t); const today = dayjs().endOf("day"); - const [query, setQuery] = useState<{filterTime: [dayjs.Dayjs, dayjs.Dayjs],}>({ + const [query, setQuery] = useState<{ filterTime: [dayjs.Dayjs, dayjs.Dayjs], }>({ filterTime: [today.clone().subtract(7, "day"), today], }); @@ -329,7 +329,7 @@ requireAuth((u) => u.platformRoles.includes(PlatformRole.PLATFORM_ADMIN)) presets={getDefaultPresets(languageId)} defaultValue={[query.filterTime?.[0], query.filterTime?.[1]]} onChange={(dates) => { - if (dates && dates[0] && dates[1]) { + if (dates?.[0] && dates?.[1]) { setQuery({ filterTime: [dates[0], dates[1]]}); } }} diff --git a/apps/mis-web/src/pages/admin/tenants/create.tsx b/apps/mis-web/src/pages/admin/tenants/create.tsx index fe11a666c3..ef2d70851b 100644 --- a/apps/mis-web/src/pages/admin/tenants/create.tsx +++ b/apps/mis-web/src/pages/admin/tenants/create.tsx @@ -141,13 +141,16 @@ const CreateTenantPageForm: React.FC = () => { }) .httpError(501, () => { message.error(t(p("unavailable"))); }) .then((createdInAuth) => { - !createdInAuth.createdInAuth ? + if (createdInAuth.createdInAuth) { + message.success(t(p("addCompleted"))); + } else { + modal.info({ title: t("common.addSuccess"), content: t(p("createTenantSuccessMessage")), okText: t("common.ok"), - }) - : message.success(t(p("addCompleted"))); + }); + } }) .catch(() => { modal.error({ diff --git a/apps/mis-web/src/pages/api/admin/getAllUsers.ts b/apps/mis-web/src/pages/api/admin/getAllUsers.ts index 6b478ec178..c19c958cbc 100644 --- a/apps/mis-web/src/pages/api/admin/getAllUsers.ts +++ b/apps/mis-web/src/pages/api/admin/getAllUsers.ts @@ -29,13 +29,13 @@ export type GetAllUsersResponse = Static; export const mapSortDirectionType = { "ascend": SortDirection.ASC, "descend": SortDirection.DESC, -} as { [key: string]: SortDirection }; +} as Record; export const mapUsersSortFieldType = { "userId": GetAllUsersRequest_UsersSortField.USER_ID, "name": GetAllUsersRequest_UsersSortField.NAME, "createTime": GetAllUsersRequest_UsersSortField.CREATE_TIME, -} as { [key: string]: GetAllUsersRequest_UsersSortField }; +} as Record; export const GetAllUsersSchema = typeboxRouteSchema({ diff --git a/apps/mis-web/src/pages/api/admin/getClustersRuntimeInfo.ts b/apps/mis-web/src/pages/api/admin/getClustersRuntimeInfo.ts index 52932e9c81..91a4f3781b 100644 --- a/apps/mis-web/src/pages/api/admin/getClustersRuntimeInfo.ts +++ b/apps/mis-web/src/pages/api/admin/getClustersRuntimeInfo.ts @@ -13,7 +13,7 @@ import { typeboxRouteSchema } from "@ddadaal/next-typed-api-routes-runtime"; import { asyncClientCall } from "@ddadaal/tsgrpc-client"; import { ClusterRuntimeInfo, ClusterRuntimeInfoSchema } from "@scow/config/build/type"; -import { ClusterRuntimeInfo_LastActivationOperation, ConfigServiceClient } from "@scow/protos/build/server/config"; +import { ConfigServiceClient } from "@scow/protos/build/server/config"; import { UserServiceClient } from "@scow/protos/build/server/user"; import { Type } from "@sinclair/typebox"; import { authenticate } from "src/auth/server"; @@ -56,11 +56,11 @@ export default route(GetClustersRuntimeInfoSchema, const client = getClient(ConfigServiceClient); const result = await asyncClientCall(client, "getClustersRuntimeInfo", {}); const operatorIds = Array.from(new Set(result.results.map((x) => { - const lastActivationOperation = x.lastActivationOperation as ClusterRuntimeInfo_LastActivationOperation; + const lastActivationOperation = x.lastActivationOperation!; return lastActivationOperation?.operatorId ?? undefined; }))); - const userIds = operatorIds.filter((id) => typeof id === "string" && id !== undefined && id !== null) as string[]; + const userIds = operatorIds.filter((id) => typeof id === "string" && id !== undefined && id !== null); const userClient = getClient(UserServiceClient); const { users } = await asyncClientCall(userClient, "getUsersByIds", { @@ -72,7 +72,7 @@ export default route(GetClustersRuntimeInfoSchema, const clusterConfigs = await getClusterConfigFiles(); const clustersDatabaseInfo: ClusterRuntimeInfo[] = result.results.map((x) => { - const lastActivationOperation = x.lastActivationOperation as ClusterRuntimeInfo_LastActivationOperation; + const lastActivationOperation = x.lastActivationOperation!; return { ...x, operatorId: lastActivationOperation?.operatorId ?? "", diff --git a/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogs.ts b/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogs.ts index 2d7a9423e0..e5eadc8b43 100644 --- a/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogs.ts +++ b/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogs.ts @@ -21,12 +21,10 @@ import { DEFAULT_GRAFANA_URL } from "src/utils/constants"; import { route } from "src/utils/route"; interface GrafanaApiResponse { - results: { - [key: string]: { - status: number; - frames: GrafanaFrame[]; - }; - }; + results: Record; } interface GrafanaFrame { @@ -173,7 +171,7 @@ export default /* #__PURE__*/route(GetAlarmLogsSchema, async (req, res) => { .then((response) => response.json()) .then((data: GrafanaApiResponse) => { // 检查数据是否存在或为空 - if (!data || !data.results || !data.results.A || data.results.A.status !== 200) { + if (!data?.results?.A || data.results.A.status !== 200) { return { 400: null }; } return { 200: { diff --git a/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogsCount.ts b/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogsCount.ts index 58be9d35aa..19519e073d 100644 --- a/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogsCount.ts +++ b/apps/mis-web/src/pages/api/admin/monitor/getAlarmLogsCount.ts @@ -21,12 +21,10 @@ import { DEFAULT_GRAFANA_URL } from "src/utils/constants"; import { route } from "src/utils/route"; interface GrafanaApiResponse { - results: { - [key: string]: { - status: number; - frames: GrafanaFrame[]; - }; - }; + results: Record; } interface GrafanaFrame { @@ -149,7 +147,7 @@ export default /* #__PURE__*/route(GetAlarmLogsCountSchema, async (req, res) => }) .then((response) => response.json()) .then((data: GrafanaApiResponse) => { - if (!data || !data.results || !data.results.A || data.results.A.status !== 200) { + if (!data?.results?.A || data.results.A.status !== 200) { return { 400: null }; } return { 200: { totalCount: transformGrafanaData(data)[0].totalCount } }; diff --git a/apps/mis-web/src/pages/api/clusterConfigsInfo.ts b/apps/mis-web/src/pages/api/clusterConfigsInfo.ts index 18ed7c1445..b9e3f16db3 100644 --- a/apps/mis-web/src/pages/api/clusterConfigsInfo.ts +++ b/apps/mis-web/src/pages/api/clusterConfigsInfo.ts @@ -28,7 +28,6 @@ import { Type } from "@sinclair/typebox"; import { authenticate } from "src/auth/server"; import { validateToken } from "src/auth/token"; import { getClusterConfigFiles } from "src/server/clusterConfig"; -import { queryIfInitialized } from "src/utils/init"; import { route } from "src/utils/route"; diff --git a/apps/mis-web/src/pages/api/file/exportOperationLog.ts b/apps/mis-web/src/pages/api/file/exportOperationLog.ts index 1d5ac139ad..de1e5d897e 100644 --- a/apps/mis-web/src/pages/api/file/exportOperationLog.ts +++ b/apps/mis-web/src/pages/api/file/exportOperationLog.ts @@ -83,34 +83,34 @@ const getExportSource = ( accountName: string | undefined): ExportOperationLog["source"] => { switch (type) { - case OperationLogQueryType.USER: - return { - $case: "user", - user: { - userId: info.identityId, - }, - }; - case OperationLogQueryType.ACCOUNT: - return accountName - ? { - $case: "account", - account: { - accountName, + case OperationLogQueryType.USER: + return { + $case: "user", + user: { + userId: info.identityId, }, - } - : undefined; - case OperationLogQueryType.TENANT: - return { - $case: "tenant", - tenant: { - tenantName: info.tenant, - }, - }; - default: - return { - $case: "admin", - admin: {}, - }; + }; + case OperationLogQueryType.ACCOUNT: + return accountName + ? { + $case: "account", + account: { + accountName, + }, + } + : undefined; + case OperationLogQueryType.TENANT: + return { + $case: "tenant", + tenant: { + tenantName: info.tenant, + }, + }; + default: + return { + $case: "admin", + admin: {}, + }; } }; @@ -221,12 +221,12 @@ export default typeboxRoute(ExportOperationLogSchema, async (req, res) => { const formatOperationLog = (x: OperationLog) => { return { id: x.operationLogId, - operationCode: x.operationEvent?.["$case"] ? OperationCodeMap[x.operationEvent?.["$case"]] : "000000", - operationType: x.operationEvent?.["$case"] === "customEvent" + operationCode: x.operationEvent?.$case ? OperationCodeMap[x.operationEvent?.$case] : "000000", + operationType: x.operationEvent?.$case === "customEvent" ? getI18nCurrentText(x.operationEvent.customEvent.name, languageId) - : OperationTypeTexts[x.operationEvent?.["$case"] || "unknown"], + : OperationTypeTexts[x.operationEvent?.$case || "unknown"], operationDetail: x.operationEvent ? - x.operationEvent?.["$case"] === "customEvent" + x.operationEvent?.$case === "customEvent" ? getI18nCurrentText(x.operationEvent.customEvent.content, languageId) : getOperationDetail(x.operationEvent, t, tArgs, languageId) : "", diff --git a/apps/mis-web/src/pages/api/finance/charges.ts b/apps/mis-web/src/pages/api/finance/charges.ts index 7a71f8f31e..9a1f284bef 100644 --- a/apps/mis-web/src/pages/api/finance/charges.ts +++ b/apps/mis-web/src/pages/api/finance/charges.ts @@ -42,12 +42,12 @@ export const mapChargesSortByType = { "time":SortBy.TIME, "amount":SortBy.AMOUNT, "type":SortBy.TYPE, -} as { [key: string]: SortBy}; +} as Record; export const mapChargesSortOrderType = { "descend":SortOrder.DESCEND, "ascend":SortOrder.ASCEND, -} as { [key: string]: SortOrder}; +} as Record; export const ChargeInfo = Type.Object({ index: Type.Number(), diff --git a/apps/mis-web/src/pages/api/finance/payments.ts b/apps/mis-web/src/pages/api/finance/payments.ts index 04a79e42e0..0ee26aa1f0 100644 --- a/apps/mis-web/src/pages/api/finance/payments.ts +++ b/apps/mis-web/src/pages/api/finance/payments.ts @@ -71,22 +71,22 @@ export const getPaymentRecordTarget = ( targetNames: string[] | undefined, ) => { switch (searchType) { - case SearchType.tenant: - return targetNames - ? { $case:"tenant" as const, tenant:{ tenantName:targetNames[0] } } - : { $case:"allTenants" as const, allTenants:{ } }; - case SearchType.selfTenant: - return { $case:"tenant" as const, tenant:{ tenantName:user.tenant } }; - case SearchType.selfAccount: - return { $case:"accountsOfTenant" as const, - accountsOfTenant:{ tenantName:user.tenant, accountNames:targetNames ?? []} }; - case SearchType.account: - return targetNames - ? { $case:"accountsOfTenant" as const, - accountsOfTenant:{ tenantName:tenantOfAccount, accountNames:targetNames } } - : { $case:"accountsOfTenant" as const, accountsOfTenant:{ tenantName:user.tenant, accountNames:[]} }; - default: - break; + case SearchType.tenant: + return targetNames + ? { $case:"tenant" as const, tenant:{ tenantName:targetNames[0] } } + : { $case:"allTenants" as const, allTenants:{ } }; + case SearchType.selfTenant: + return { $case:"tenant" as const, tenant:{ tenantName:user.tenant } }; + case SearchType.selfAccount: + return { $case:"accountsOfTenant" as const, + accountsOfTenant:{ tenantName:user.tenant, accountNames:targetNames ?? []} }; + case SearchType.account: + return targetNames + ? { $case:"accountsOfTenant" as const, + accountsOfTenant:{ tenantName:tenantOfAccount, accountNames:targetNames } } + : { $case:"accountsOfTenant" as const, accountsOfTenant:{ tenantName:user.tenant, accountNames:[]} }; + default: + break; } }; diff --git a/apps/mis-web/src/pages/api/job/changeJobTimeLimit.ts b/apps/mis-web/src/pages/api/job/changeJobTimeLimit.ts index 28602545d7..63f4132206 100644 --- a/apps/mis-web/src/pages/api/job/changeJobTimeLimit.ts +++ b/apps/mis-web/src/pages/api/job/changeJobTimeLimit.ts @@ -26,7 +26,7 @@ import { handlegRPCError, parseIp } from "src/utils/server"; export type ChangeMode = | "INCREASE" - | "DECREASE" + | "DECREASE"; // 修改作业运行时限。 // 只有平台管理员、租户管理员、或者作业发起者本人、或者作业发起者所在账户的管理员或者拥有者可以修改 diff --git a/apps/mis-web/src/pages/api/job/jobInfo.ts b/apps/mis-web/src/pages/api/job/jobInfo.ts index 78e1991dd9..48e78c8fe2 100644 --- a/apps/mis-web/src/pages/api/job/jobInfo.ts +++ b/apps/mis-web/src/pages/api/job/jobInfo.ts @@ -34,12 +34,12 @@ export const mapJobSortByType = { "timeEnd":SortBy.TIME_END, "timeSubmit":SortBy.TIME_SUBMIT, "user":SortBy.USER, -}as { [key: string]: SortBy}; +} as Record; export const mapJobSortOrderType = { "descend":SortOrder.DESCEND, "ascend":SortOrder.ASCEND, -}as { [key: string]: SortOrder}; +} as Record; export const GetJobFilter = Type.Object({ diff --git a/apps/mis-web/src/pages/api/log/getOperationLog.ts b/apps/mis-web/src/pages/api/log/getOperationLog.ts index 024edf1328..f9d926cf9a 100644 --- a/apps/mis-web/src/pages/api/log/getOperationLog.ts +++ b/apps/mis-web/src/pages/api/log/getOperationLog.ts @@ -30,12 +30,12 @@ export const mapOperationSortByType = { "operationTime":SortBy.OPERATION_TIME, "operatorIp":SortBy.OPERATOR_IP, "operatorUserId":SortBy.OPERATOR_USER_ID, -} as { [key: string]: SortBy}; +} as Record; export const mapOperationSortOrderType = { "descend":SortOrder.DESCEND, "ascend":SortOrder.ASCEND, -} as { [key: string]: SortOrder }; +} as Record; export const GetOperationLogFilter = Type.Object({ diff --git a/apps/mis-web/src/pages/api/profile/changePassword.ts b/apps/mis-web/src/pages/api/profile/changePassword.ts index cf2995510b..82336104f2 100644 --- a/apps/mis-web/src/pages/api/profile/changePassword.ts +++ b/apps/mis-web/src/pages/api/profile/changePassword.ts @@ -75,12 +75,12 @@ export default /* #__PURE__*/typeboxRoute(ChangePasswordSchema, async (req, res) .then(() => ({ 204: null })) .catch((e) => { switch (e.status) { - case "NOT_FOUND": - return { 404: null }; - case "NOT_SUPPORTED": - return { 501: null }; - default: - throw e; + case "NOT_FOUND": + return { 404: null }; + case "NOT_SUPPORTED": + return { 501: null }; + default: + throw e; } }); diff --git a/apps/mis-web/src/pages/api/profile/checkPassword.ts b/apps/mis-web/src/pages/api/profile/checkPassword.ts index 7ca3170e78..acc2a75470 100644 --- a/apps/mis-web/src/pages/api/profile/checkPassword.ts +++ b/apps/mis-web/src/pages/api/profile/checkPassword.ts @@ -61,10 +61,10 @@ export default typeboxRoute(CheckPasswordSchema, async (req, res) => { }) .catch((e) => { switch (e.status) { - case "NOT_SUPPORTED": - return { 501: null }; - default: - throw e; + case "NOT_SUPPORTED": + return { 501: null }; + default: + throw e; } }); }); diff --git a/apps/mis-web/src/pages/api/simpleClustersInfo.ts b/apps/mis-web/src/pages/api/simpleClustersInfo.ts index 3b5f153114..1df3ad4023 100644 --- a/apps/mis-web/src/pages/api/simpleClustersInfo.ts +++ b/apps/mis-web/src/pages/api/simpleClustersInfo.ts @@ -23,12 +23,12 @@ */ import { typeboxRouteSchema } from "@ddadaal/next-typed-api-routes-runtime"; -import { getClusterConfigFiles } from "src/server/clusterConfig"; import { ClusterConfigSchema, SimpleClusterSchema } from "@scow/config/build/cluster"; -import { route } from "src/utils/route"; import { Type } from "@sinclair/typebox"; -import { queryIfInitialized } from "src/utils/init"; import { authenticate } from "src/auth/server"; +import { getClusterConfigFiles } from "src/server/clusterConfig"; +import { queryIfInitialized } from "src/utils/init"; +import { route } from "src/utils/route"; export const GetSimpleClustersInfoFromConfigFilesSchema = typeboxRouteSchema({ method: "GET", @@ -54,13 +54,13 @@ export default route(GetSimpleClustersInfoFromConfigFilesSchema, const clustersInfo: Record = {}; - Object.keys(clustersFullInfo).forEach(key => { + Object.keys(clustersFullInfo).forEach((key) => { clustersInfo[key] = { clusterId: key, displayName: clustersFullInfo[key].displayName, priority: clustersFullInfo[key].priority, - }; - }); + }; + }); return { 200: { clustersInfo }, diff --git a/apps/mis-web/src/pages/dashboard.tsx b/apps/mis-web/src/pages/dashboard.tsx index e754bfa4b4..ee542f99c5 100644 --- a/apps/mis-web/src/pages/dashboard.tsx +++ b/apps/mis-web/src/pages/dashboard.tsx @@ -27,7 +27,7 @@ import { UnifiedErrorPage } from "src/components/errorPages/UnifiedErrorPage"; import { useI18nTranslateToString } from "src/i18n"; import { AccountInfoSection } from "src/pageComponents/dashboard/AccountInfoSection"; import { JobsSection } from "src/pageComponents/dashboard/JobsSection"; -import { getUserStatus, GetUserStatusSchema } from "src/pages/api/dashboard/status"; +import { getUserStatus, type GetUserStatusSchema } from "src/pages/api/dashboard/status"; import { UserStore } from "src/stores/UserStore"; import { ensureNotUndefined } from "src/utils/checkNull"; @@ -38,7 +38,7 @@ export type AccountInfo = Omit = ({ tenantName }) => > - name="comment" label={t(p("remark"))}> + diff --git a/apps/mis-web/src/pages/tenant/info.tsx b/apps/mis-web/src/pages/tenant/info.tsx index b2c05771ef..34885a1b06 100644 --- a/apps/mis-web/src/pages/tenant/info.tsx +++ b/apps/mis-web/src/pages/tenant/info.tsx @@ -35,75 +35,75 @@ import { handlegRPCError } from "src/utils/server"; type Info = GetTenantInfoResponse & { tenantName: string }; -type Props = SSRProps +type Props = SSRProps; const p = prefix("page.tenant.info."); -export const TenantInfoPage: NextPage = requireAuth((u) => u.tenantRoles.includes(TenantRole.TENANT_ADMIN)) -((props: Props) => { +export const TenantInfoPage: NextPage = requireAuth((u) => u.tenantRoles.includes(TenantRole.TENANT_ADMIN))( + (props: Props) => { - const router = useRouter(); + const router = useRouter(); - const t = useI18nTranslateToString(); + const t = useI18nTranslateToString(); - if ("error" in props) { - return ; - } + if ("error" in props) { + return ; + } - const { balance, accountCount, admins, - userCount, tenantName, financialStaff, defaultAccountBlockThreshold } = + const { balance, accountCount, admins, + userCount, tenantName, financialStaff, defaultAccountBlockThreshold } = ensureNotUndefined(props, ["balance", "defaultAccountBlockThreshold"]); - return ( -
- - - - - {tenantName} - - - { - admins.map(({ userId, userName }) => ( - - {userName} (ID: {userId}) - - )) - } - - - { - financialStaff.map(({ userId, userName }) => ( - - {userName} (ID: {userId}) - - )) - } - - - {accountCount} - - - {userCount} - - - {moneyToNumber(balance).toFixed(2)} {t("common.unit")} - - - - - {moneyToNumber(defaultAccountBlockThreshold).toFixed(2)} {t("common.unit")} - - { router.reload(); }} - >修改 - - -
- ); -}); + return ( +
+ + + + + {tenantName} + + + { + admins.map(({ userId, userName }) => ( + + {userName} (ID: {userId}) + + )) + } + + + { + financialStaff.map(({ userId, userName }) => ( + + {userName} (ID: {userId}) + + )) + } + + + {accountCount} + + + {userCount} + + + {moneyToNumber(balance).toFixed(2)} {t("common.unit")} + + + + + {moneyToNumber(defaultAccountBlockThreshold).toFixed(2)} {t("common.unit")} + + { router.reload(); }} + >修改 + + +
+ ); + }); export const getServerSideProps: GetServerSideProps = async (ctx) => { diff --git a/apps/mis-web/src/pages/tenant/storage.tsx b/apps/mis-web/src/pages/tenant/storage.tsx index 04fc9e7965..c2a4c2530d 100644 --- a/apps/mis-web/src/pages/tenant/storage.tsx +++ b/apps/mis-web/src/pages/tenant/storage.tsx @@ -128,7 +128,7 @@ const StorageForm: React.FC = () => { }
- label={t(p("storageChange"))} rules={[{ required: true }]}> + diff --git a/apps/portal-web/src/pageComponents/filemanager/FileEditModal.tsx b/apps/portal-web/src/pageComponents/filemanager/FileEditModal.tsx index 506b9c9329..381a6fc014 100644 --- a/apps/portal-web/src/pageComponents/filemanager/FileEditModal.tsx +++ b/apps/portal-web/src/pageComponents/filemanager/FileEditModal.tsx @@ -256,6 +256,7 @@ export const FileEditModal: React.FC = ({ previewFile, setPreviewFile }) body: formData, }).then((response) => { if (!response.ok) { + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors return Promise.reject(response.statusText); } message.success(t(p("saveFileSuccess"))); @@ -418,7 +419,11 @@ export const FileEditModal: React.FC = ({ previewFile, setPreviewFile }) options={options} value={fileContent} onMount={(editor) => { editorRef.current = editor; }} - onChange={(content) => { !downloading && handleEdit(content); }} + onChange={(content) => { + if (!downloading) { + handleEdit(content); + } + }} /> ), diff --git a/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx b/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx index a1cbcd9a2d..ffe5c06191 100644 --- a/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx +++ b/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx @@ -224,7 +224,7 @@ export const FileManager: React.FC = ({ cluster, path, urlPrefix }) => { const exists = await api.fileExist({ query: { cluster: cluster.id, path: join(path, x.name) } }); if (exists.result) { - await new Promise(async (res) => { + await new Promise((res) => { modal.confirm({ title: t(p("moveCopy.existModalTitle")), content: t(p("moveCopy.existModalContent"), [x.name]), @@ -233,24 +233,16 @@ export const FileManager: React.FC = ({ cluster, path, urlPrefix }) => { const fileType = await api.getFileType({ query: { cluster: cluster.id, path: join(path, x.name) } }); const deleteOperation = fileType.type === "dir" ? api.deleteDir : api.deleteFile; await deleteOperation({ query: { cluster: cluster.id, path: join(path, x.name) } }); - try { - await pasteFile(x, join(operation.originalPath, x.name), join(path, x.name)); - successfulCount++; - } catch (e) { - throw e; - } + await pasteFile(x, join(operation.originalPath, x.name), join(path, x.name)); + successfulCount++; res(); }, onCancel: async () => { abandonCount++; res(); }, }); }); } else { - try { - await pasteFile(x, join(operation.originalPath, x.name), join(path, x.name)); - successfulCount++; - } catch (e) { - throw e; - } + await pasteFile(x, join(operation.originalPath, x.name), join(path, x.name)); + successfulCount++; } } catch (e) { console.error(e); @@ -295,7 +287,7 @@ export const FileManager: React.FC = ({ cluster, path, urlPrefix }) => { message.success(t(p("delete.successMessage"), [allCount])); resetSelectedAndOperation(); } else { - message.error(t(p("delete.errorMessage"), [(allCount - failedCount), failedCount])), + message.error(t(p("delete.errorMessage"), [(allCount - failedCount), failedCount])); setOperation((o) => o && ({ ...o, started: false })); } }).catch((e) => { @@ -388,7 +380,13 @@ export const FileManager: React.FC = ({ cluster, path, urlPrefix }) => { { curPath === path ? reload() : router.push(fullUrl(curPath)); }} + onPathChange={(curPath) => { + if (curPath === path) { + reload(); + } else { + router.push(fullUrl(curPath)); + } + }} breadcrumbItemRender={(pathSegment, index, path) => (index === 0 ? ( e.stopPropagation()}> @@ -615,24 +613,27 @@ export const FileManager: React.FC = ({ cluster, path, urlPrefix }) => { }, }) .httpError(500, (e) => { - e.code === "SCHEDULER_FAILED" || - e.code === "FAILED_PRECONDITION" - || e.code === "UNIMPLEMENTED" ? modal.error({ + if (e.code === "SCHEDULER_FAILED" || e.code === "FAILED_PRECONDITION" + || e.code === "UNIMPLEMENTED") { + modal.error({ title: t(p("tableInfo.submitFailedMessage")), content: e.message, - }) : (() => { - message.error(e.message); - throw e; - })(); + }); + } else { + message.error(e.message); + throw e; + } }) .httpError(400, (e) => { - e.code === "INVALID_ARGUMENT" || e.code === "INVALID_PATH" ? modal.error({ - title: t(p("tableInfo.submitFailedMessage")), - content: e.message, - }) : (() => { + if (e.code === "INVALID_ARGUMENT" || e.code === "INVALID_PATH") { + modal.error({ + title: t(p("tableInfo.submitFailedMessage")), + content: e.message, + }); + } else { message.error(e.message); throw e; - })(); + } }) .then((result) => { message.success(t(p("tableInfo.submitSuccessMessage"), [result.jobId])); diff --git a/apps/portal-web/src/pageComponents/filemanager/MkdirModal.tsx b/apps/portal-web/src/pageComponents/filemanager/MkdirModal.tsx index be380e44d7..5a943102d1 100644 --- a/apps/portal-web/src/pageComponents/filemanager/MkdirModal.tsx +++ b/apps/portal-web/src/pageComponents/filemanager/MkdirModal.tsx @@ -68,7 +68,7 @@ export const MkdirModal: React.FC = ({ open, onClose, path, reload, clust {path} - label={t(p("dirName"))} name="newFileName" rules={[{ required: true }]}> + diff --git a/apps/portal-web/src/pageComponents/filemanager/RenameModal.tsx b/apps/portal-web/src/pageComponents/filemanager/RenameModal.tsx index e872aa7594..e4014cc450 100644 --- a/apps/portal-web/src/pageComponents/filemanager/RenameModal.tsx +++ b/apps/portal-web/src/pageComponents/filemanager/RenameModal.tsx @@ -70,7 +70,7 @@ export const RenameModal: React.FC = ({ open, onClose, path, reload, clus {path} - label={t(p("newFileName"))} name="newFileName" rules={[{ required: true }]}> + diff --git a/apps/portal-web/src/pageComponents/filemanager/UploadModal.tsx b/apps/portal-web/src/pageComponents/filemanager/UploadModal.tsx index f904af6c3f..6a1065ae03 100644 --- a/apps/portal-web/src/pageComponents/filemanager/UploadModal.tsx +++ b/apps/portal-web/src/pageComponents/filemanager/UploadModal.tsx @@ -95,26 +95,29 @@ export const UploadModal: React.FC = ({ open, onClose, path, reload, clus return Upload.LIST_IGNORE; } - return new Promise(async (resolve, reject) => { - - const exists = await api.fileExist({ query:{ cluster: cluster, path: join(path, file.name) } }); - - if (exists.result) { - modal.confirm({ - title: t(p("existedModalTitle")), - content: t(p("existedModalContent"), [file.name]), - okText: t(p("existedModalOk")), - onOk: async () => { - const fileType = await api.getFileType({ query:{ cluster: cluster, path: join(path, file.name) } }); - const deleteOperation = fileType.type === "dir" ? api.deleteDir : api.deleteFile; - await deleteOperation({ query: { cluster: cluster, path: join(path, file.name) } }) - .then(() => resolve(file)); - }, - onCancel: () => { reject(file); }, - }); - } else { - resolve(file); - } + return new Promise((resolve, reject) => { + + api.fileExist({ query:{ cluster: cluster, path: join(path, file.name) } }).then(({ result }) => { + if (result) { + modal.confirm({ + title: t(p("existedModalTitle")), + content: t(p("existedModalContent"), [file.name]), + okText: t(p("existedModalOk")), + onOk: async () => { + const fileType = await api.getFileType({ query:{ cluster: cluster, path: join(path, file.name) } }); + const deleteOperation = fileType.type === "dir" ? api.deleteDir : api.deleteFile; + await deleteOperation({ query: { cluster: cluster, path: join(path, file.name) } }) + .then(() => resolve(file)); + }, + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors + onCancel: () => { reject(file); }, + }); + } else { + resolve(file); + } + + }); + }); }} diff --git a/apps/portal-web/src/pageComponents/job/AccountSelector.tsx b/apps/portal-web/src/pageComponents/job/AccountSelector.tsx index 16b5af48c7..071ad6b4a9 100644 --- a/apps/portal-web/src/pageComponents/job/AccountSelector.tsx +++ b/apps/portal-web/src/pageComponents/job/AccountSelector.tsx @@ -43,7 +43,7 @@ export const AccountSelector: React.FC = ({ cluster, onChange, value }) = useEffect(() => { - if (data && data.accounts.length) { + if (data?.accounts.length) { if (!value || !data.accounts.includes(value)) { onChange?.(data.accounts[0]); } diff --git a/apps/portal-web/src/pageComponents/job/AllJobsTable.tsx b/apps/portal-web/src/pageComponents/job/AllJobsTable.tsx index 161772044c..1caee100bc 100644 --- a/apps/portal-web/src/pageComponents/job/AllJobsTable.tsx +++ b/apps/portal-web/src/pageComponents/job/AllJobsTable.tsx @@ -143,12 +143,12 @@ export const AllJobQueryTable: React.FC = ({ ); }; -type JobInfoTableProps = { +interface JobInfoTableProps { data: JobInfo[] | undefined; isLoading: boolean; reload: () => void; cluster: Cluster; -}; +} export const JobInfoTable: React.FC = ({ data, isLoading, cluster, diff --git a/apps/portal-web/src/pageComponents/job/FileSelectModal.tsx b/apps/portal-web/src/pageComponents/job/FileSelectModal.tsx index 714b9a6185..1ce8b95377 100644 --- a/apps/portal-web/src/pageComponents/job/FileSelectModal.tsx +++ b/apps/portal-web/src/pageComponents/job/FileSelectModal.tsx @@ -143,7 +143,11 @@ export const FileSelectModal: React.FC = ({ cluster, onSubmit }) => { path={formatPath(path)} loading={isLoading} onPathChange={(curPath) => { - curPath === path ? reload() : setPath(join("/", curPath)); + if (curPath === path) { + reload(); + } else { + setPath(join("/", curPath)); + } }} breadcrumbItemRender={(segment, index, curPath) => index === 0 diff --git a/apps/portal-web/src/pageComponents/job/RunningJobTable.tsx b/apps/portal-web/src/pageComponents/job/RunningJobTable.tsx index 41fcb47f29..94bd2828ee 100644 --- a/apps/portal-web/src/pageComponents/job/RunningJobTable.tsx +++ b/apps/portal-web/src/pageComponents/job/RunningJobTable.tsx @@ -119,11 +119,11 @@ export const RunningJobQueryTable: React.FC = ({ ); }; -type JobInfoTableProps = { +interface JobInfoTableProps { data: RunningJobInfo[] | undefined; isLoading: boolean; reload: () => void; -}; +} export const RunningJobInfoTable: React.FC = ({ data, isLoading, reload, diff --git a/apps/portal-web/src/pageComponents/job/SubmitJobForm.tsx b/apps/portal-web/src/pageComponents/job/SubmitJobForm.tsx index 3d7f645b06..e6afa31068 100644 --- a/apps/portal-web/src/pageComponents/job/SubmitJobForm.tsx +++ b/apps/portal-web/src/pageComponents/job/SubmitJobForm.tsx @@ -140,15 +140,15 @@ export const SubmitJobForm: React.FC = ({ initial = initialValues, submit }; - const jobName = Form.useWatch("jobName", form) as string; + const jobName = Form.useWatch("jobName", form); - const nodeCount = Form.useWatch("nodeCount", form) as number; + const nodeCount = Form.useWatch("nodeCount", form); - const coreCount = Form.useWatch("coreCount", form) as number; + const coreCount = Form.useWatch("coreCount", form); - const gpuCount = Form.useWatch("gpuCount", form) as number; + const gpuCount = Form.useWatch("gpuCount", form)!; - const showScriptOutput = Form.useWatch("showScriptOutput", form) as boolean; + const showScriptOutput = Form.useWatch("showScriptOutput", form); const calculateWorkingDirectory = (template: string, homePath: string = "") => join(homePath + "/", parsePlaceholder(template, { name: jobName })); @@ -294,7 +294,7 @@ export const SubmitJobForm: React.FC = ({ initial = initialValues, submit // 第一次请求已经处理过 setIsFirstParQuery(false); } else { - if (data && data.partitions && data.partitions.length > 0) { + if (data?.partitions && data.partitions.length > 0) { form.setFieldValue("partition", data.partitions[0].name); form.setFieldValue("qos", data.partitions[0].qos?.[0]); } @@ -383,12 +383,12 @@ export const SubmitJobForm: React.FC = ({ initial = initialValues, submit >
- label={t(p("cluster"))} name="cluster" rules={[{ required: true }]}> + - label={t(p("jobName"))} name="jobName" rules={[{ required: true }, { max: 50 }]}> + @@ -567,12 +567,12 @@ export const SubmitJobForm: React.FC = ({ initial = initialValues, submit - label={t(p("output"))} name="output" rules={[{ required: true }]}> + - label={t(p("errorOutput"))} name="errorOutput" rules={[{ required: true }]}> + diff --git a/apps/portal-web/src/pageComponents/shell/Shell.tsx b/apps/portal-web/src/pageComponents/shell/Shell.tsx index c985e4d5f1..c03da75274 100644 --- a/apps/portal-web/src/pageComponents/shell/Shell.tsx +++ b/apps/portal-web/src/pageComponents/shell/Shell.tsx @@ -103,37 +103,38 @@ export const Shell: React.FC = ({ user, cluster, loginNode, path }) => { socket.onmessage = (e) => { const message = JSON.parse(e.data) as ShellOutputData; switch (message.$case) { - case "data": - const data = Buffer.from(message.data.data); - - const dataString = data.toString(); - if (dataString.includes(OPEN_FILE) && !dataString.includes("pwd")) { - const result = dataString.split("\r\n")[0]; - const pathStartIndex = result.search("/"); - const path = result.substring(pathStartIndex); - - if (result.includes(OPEN_EXPLORER_PREFIX)) { - window.open(join(publicConfig.BASE_PATH, "/files", cluster, path)); - } else if (result.includes(DOWNLOAD_FILE_PREFIX)) { - const fileStartIndex = result.search(DOWNLOAD_FILE_PREFIX); - const fileEndIndex = result.search(DOWNLOAD_FILE_SUFFIX); - const file = result.substring(fileStartIndex + DOWNLOAD_FILE_PREFIX.length, fileEndIndex); - window.location.href = urlToDownload(cluster, join(path, file), true); - } else if (result.includes(EDIT_FILE_PREFIX)) { - const fileStartIndex = result.search(EDIT_FILE_PREFIX); - const fileEndIndex = result.search(EDIT_FILE_SUFFIX); - const file = result.substring(fileStartIndex + EDIT_FILE_PREFIX.length, fileEndIndex); - window.open(join(publicConfig.BASE_PATH, "/files", cluster, path + "?edit=" + file)); - } else if (result.includes(UPLOAD_FILE_PREFIX)) { - window.open(join(publicConfig.BASE_PATH, "/files", cluster, path + "?uploadModalOpen=true")); + case "data": { + const data = Buffer.from(message.data.data); + + const dataString = data.toString(); + if (dataString.includes(OPEN_FILE) && !dataString.includes("pwd")) { + const result = dataString.split("\r\n")[0]; + const pathStartIndex = result.search("/"); + const path = result.substring(pathStartIndex); + + if (result.includes(OPEN_EXPLORER_PREFIX)) { + window.open(join(publicConfig.BASE_PATH, "/files", cluster, path)); + } else if (result.includes(DOWNLOAD_FILE_PREFIX)) { + const fileStartIndex = result.search(DOWNLOAD_FILE_PREFIX); + const fileEndIndex = result.search(DOWNLOAD_FILE_SUFFIX); + const file = result.substring(fileStartIndex + DOWNLOAD_FILE_PREFIX.length, fileEndIndex); + window.location.href = urlToDownload(cluster, join(path, file), true); + } else if (result.includes(EDIT_FILE_PREFIX)) { + const fileStartIndex = result.search(EDIT_FILE_PREFIX); + const fileEndIndex = result.search(EDIT_FILE_SUFFIX); + const file = result.substring(fileStartIndex + EDIT_FILE_PREFIX.length, fileEndIndex); + window.open(join(publicConfig.BASE_PATH, "/files", cluster, path + "?edit=" + file)); + } else if (result.includes(UPLOAD_FILE_PREFIX)) { + window.open(join(publicConfig.BASE_PATH, "/files", cluster, path + "?uploadModalOpen=true")); + } } - } - term.write(data); + term.write(data); - break; - case "exit": - term.write(`Process exited with code ${message.exit.code} and signal ${message.exit.signal}.`); - break; + break; + } + case "exit": + term.write(`Process exited with code ${message.exit.code} and signal ${message.exit.signal}.`); + break; } }; diff --git a/apps/portal-web/src/pages/_app.tsx b/apps/portal-web/src/pages/_app.tsx index 1b228827e6..d33ff4ad54 100644 --- a/apps/portal-web/src/pages/_app.tsx +++ b/apps/portal-web/src/pages/_app.tsx @@ -96,7 +96,7 @@ const FailEventHandler: React.FC = () => { (publicConfigClusters.find((c) => c.id === clusterId)?.name ?? clusterId) : undefined; message.error(`${tArgs("pages._app.adapterConnectionError", - [getI18nConfigCurrentText(clusterName, languageId)])}(${ + [getI18nConfigCurrentText(clusterName, languageId)]) as string}(${ e.data.details })`); return; @@ -123,7 +123,7 @@ const FailEventHandler: React.FC = () => { return; } - message.error(`${tArgs("pages._app.otherError")}(${e.status}, ${e.data?.code}))`); + message.error(`${tArgs("pages._app.otherError") as string}(${e.status}, ${e.data?.code}))`); }); }, []); @@ -145,7 +145,7 @@ interface ExtraProps { loginNodes: Record; darkModeCookieValue: DarkModeCookie | undefined; initialLanguage: string; - clusterConfigs: { [clusterId: string]: ClusterConfigSchema }; + clusterConfigs: Record; initialCurrentClusters: Cluster[]; // 用于获取桌面功能是否可用,如集群配置文件中没有配置则判断门户的配置文件,需要通过SSR进行传递 initialPortalRuntimeDesktopEnabled: boolean; @@ -284,7 +284,7 @@ MyApp.getInitialProps = async (appContext: AppContext) => { await api.getClustersRuntimeInfo({ query: { token } }).then((x) => x, () => undefined); const initialActivatedClusters = formatActivatedClusters({ clustersRuntimeInfo: currentClusters?.results, - configClusters: publicConfigClusters as Cluster[], + configClusters: publicConfigClusters, misDeployed: publicConfig.MIS_DEPLOYED }); extra.initialCurrentClusters = initialActivatedClusters.activatedClusters ?? []; diff --git a/apps/portal-web/src/pages/api/app/createAppSession.ts b/apps/portal-web/src/pages/api/app/createAppSession.ts index 123fd43360..83d918877b 100644 --- a/apps/portal-web/src/pages/api/app/createAppSession.ts +++ b/apps/portal-web/src/pages/api/app/createAppSession.ts @@ -124,14 +124,14 @@ export default /* #__PURE__*/route(CreateAppSessionSchema, async (req, res) => { const errors = parseErrorDetails(ex.metadata); if (errors[0] && errors[0].$type === "google.rpc.ErrorInfo") { switch (errors[0].reason) { - case "SBATCH_FAILED": - return { 409: { code: "SBATCH_FAILED" as const, message: ex.details } }; - case "NOT FOUND": - return { 404: { code: "APP_NOT_FOUND" as const, message: ex.details } }; - case "INVALID ARGUMENT": - return { 400: { code: "INVALID_INPUT" as const, message: ex.details } }; - default: - return e; + case "SBATCH_FAILED": + return { 409: { code: "SBATCH_FAILED" as const, message: ex.details } }; + case "NOT FOUND": + return { 404: { code: "APP_NOT_FOUND" as const, message: ex.details } }; + case "INVALID ARGUMENT": + return { 400: { code: "INVALID_INPUT" as const, message: ex.details } }; + default: + return e; } } else { throw e; diff --git a/apps/portal-web/src/pages/api/app/getAppSessions.ts b/apps/portal-web/src/pages/api/app/getAppSessions.ts index 74169aebb6..97659d0afc 100644 --- a/apps/portal-web/src/pages/api/app/getAppSessions.ts +++ b/apps/portal-web/src/pages/api/app/getAppSessions.ts @@ -33,7 +33,7 @@ export const AppSession = Type.Object({ host: Type.Optional(Type.String()), port: Type.Optional(Type.Number()), }); -export type AppSession = Static +export type AppSession = Static; export const GetAppSessionsSchema = typeboxRouteSchema({ method: "GET", diff --git a/apps/portal-web/src/pages/api/profile/changePassword.ts b/apps/portal-web/src/pages/api/profile/changePassword.ts index e4b77a3fd3..dcc07c3619 100644 --- a/apps/portal-web/src/pages/api/profile/changePassword.ts +++ b/apps/portal-web/src/pages/api/profile/changePassword.ts @@ -75,12 +75,12 @@ export default typeboxRoute(ChangePasswordSchema, async (req, res) => { .then(() => ({ 204: null })) .catch((e) => { switch (e.status) { - case "NOT_FOUND": - return { 404: null }; - case "NOT_SUPPORTED": - return { 501: null }; - default: - throw e; + case "NOT_FOUND": + return { 404: null }; + case "NOT_SUPPORTED": + return { 501: null }; + default: + throw e; } }); diff --git a/apps/portal-web/src/pages/api/profile/checkPassword.ts b/apps/portal-web/src/pages/api/profile/checkPassword.ts index 7ca3170e78..acc2a75470 100644 --- a/apps/portal-web/src/pages/api/profile/checkPassword.ts +++ b/apps/portal-web/src/pages/api/profile/checkPassword.ts @@ -61,10 +61,10 @@ export default typeboxRoute(CheckPasswordSchema, async (req, res) => { }) .catch((e) => { switch (e.status) { - case "NOT_SUPPORTED": - return { 501: null }; - default: - throw e; + case "NOT_SUPPORTED": + return { 501: null }; + default: + throw e; } }); }); diff --git a/apps/portal-web/src/pages/dashboard.tsx b/apps/portal-web/src/pages/dashboard.tsx index 9c575803ef..50184a0285 100644 --- a/apps/portal-web/src/pages/dashboard.tsx +++ b/apps/portal-web/src/pages/dashboard.tsx @@ -33,7 +33,7 @@ interface Props { } interface FulfilledResult { - clusterInfo: {clusterName: string, partitions: PartitionInfo[]} + clusterInfo: { clusterName: string, partitions: PartitionInfo[] } } diff --git a/apps/portal-web/src/pages/desktop/index.tsx b/apps/portal-web/src/pages/desktop/index.tsx index 4102e38d8f..e8401dc74c 100644 --- a/apps/portal-web/src/pages/desktop/index.tsx +++ b/apps/portal-web/src/pages/desktop/index.tsx @@ -35,28 +35,28 @@ type Props = { loginDesktopEnabledClusters: Cluster[]; }; -export const DesktopIndexPage: NextPage = requireAuth(() => true) -((props: Props) => { - - if ("error" in props) { - return ; - } - - const { enableLoginDesktop } = useStore(ClusterInfoStore); - if (!enableLoginDesktop || props.loginDesktopEnabledClusters.length === 0) { - return ; - } - - const t = useI18nTranslateToString(); - - return ( -
- - - -
- ); -}); +export const DesktopIndexPage: NextPage = requireAuth(() => true)( + (props: Props) => { + + if ("error" in props) { + return ; + } + + const { enableLoginDesktop } = useStore(ClusterInfoStore); + if (!enableLoginDesktop || props.loginDesktopEnabledClusters.length === 0) { + return ; + } + + const t = useI18nTranslateToString(); + + return ( +
+ + + +
+ ); + }); export const getServerSideProps: GetServerSideProps = async ({ req }) => { diff --git a/apps/portal-web/src/pages/files/[cluster]/[[...path]].tsx b/apps/portal-web/src/pages/files/[cluster]/[[...path]].tsx index 65748f4dec..aa18d31952 100644 --- a/apps/portal-web/src/pages/files/[cluster]/[[...path]].tsx +++ b/apps/portal-web/src/pages/files/[cluster]/[[...path]].tsx @@ -37,7 +37,7 @@ export const FileManagerPage: NextPage = requireAuth(() => true)(() => { const clusterObj = currentClusters.find((x) => x.id === cluster); - const fullPath = "/" + pathParts?.join("/") ?? ""; + const fullPath = "/" + (pathParts?.join("/") ?? ""); if (!clusterObj) { return ( diff --git a/apps/portal-web/src/server/operationLog.ts b/apps/portal-web/src/server/operationLog.ts index daa2f4b8a1..8104487da3 100644 --- a/apps/portal-web/src/server/operationLog.ts +++ b/apps/portal-web/src/server/operationLog.ts @@ -15,7 +15,7 @@ import { createOperationLogClient, import { runtimeConfig } from "src/utils/config"; interface PartialLogCallParams - extends Omit, "operationResult" | "logger"> {} + extends Omit, "operationResult" | "logger"> {} export const callLog = async ( { diff --git a/apps/portal-web/src/server/setup/proxy.ts b/apps/portal-web/src/server/setup/proxy.ts index b2a7685ec0..4b70dd4e0f 100644 --- a/apps/portal-web/src/server/setup/proxy.ts +++ b/apps/portal-web/src/server/setup/proxy.ts @@ -83,7 +83,7 @@ export const proxy = httpProxy.createServer(); export const setupWssProxy = (req: NextApiRequest) => { (req.socket as any).server.on("upgrade", async (req, socket, head) => { - const url = normalizePathnameWithQuery(req.url!); + const url = normalizePathnameWithQuery(req.url); if (!url.startsWith(join(publicConfig.BASE_PATH, "/api/proxy"))) { return; @@ -106,7 +106,7 @@ export const setupWssProxy = (req: NextApiRequest) => { const clusterConfigs = await getClusterConfigFiles(); // req.url of raw node.js request object doesn't remove base path - const target = parseProxyTarget(req.url!, true, clusterConfigs); + const target = parseProxyTarget(req.url, true, clusterConfigs); if (target instanceof Error) { writeError("400 Bad Request", target.message); diff --git a/apps/portal-web/src/server/setup/shell.ts b/apps/portal-web/src/server/setup/shell.ts index 065ddf350d..7ce22056b0 100644 --- a/apps/portal-web/src/server/setup/shell.ts +++ b/apps/portal-web/src/server/setup/shell.ts @@ -28,23 +28,23 @@ import { WebSocket, WebSocketServer } from "ws"; import { getClusterConfigFiles } from "../clusterConfig"; -export type ShellQuery = { +export interface ShellQuery { cluster: string; loginNode: string; path?: string; cols?: string; rows?: string; -} +}; export type ShellInputData = | { $case: "resize", resize: { cols: number; rows: number } } - | { $case: "data", data: { data: string }} + | { $case: "data", data: { data: string } } | { $case: "disconnect" } ; export type ShellOutputData = | { $case: "data", data: { data: string } } - | { $case: "exit", exit: { code?: number; signal?: string }} + | { $case: "exit", exit: { code?: number; signal?: string } } ; export const config = { api: { @@ -156,29 +156,32 @@ wss.on("connection", async (ws: AliveCheckedWebSocket, req) => { stream.on("data", (chunk: ShellResponse) => { switch (chunk.message?.$case) { - case "data": - send({ $case: "data", data: { data: chunk.message.data.data.toString() } }); - break; - case "exit": - send({ $case: "exit", exit: { code: chunk.message.exit.code, signal: chunk.message.exit.signal } }); - break; + case "data": + send({ $case: "data", data: { data: chunk.message.data.data.toString() } }); + break; + case "exit": + send({ $case: "exit", exit: { code: chunk.message.exit.code, signal: chunk.message.exit.signal } }); + break; } }); ws.on("message", (data) => { + // eslint-disable-next-line @typescript-eslint/no-base-to-string const message = JSON.parse(data.toString()) as ShellInputData; switch (message.$case) { - case "data": - stream.write({ message: { $case :"data", data: { data: Buffer.from(message.data.data) } } }); - break; - case "resize": - stream.write({ message: { $case: "resize", resize: { cols: message.resize.cols, rows: message.resize.rows } } }); - break; - case "disconnect": - stream.write({ message: { $case: "disconnect", disconnect: {} } }); - stream.end(); - break; + case "data": + stream.write({ message: { $case :"data", data: { data: Buffer.from(message.data.data) } } }); + break; + case "resize": + stream.write({ message: { $case: "resize", resize: { + cols: message.resize.cols, rows: message.resize.rows, + } } }); + break; + case "disconnect": + stream.write({ message: { $case: "disconnect", disconnect: {} } }); + stream.end(); + break; } }); @@ -201,7 +204,7 @@ wss.on("connection", async (ws: AliveCheckedWebSocket, req) => { export const setupShellServer = (req: NextApiRequest) => { (req.socket as any).server.on("upgrade", (request, socket, head) => { - const url = normalizePathnameWithQuery(request.url!); + const url = normalizePathnameWithQuery(request.url); if (!url.startsWith(join(publicConfig.BASE_PATH, "/api/shell"))) { return; } diff --git a/apps/portal-web/src/stores/ClusterInfoStore.ts b/apps/portal-web/src/stores/ClusterInfoStore.ts index 92abb76c07..5090948cb5 100644 --- a/apps/portal-web/src/stores/ClusterInfoStore.ts +++ b/apps/portal-web/src/stores/ClusterInfoStore.ts @@ -20,7 +20,7 @@ import { publicConfig } from "src/utils/config"; const SCOW_DEFAULT_CLUSTER_ID = "SCOW_DEFAULT_CLUSTER_ID"; export function ClusterInfoStore( - clusterConfigs: {[clusterId: string]: ClusterConfigSchema}, + clusterConfigs: Record, initialCurrentClusters: Cluster[], // 用于获取桌面功能是否可用,如集群配置文件中没有配置则判断门户的配置文件 portalRuntimeDesktopEnabled: boolean, @@ -40,7 +40,7 @@ export function ClusterInfoStore( return currentClusters.find((c) => c.id === x); }); - const [clusterId, setClusterId] = useLocalStorage( + const [clusterId, setClusterId] = useLocalStorage( SCOW_DEFAULT_CLUSTER_ID, initialDefaultClusterId || "", ); diff --git a/apps/portal-web/src/utils/cluster.ts b/apps/portal-web/src/utils/cluster.ts index f0b3ceee9e..97499206bf 100644 --- a/apps/portal-web/src/utils/cluster.ts +++ b/apps/portal-web/src/utils/cluster.ts @@ -52,7 +52,7 @@ export function getFileTransferEnabled( return fileTransferEnabled; } -export type Cluster = { id: string; name: I18nStringType; } +export interface Cluster { id: string; name: I18nStringType; }; export const getLoginDesktopEnabled = ( cluster: string, clusterConfigs: Record): boolean => { @@ -64,7 +64,7 @@ export const getLoginDesktopEnabled = ( return clusterLoginDesktopEnabled === undefined ? commonLoginDesktopEnabled : clusterLoginDesktopEnabled; }; -export type LoginNode = { name: string, address: string } +export interface LoginNode { name: string, address: string }; export const getClusterName = (clusterId: string, languageId: string, publicConfigClusters: Cluster[]) => { diff --git a/apps/portal-web/src/utils/config.ts b/apps/portal-web/src/utils/config.ts index 1cbbe5093f..f865105853 100644 --- a/apps/portal-web/src/utils/config.ts +++ b/apps/portal-web/src/utils/config.ts @@ -97,13 +97,13 @@ export interface PublicRuntimeConfig { export const runtimeConfig: ServerRuntimeConfig = getConfig().serverRuntimeConfig; export const publicConfig: PublicRuntimeConfig = getConfig().publicRuntimeConfig; -export type NavLink = { +export interface NavLink { text: string; url?: string; openInNewPage?: boolean; iconPath?: string; children?: (Omit & { url: string })[]; -} +}; type ServerI18nConfigKeys = keyof typeof runtimeConfig.SERVER_I18N_CONFIG_TEXTS; // 获取ServerConfig中相关字符串配置的对应语言的字符串 @@ -137,7 +137,7 @@ export const getRuntimeI18nConfigText = ( * @returns string | undefined * i18n语言文本 */ -export const getI18nText = ( +export const getI18nText = ( obj: TObject, key: TKey, languageId: string, ): (TObject[TKey] extends I18nStringType ? string : (string | undefined)) => { const value = obj[key]; diff --git a/apps/portal-web/src/utils/dashboard.ts b/apps/portal-web/src/utils/dashboard.ts index 240d7c2be5..29d92c640a 100644 --- a/apps/portal-web/src/utils/dashboard.ts +++ b/apps/portal-web/src/utils/dashboard.ts @@ -14,7 +14,7 @@ import { Cluster } from "@scow/config/build/type"; import { getI18nConfigCurrentText } from "@scow/lib-web/build/utils/systemLanguage"; import { Entry } from "@scow/protos/build/portal/dashboard"; import { SortOrder } from "antd/lib/table/interface"; -import { useI18nTranslateToString } from "src/i18n"; +import { type useI18nTranslateToString } from "src/i18n"; import { AppWithCluster } from "src/pageComponents/dashboard/QuickEntry"; export const formatEntryId = (item: Entry) => { @@ -81,7 +81,7 @@ export const getEntryExtraInfo = (item: Entry, currentLanguageId: string, public return []; }; -export const getEntryClusterName = (item: Entry["entry"] & {$case: "app" | "shell" } +export const getEntryClusterName = (item: Entry["entry"] & { $case: "app" | "shell" } , publicConfigClusters: Cluster[]) => { const clusters = publicConfigClusters; @@ -107,7 +107,7 @@ export const getEntryLogoPath = (item: Entry, apps: AppWithCluster) => { }; export const compareWithUndefined = - (a: T, b: T, sortOrder?: SortOrder): number => { +(a: T, b: T, sortOrder?: SortOrder): number => { if (a === undefined && b === undefined) { // 两者均为 undefined,视为相等 return 0; diff --git a/apps/portal-web/src/utils/isPortReachable.ts b/apps/portal-web/src/utils/isPortReachable.ts index 0409bbc452..9c1995f3fa 100644 --- a/apps/portal-web/src/utils/isPortReachable.ts +++ b/apps/portal-web/src/utils/isPortReachable.ts @@ -22,9 +22,9 @@ export async function isPortReachable(port: number, host: string, timeout: numbe const promise = new Promise((resolve, reject) => { const socket = new net.Socket(); - const onError = () => { + const onError = (error: Error) => { socket.destroy(); - reject(); + reject(error); }; socket.setTimeout(timeout); diff --git a/apps/portal-web/src/utils/route.ts b/apps/portal-web/src/utils/route.ts index efb43a3583..f7cdba7d40 100644 --- a/apps/portal-web/src/utils/route.ts +++ b/apps/portal-web/src/utils/route.ts @@ -38,13 +38,13 @@ export const route: typeof typeboxRoute = (schema, handler) => { const clusterErrorsString = e.metadata.get("clusterErrors") ?? undefined; const clusterErrorsArray = clusterErrorsString && clusterErrorsString.length > 0 ? - JSON.parse(clusterErrorsString) as ClusterErrorMetadata[] : undefined; + JSON.parse(clusterErrorsString) as ClusterErrorMetadata[] : undefined; // 如果包含当前在线集群的信息 const currentActivatedClusterIdsStr = e.metadata.get("currentActivatedClusterIds") ?? undefined; const currentActivatedClusterIds = currentActivatedClusterIdsStr && currentActivatedClusterIdsStr.length > 0 ? - JSON.parse(currentActivatedClusterIdsStr) as string[] : undefined; + JSON.parse(currentActivatedClusterIdsStr) as string[] : undefined; return { 500: { code, details, message, clusterErrorsArray, currentActivatedClusterIds } } as any; }); diff --git a/apps/portal-web/src/utils/server.ts b/apps/portal-web/src/utils/server.ts index 8d2a9c6eb0..f18e8df3ec 100644 --- a/apps/portal-web/src/utils/server.ts +++ b/apps/portal-web/src/utils/server.ts @@ -22,15 +22,15 @@ export const handlegRPCError = void, // @ts-ignore ) => (e: ServiceError): ReturnType> => { - logHandle?.(); - const handler = handlers[e.code]; - if (handler) { - // @ts-ignore - return handler(e) as ReturnType>; - } else { - throw e; - } - }; + logHandle?.(); + const handler = handlers[e.code]; + if (handler) { + // @ts-ignore + return handler(e) as ReturnType>; + } else { + throw e; + } +}; export const parseIp = (req: NextApiRequest | IncomingMessage): string | undefined => { diff --git a/apps/portal-web/src/utils/staticFiles.ts b/apps/portal-web/src/utils/staticFiles.ts index ae46d1bb9e..8d14d6f33d 100644 --- a/apps/portal-web/src/utils/staticFiles.ts +++ b/apps/portal-web/src/utils/staticFiles.ts @@ -15,7 +15,7 @@ import { nonEditableExtensions } from "src/utils/nonEditableExtensions"; export function basename(path: string) { - const parts = path.split(/[\/\\]/); + const parts = path.split(/[/\\]/); return parts[parts.length - 1]; } diff --git a/libs/web/eslint.config.js b/libs/web/eslint.config.js new file mode 100644 index 0000000000..4cea25ff4a --- /dev/null +++ b/libs/web/eslint.config.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy + * SCOW is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +const base = require("../../eslint.config"); +const react = require("@ddadaal/eslint-config/react"); + +module.exports = [ + ...base, + ...react, + { + rules: { + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-unsafe-enum-comparison": "off", + "@typescript-eslint/no-misused-promises": "off", + "@typescript-eslint/only-throw-error": "off", + } + } +]; diff --git a/libs/web/package.json b/libs/web/package.json index 929f0191db..7c379c430f 100644 --- a/libs/web/package.json +++ b/libs/web/package.json @@ -8,7 +8,7 @@ "scripts": { "dev": "tsc -p tsconfig.build.json && (concurrently \"tsc -p tsconfig.build.json -w\" \"tsc-alias -p tsconfig.build.json -w\")", "build": "rimraf build && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json", - "lint": "eslint -c ../../eslint.config.js ." + "lint": "eslint ." }, "files": [ "build", diff --git a/libs/web/src/layouts/AppFloatButtons.tsx b/libs/web/src/layouts/AppFloatButtons.tsx index 02eb8592c2..4046f03d24 100644 --- a/libs/web/src/layouts/AppFloatButtons.tsx +++ b/libs/web/src/layouts/AppFloatButtons.tsx @@ -18,7 +18,7 @@ export const AppFloatButtons = ({ darkModeButtonProps }: { }) => { return ( - + ); diff --git a/libs/web/src/layouts/base/BaseLayout.tsx b/libs/web/src/layouts/base/BaseLayout.tsx index 579ad52210..16ebaadff2 100644 --- a/libs/web/src/layouts/base/BaseLayout.tsx +++ b/libs/web/src/layouts/base/BaseLayout.tsx @@ -195,7 +195,7 @@ export const BaseLayout: React.FC> = ({ {children} -
+
diff --git a/libs/web/src/layouts/base/Footer.tsx b/libs/web/src/layouts/base/Footer.tsx index 3eb2b7ec69..1160237ca7 100644 --- a/libs/web/src/layouts/base/Footer.tsx +++ b/libs/web/src/layouts/base/Footer.tsx @@ -51,7 +51,8 @@ export const Footer: React.FC = ({ text, versionTag }) => { <> + dangerouslySetInnerHTML={{ __html: text }} + /> ) } diff --git a/libs/web/src/layouts/base/common.tsx b/libs/web/src/layouts/base/common.tsx index 0eae41b35d..1121c00623 100644 --- a/libs/web/src/layouts/base/common.tsx +++ b/libs/web/src/layouts/base/common.tsx @@ -62,7 +62,8 @@ export function createMenuItems( key: route.path, label: ( {route.text} diff --git a/libs/web/src/layouts/base/header/UserIcon.tsx b/libs/web/src/layouts/base/header/UserIcon.tsx index 308a18d875..d05018f212 100644 --- a/libs/web/src/layouts/base/header/UserIcon.tsx +++ b/libs/web/src/layouts/base/header/UserIcon.tsx @@ -15,9 +15,14 @@ import React, { LegacyRef } from "react"; const userSVG = () => ( - - + + ); diff --git a/libs/web/src/layouts/base/header/UserIndicator.tsx b/libs/web/src/layouts/base/header/UserIndicator.tsx index efc5817e35..07124bea32 100644 --- a/libs/web/src/layouts/base/header/UserIndicator.tsx +++ b/libs/web/src/layouts/base/header/UserIndicator.tsx @@ -73,13 +73,17 @@ export const UserIndicator: React.FC = ({ ...userLinks ? userLinks.map((link) => { return ({ key: link.text, - label: EXTERNAL_URL_PREFIX.some((pref) => link.url.startsWith(pref)) ? {link.text} : {link.text}, + label: EXTERNAL_URL_PREFIX.some((pref) => link.url.startsWith(pref)) ? ( + {link.text} + ) : ( + {link.text} + ), }); }) : [], { key: "logout", diff --git a/libs/web/src/layouts/base/header/index.tsx b/libs/web/src/layouts/base/header/index.tsx index 8cbbf87175..30e57b74f7 100644 --- a/libs/web/src/layouts/base/header/index.tsx +++ b/libs/web/src/layouts/base/header/index.tsx @@ -122,7 +122,7 @@ export const Header: React.FC = ({ {React.createElement( sidebarCollapsed ? MenuUnfoldOutlined : MenuFoldOutlined)} - ) : + ) : } @@ -140,7 +140,7 @@ export const Header: React.FC = ({ {right} - + diff --git a/libs/web/src/layouts/icon.tsx b/libs/web/src/layouts/icon.tsx index 363e18ffce..d159bddbb7 100644 --- a/libs/web/src/layouts/icon.tsx +++ b/libs/web/src/layouts/icon.tsx @@ -32,7 +32,6 @@ export function NavIcon({ src, alt = "" }: Props) { {altName}=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -4409,8 +4409,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.0.0-alpha.39': - resolution: {integrity: sha512-5k+pwV91plJojHgZkWlq4/TQdOrnEaeSvt48V0m8iEwdMJqX/63BXYxy8BUOSghWcjp05s73vy9HJjovAKmHkQ==} + '@typescript-eslint/parser@8.0.0-alpha.41': + resolution: {integrity: sha512-7HMXwy/q/59ZASBXz2FtdIsR7LgABrR8j2dTKq9GMR8OkjjdO4klxWSY/uOBozVt4UxlMRYsBdBDhEq4/tHRiw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4423,12 +4423,12 @@ packages: resolution: {integrity: sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@8.0.0-alpha.39': - resolution: {integrity: sha512-HCBlKQROY+JIgWolucdFMj1W3VUnnIQTdxAhxJTAj3ix2nASmvKIFgrdo5KQMrXxQj6tC4l3zva10L+s0dUIIw==} + '@typescript-eslint/scope-manager@8.0.0-alpha.41': + resolution: {integrity: sha512-iNxuQ0TMVfFiMJ2al4bGd/mY9+aLtBxnHfo7B2xoVzR6cRFgUdBLlMa//MSIjSmVRpCEqNLQnkxpJb96tFG+xw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.0.0-alpha.39': - resolution: {integrity: sha512-alO13fRU6yVeJbwl9ESI3AYhq5dQdz3Dpd0I5B4uezs2lvgYp44dZsj5hWyPz/kL7JFEsjbn+4b/CZA0OQJzjA==} + '@typescript-eslint/type-utils@8.0.0-alpha.41': + resolution: {integrity: sha512-+QIA1z/jrox6bbvqlyqBQjotpevieLTycfiuoKuqGcKoskFZV5Rma51BV8LCJacnOafwJtSi+7b8zDo8OsXUvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -4440,8 +4440,8 @@ packages: resolution: {integrity: sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@8.0.0-alpha.39': - resolution: {integrity: sha512-yINN7j0/+S1VGSp0IgH52oQvUx49vkOug6xbrDA/9o+U55yCAQKSvYWvzYjNa+SZE3hXI0zwvYtMVsIAAMmKIQ==} + '@typescript-eslint/types@8.0.0-alpha.41': + resolution: {integrity: sha512-n0P2FP3YC3pD3yoiCf4lHqbUP45xlnOk8HkjB+LtKSUZZWLLJ8k1ZXZtQj7MEX22tytCMj//Bmq403xFuCwfIg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@7.13.1': @@ -4453,8 +4453,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.0.0-alpha.39': - resolution: {integrity: sha512-S8gREuP8r8PCxGegeojeXntx0P50ul9YH7c7JYpbLIIsEPNr5f7UHlm+I1NUbL04CBin4kvZ60TG4eWr/KKN9A==} + '@typescript-eslint/typescript-estree@8.0.0-alpha.41': + resolution: {integrity: sha512-adCr+vbLYTFhwhIwjIjjMxTdUYiPA2Jlyuhnbj092IzgLHtT79bvuwcgPWeTyLbFb/13SMKmOEka00xHiqLpig==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -4468,8 +4468,8 @@ packages: peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/utils@8.0.0-alpha.39': - resolution: {integrity: sha512-Nr2PrlfNhrNQTlFHlD7XJdTGw/Vt8qY44irk6bfjn9LxGdSG5e4c1R2UN6kvGMhhx20DBPbM7q3Z3r+huzmL1w==} + '@typescript-eslint/utils@8.0.0-alpha.41': + resolution: {integrity: sha512-DTxc9VdERS6iloiw1P5tgRDqRArmp/sIuvgdHBvGh2SiltEFc3VjLGnHHGSTr6GfH7tjFWvcCnCtxx+pjWfp5Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4478,8 +4478,8 @@ packages: resolution: {integrity: sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.0.0-alpha.39': - resolution: {integrity: sha512-DVJ0UdhucZy+/1GlIy7FX2+CFhCeNAi4VwaEAe7u2UDenQr9/kGqvzx00UlpWibmEVDw4KsPOI7Aqa1+2Vqfmw==} + '@typescript-eslint/visitor-keys@8.0.0-alpha.41': + resolution: {integrity: sha512-uetCAUBVC+YarBdZnWzDDgX11PpAEGV8Cw31I3d1xNrhx6/bJGThKX+holEmd3amMdnr4w/XUKH/4YuQOgtjDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript/vfs@1.5.0': @@ -11393,8 +11393,8 @@ packages: types-ramda@0.30.0: resolution: {integrity: sha512-oVPw/KHB5M0Du0txTEKKM8xZOG9cZBRdCVXvwHYuNJUVkAiJ9oWyqkA+9Bj2gjMsHgkkhsYevobQBWs8I2/Xvw==} - typescript-eslint@8.0.0-alpha.39: - resolution: {integrity: sha512-bsuR1BVJfHr7sBh7Cca962VPIcP+5UWaIa/+6PpnFZ+qtASjGTxKWIF5dG2o73BX9NsyqQfvRWujb3M9CIoRXA==} + typescript-eslint@8.0.0-alpha.41: + resolution: {integrity: sha512-+e7D2XDZeHLe9D3bP7S0Va8YdLHzn3YcesoxMS9SjMWhtaSb5ylxk2txqT84sUS0WIDQetZlvDg2/UmY5B/ycg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -13288,7 +13288,7 @@ snapshots: eslint: 9.6.0 eslint-plugin-simple-import-sort: 12.1.1(eslint@9.6.0) globals: 15.8.0 - typescript-eslint: 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2) + typescript-eslint: 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2) optionalDependencies: eslint-plugin-react: 7.34.3(eslint@9.6.0) transitivePeerDependencies: @@ -16524,14 +16524,14 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.0.0-alpha.39(@typescript-eslint/parser@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2))(eslint@9.6.0)(typescript@5.5.2)': + '@typescript-eslint/eslint-plugin@8.0.0-alpha.41(@typescript-eslint/parser@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2))(eslint@9.6.0)(typescript@5.5.2)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2) - '@typescript-eslint/scope-manager': 8.0.0-alpha.39 - '@typescript-eslint/type-utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2) - '@typescript-eslint/utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2) - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 + '@typescript-eslint/parser': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2) + '@typescript-eslint/scope-manager': 8.0.0-alpha.41 + '@typescript-eslint/type-utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2) + '@typescript-eslint/utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2) + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 eslint: 9.6.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -16542,12 +16542,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2)': + '@typescript-eslint/parser@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2)': dependencies: - '@typescript-eslint/scope-manager': 8.0.0-alpha.39 - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/typescript-estree': 8.0.0-alpha.39(typescript@5.5.2) - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 + '@typescript-eslint/scope-manager': 8.0.0-alpha.41 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/typescript-estree': 8.0.0-alpha.41(typescript@5.5.2) + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 debug: 4.3.4(supports-color@5.5.0) eslint: 9.6.0 optionalDependencies: @@ -16560,15 +16560,15 @@ snapshots: '@typescript-eslint/types': 7.13.1 '@typescript-eslint/visitor-keys': 7.13.1 - '@typescript-eslint/scope-manager@8.0.0-alpha.39': + '@typescript-eslint/scope-manager@8.0.0-alpha.41': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 - '@typescript-eslint/type-utils@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2)': + '@typescript-eslint/type-utils@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2)': dependencies: - '@typescript-eslint/typescript-estree': 8.0.0-alpha.39(typescript@5.5.2) - '@typescript-eslint/utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2) + '@typescript-eslint/typescript-estree': 8.0.0-alpha.41(typescript@5.5.2) + '@typescript-eslint/utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2) debug: 4.3.4(supports-color@5.5.0) ts-api-utils: 1.3.0(typescript@5.5.2) optionalDependencies: @@ -16579,7 +16579,7 @@ snapshots: '@typescript-eslint/types@7.13.1': {} - '@typescript-eslint/types@8.0.0-alpha.39': {} + '@typescript-eslint/types@8.0.0-alpha.41': {} '@typescript-eslint/typescript-estree@7.13.1(typescript@5.5.2)': dependencies: @@ -16596,10 +16596,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.0.0-alpha.39(typescript@5.5.2)': + '@typescript-eslint/typescript-estree@8.0.0-alpha.41(typescript@5.5.2)': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/visitor-keys': 8.0.0-alpha.39 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/visitor-keys': 8.0.0-alpha.41 debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 @@ -16622,12 +16622,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2)': + '@typescript-eslint/utils@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.6.0) - '@typescript-eslint/scope-manager': 8.0.0-alpha.39 - '@typescript-eslint/types': 8.0.0-alpha.39 - '@typescript-eslint/typescript-estree': 8.0.0-alpha.39(typescript@5.5.2) + '@typescript-eslint/scope-manager': 8.0.0-alpha.41 + '@typescript-eslint/types': 8.0.0-alpha.41 + '@typescript-eslint/typescript-estree': 8.0.0-alpha.41(typescript@5.5.2) eslint: 9.6.0 transitivePeerDependencies: - supports-color @@ -16638,9 +16638,9 @@ snapshots: '@typescript-eslint/types': 7.13.1 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.0.0-alpha.39': + '@typescript-eslint/visitor-keys@8.0.0-alpha.41': dependencies: - '@typescript-eslint/types': 8.0.0-alpha.39 + '@typescript-eslint/types': 8.0.0-alpha.41 eslint-visitor-keys: 3.4.3 '@typescript/vfs@1.5.0': @@ -24984,11 +24984,11 @@ snapshots: dependencies: ts-toolbelt: 9.6.0 - typescript-eslint@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2): + typescript-eslint@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.0.0-alpha.39(@typescript-eslint/parser@8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2))(eslint@9.6.0)(typescript@5.5.2) - '@typescript-eslint/parser': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2) - '@typescript-eslint/utils': 8.0.0-alpha.39(eslint@9.6.0)(typescript@5.5.2) + '@typescript-eslint/eslint-plugin': 8.0.0-alpha.41(@typescript-eslint/parser@8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2))(eslint@9.6.0)(typescript@5.5.2) + '@typescript-eslint/parser': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2) + '@typescript-eslint/utils': 8.0.0-alpha.41(eslint@9.6.0)(typescript@5.5.2) optionalDependencies: typescript: 5.5.2 transitivePeerDependencies: