Skip to content
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@

# misc
**/.DS_Store
**/.env.local
**/.env.development.local
**/.env.test.local
**/.env.production.local

**/npm-debug.log*
**/yarn-debug.log*
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ yarn-error.log*
.vscode/*
.idea
stats.html
/public/moeflow-runtime-config.json
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
locale-json: src/locales/en.json src/locales/zh-cn.json

locale-json-watch:
watch make locale-json

format:
npm run format:fix

src/locales/en.json: src/locales/messages.yaml
node_modules/.bin/tsx scripts/generate-locale-json.ts

src/locales/zh-cn.json: src/locales/messages.yaml
node_modules/.bin/tsx scripts/generate-locale-json.ts

63 changes: 2 additions & 61 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@fortawesome/free-regular-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.19",
"@gradio/client": "1.14.0",
"@gradio/client": "^1.14.0",
"@jokester/ts-commonutil": "^0.6.1",
"@reduxjs/toolkit": "^1.9.7",
"@zip.js/zip.js": "^2.7.60",
Expand Down
7 changes: 7 additions & 0 deletions public/moeflow-runtime-config.sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"comment": "Runtime configuration overrides. See src/configs.tsx",
"moeflowCompanion": {
"gradioUrl": "http://localhost:7860",
"defaultMultimodalModel": "gemini-2.0-flash-lite"
}
}
2 changes: 1 addition & 1 deletion src/apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import axios, {
import qs from 'qs';
import { createElement } from 'react';
import { Icon } from '../components';
import { configs, runtimeConfig } from '@/configs';
import { runtimeConfig } from '@/configs';
import { createDebugLogger } from '@/utils/debug-logger';
import { getIntl } from '@/locales';
import store from '../store';
Expand Down
2 changes: 1 addition & 1 deletion src/components/ApplicationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import { formatGroupType } from '@/utils/i18n';
import { clickEffect } from '@/utils/style';
import { can } from '@/utils/user';
import { Spin } from './Spin';
import { Spin } from './shared/Spin';

/** 申请管理页的属性接口 */
interface ApplicationListProps {
Expand Down Expand Up @@ -137,7 +137,7 @@
const handleChange = ({
page,
pageSize,
word,

Check warning on line 140 in src/components/ApplicationList.tsx

View workflow job for this annotation

GitHub Actions / check-pr

'word' is defined but never used
cancelToken,
}: {
page: number;
Expand All @@ -149,8 +149,8 @@
let getApplications;
if (type === 'group') {
getApplications = api.application.getApplications({
groupType: groupType!,

Check warning on line 152 in src/components/ApplicationList.tsx

View workflow job for this annotation

GitHub Actions / check-pr

Forbidden non-null assertion
groupID: currentGroup!.id,

Check warning on line 153 in src/components/ApplicationList.tsx

View workflow job for this annotation

GitHub Actions / check-pr

Forbidden non-null assertion
params: {
page,
limit: pageSize,
Expand Down
2 changes: 1 addition & 1 deletion src/components/AuthLoginedTip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from 'react';
import { useIntl } from 'react-intl';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router';
import { Avatar } from './Avatar';
import { Avatar } from './shared/Avatar';
import { AppState } from '../store';
import { setUserToken } from '../store/user/slice';
import style from '../style';
Expand Down
12 changes: 6 additions & 6 deletions src/components/CAPTCHAInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import classNames from 'classnames';
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
import { useIntl } from 'react-intl';
import api from '../apis';
import { LoadingIcon } from './LoadingIcon';
import { getIntl } from '../locales';
import style from '../style';
import { getCancelToken } from '../utils/api';
import { clickEffect, imageClickEffect } from '../utils/style';
import api from '@/apis';
import { LoadingIcon } from '@/components';
import { getIntl } from '@/locales';
import style from '@/style';
import { getCancelToken } from '@/utils/api';
import { clickEffect, imageClickEffect } from '@/utils/style';

/** 用于 Form.Item 校验验证码,rules={[{validator: checkCAPTCHA}]} */
export const checkCAPTCHA = (rule: any, captcha: CAPTCHAInputValue) => {

Check warning on line 15 in src/components/CAPTCHAInput.tsx

View workflow job for this annotation

GitHub Actions / check-pr

Unexpected any. Specify a different type
const intl = getIntl();
if (captcha.value === '') {
return Promise.reject(intl.formatMessage({ id: 'form.required' }));
Expand Down
2 changes: 1 addition & 1 deletion src/components/InvitationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { toLowerCamelCase } from '../utils';
import { getCancelToken } from '../utils/api';
import { FC } from '../interfaces';
import { clickEffect } from '../utils/style';
import { Spin } from './Spin';
import { Spin } from './shared/Spin';
import { INVITATION_STATUS } from '../constants';

const { Option } = Select;
Expand Down
4 changes: 2 additions & 2 deletions src/components/InviteUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { FC, Role, Project, UserTeam } from '../interfaces';
import style from '../style';
import { toLowerCamelCase } from '../utils';
import { getCancelToken } from '../utils/api';
import { Spin } from './Spin';
import { LIST_ITEM_DEFAULT_HEIGHT } from './ListItem';
import { Spin } from './shared/Spin';
import { LIST_ITEM_DEFAULT_HEIGHT } from '@/components/shared/ListItem';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Spin and ListItem constant imports updated to shared modules.

All good. If migrating fully to antd v5 (Modal/Drawer use open), plan to replace SelectValue with SelectProps['value'] to avoid internal imports.


🏁 Script executed:

#!/bin/bash
# Find internal antd type imports to modernize
rg -nP "from ['\"]/antd/(lib|es)/select['\"]|SelectValue\b" src

Length of output: 564


Replace internal SelectValue imports with SelectProps['value'] across components
Remove import { SelectValue } from 'antd/lib/select' and replace with

import type { SelectProps } from 'antd';

Then update all onChange (and other) type annotations from SelectValue to SelectProps['value'] in:
• src/components/RoleSelect.tsx (line 3 import, line 46 annotation)
• src/components/InvitationList.tsx (line 4 import, line 294 annotation)
• src/components/InviteUser.tsx (line 4 import, line 197 annotation)

🤖 Prompt for AI Agents
In src/components/InviteUser.tsx around lines 16 to 18, replace the internal
SelectValue import with a typed import from antd and update usages: remove any
import of SelectValue, add import type { SelectProps } from 'antd'; then change
the onChange (and any other) type annotations that currently use SelectValue to
use SelectProps['value'] (specifically update the annotation at ~line 197). Also
ensure similar changes are applied in RoleSelect.tsx and InvitationList.tsx as
noted in the review (remove SelectValue import, add import type { SelectProps }
from 'antd', and replace SelectValue annotations with SelectProps['value']).

const { Option } = Select;

Expand Down
2 changes: 1 addition & 1 deletion src/components/MemberList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import style from '../style';
import { toLowerCamelCase } from '../utils';
import { getCancelToken } from '../utils/api';
import { can } from '../utils/user';
import { Spin } from './Spin';
import { Spin } from './shared/Spin';
import { TypeData } from './TypeRadioGroup';

/** 成员设置页的属性接口 */
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProjectSetList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from '../store/projectSet/slice';
import { toLowerCamelCase } from '../utils';
import { can } from '../utils/user';
import { LIST_ITEM_DEFAULT_HEIGHT } from './ListItem';
import { LIST_ITEM_DEFAULT_HEIGHT } from '@/components/shared/ListItem';

/** 项目集的属性接口 */
interface ProjectSetListProps {
Expand Down
4 changes: 2 additions & 2 deletions src/components/TeamInsightProjectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
Tag,
message,
} from 'antd';
import { Button as CustomButton } from './Button';
import { Button as CustomButton } from './shared/Button';
import classNames from 'classnames';
import produce from 'immer';
import qs from 'qs';
Expand Down Expand Up @@ -324,7 +324,7 @@ export const TeamInsightProjectList: FC<TeamInsightProjectListProps> = ({
}}
/>
<Column
title={formatMessage({ id: 'site.output' })}
title={formatMessage({ id: 'project.export' })}
key="project"
width="30%"
Comment on lines +327 to 329

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Header i18n key updated to project.export — LGTM

Ensure the new key exists in locales to avoid runtime fallback.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
for f in src/locales/en.json src/locales/zh-cn.json; do
  jq -e '.project.export' "$f" >/dev/null || { echo "Missing project.export in $f"; exit 1; }
done
echo "OK: project.export present"

Length of output: 227


Add missing i18n key project.export to locale files
Add an entry for project.export in src/locales/en.json (and ensure it’s present in src/locales/zh-cn.json) to match the usage in TeamInsightProjectList.tsx and prevent runtime fallbacks.

🤖 Prompt for AI Agents
In src/components/TeamInsightProjectList.tsx around lines 327 to 329, the
component uses formatMessage({ id: 'project.export' }) but the i18n key is
missing from locale files; add "project.export": "<English label>" to
src/locales/en.json and the corresponding translated string to
src/locales/zh-cn.json (or its appropriate value) so the key exists and prevents
runtime fallback; keep key naming consistent and run the app or i18n lint to
verify correct loading.

render={(text, record: APIInsightProjectWithPage, index) => {
Expand Down
12 changes: 6 additions & 6 deletions src/components/TeamList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { useDispatch, useSelector } from 'react-redux';
import { matchPath, useHistory, useLocation } from 'react-router-dom';
import { Avatar, EmptyTip, Icon, List, ListItem } from '.';
import api, { resultTypes } from '../apis';
import { FC, UserTeam } from '../interfaces';
import { AppState } from '../store';
import { resetProjectSetsState } from '../store/projectSet/slice';
import { clearTeams, createTeam, setTeamsState } from '../store/team/slice';
import { toLowerCamelCase } from '../utils';
import { LIST_ITEM_DEFAULT_HEIGHT } from './ListItem';
import { FC, UserTeam } from '@/interfaces';
import { AppState } from '@/store';
import { resetProjectSetsState } from '@/store/projectSet/slice';
import { clearTeams, createTeam, setTeamsState } from '@/store/team/slice';
import { toLowerCamelCase } from '@/utils';
import { LIST_ITEM_DEFAULT_HEIGHT } from '@/components/shared/ListItem';

/** 团队列表的属性接口 */
interface TeamListProps {
Expand Down
2 changes: 1 addition & 1 deletion src/components/TeamSearchList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { createTeam } from '../store/team/slice';
import { toLowerCamelCase } from '../utils';
import { FC, UserTeam } from '../interfaces';
import { Team } from '../interfaces';
import { LIST_ITEM_DEFAULT_HEIGHT } from './ListItem';
import { LIST_ITEM_DEFAULT_HEIGHT } from '@/components/shared/ListItem';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Switch to shared ListItem constant is aligned with the alias move.

Looks good. Verify alias setup for "@/..." across TS, bundler, and tests, and that the constant remains a named export.


🏁 Script executed:

#!/bin/bash
# 1) TS path alias
rg -nP --glob 'tsconfig*.json' '"paths"\s*:\s*{[^}]*"@/\*"' -S

# 2) Bundler alias (vite/webpack/craco)
rg -nP '(alias|resolve\.alias).*@' -S

# 3) Jest/Vitest mapping
rg -nP 'moduleNameMapper|alias.*@' -S

# 4) Ensure named export exists
rg -nP "export\s+const\s+LIST_ITEM_DEFAULT_HEIGHT\b" src/components/shared/ListItem.tsx

# 5) (Optional) locate deprecated antd internal types to migrate off if using antd v5
rg -nP "antd/(lib|es)/select" -S

Length of output: 647


Alias configuration for @/ imports is missing
I didn’t find any @/* path mapping in tsconfig.json, your bundler config, or your test runner config—so

import { LIST_ITEM_DEFAULT_HEIGHT } from '@/components/shared/ListItem';

will fail. Add the @/* alias under compilerOptions.paths in tsconfig.json, configure resolve.alias in your bundler (e.g. vite.config.ts or webpack.config.js), and set up moduleNameMapper (Jest) or alias (Vitest). The export const LIST_ITEM_DEFAULT_HEIGHT = 45; remains correctly declared.

🤖 Prompt for AI Agents
In src/components/TeamSearchList.tsx around line 18 the import using the '@/...'
alias will fail because no path mapping is configured; add the '@/*' mapping
under compilerOptions.paths in tsconfig.json (pointing '@/*' to 'src/*'), add
the same alias to your bundler resolve.alias (e.g. vite.config.ts or
webpack.config.js) and add the equivalent mapping for your test runner
(moduleNameMapper for Jest or alias in Vitest) so imports like
'@/components/...' resolve correctly; keep the existing export of
LIST_ITEM_DEFAULT_HEIGHT as-is.


/** 搜索团队的属性接口 */
interface TeamSearchListProps {
Expand Down
2 changes: 1 addition & 1 deletion src/components/TeamSettingBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import style from '../style';
import { FC, UserTeam } from '../interfaces';
import { can } from '../utils/user';
import copy from 'copy-to-clipboard';
import { AvatarUpload } from './AvatarUpload';
import { AvatarUpload } from './shared/AvatarUpload';

/** 团队基础设置的属性接口 */
interface TeamSettingBaseProps {
Expand Down
2 changes: 1 addition & 1 deletion src/components/UserInvitationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { createTeam } from '../store/team/slice';
import style from '../style';
import { toLowerCamelCase } from '../utils';
import { clickEffect } from '../utils/style';
import { Spin } from './Spin';
import { Spin } from './shared/Spin';

/** 申请管理页的属性接口 */
interface UserInvitationListProps {
Expand Down
42 changes: 19 additions & 23 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export { Icon } from './icon';
export { ApplicationList } from './ApplicationList';
export { AuthFormWrapper } from './AuthFormWrapper';
export { AuthLoginedTip } from './AuthLoginedTip';
export { Avatar } from './Avatar';
export { Button } from './Button';
export { Avatar } from './shared/Avatar';
export { Button } from './shared/Button';
export { CAPTCHAInput } from './CAPTCHAInput';
export { CAPTCHAModal } from './CAPTCHAModal';
export { Content } from './Content';
Expand All @@ -12,44 +12,40 @@ export { ContentTitle } from './ContentTitle';
export { DashboardBox } from './DashboardBox';
export { DashboardMenu } from './DashboardMenu';
export { DebounceStatus } from './DebounceStatus';
export { Dropdown } from './Dropdown';
export { Dropdown } from './shared/Dropdown';
export { EmailInput } from './EmailInput';
export { EmailVCodeInputItem } from './EmailVCodeInputItem';
export { EmptyTip } from './EmptyTip';
export { FileCover } from './FileCover';
export { FileItem } from './FileItem';
export { FileList } from './FileList';
export { FileUploadProgress } from './FileUploadProgress';
export { FileList } from './project/FileList';
export { FileUploadProgress } from './project/FileUploadProgress';
export { Form } from './Form';
export { FormItem } from './FormItem';
export { GroupJoinForm } from './GroupJoinForm';
export { Header } from './Header';
export { Header } from './shared/Header';
export { useHotKey } from './HotKey';
export { ImageOCRProgress } from './ImageOCRProgress';
export { ImageOCRProgress } from './unused/ImageOCRProgress';
export { InvitationList } from './InvitationList';
export { InviteUser } from './InviteUser';
export { Label } from './Label';
export { LanguageSelect } from './LanguageSelect';
export { List } from './List';
export { ListItem, LIST_ITEM_DEFAULT_HEIGHT } from './ListItem';
export { ListSearchInput } from './ListSearchInput';
export { ListSkeletonItem } from './ListSkeletonItem';
export { LoadingIcon } from './LoadingIcon';
export { Label } from './shared/Label';
export { LanguageSelect } from './project/LanguageSelect';
export { List } from './shared/List';
export { ListItem, LIST_ITEM_DEFAULT_HEIGHT } from './shared/ListItem';
export { ListSearchInput } from './shared/ListSearchInput';
export { ListSkeletonItem } from './shared/ListSkeletonItem';
export { LoadingIcon } from './shared/LoadingIcon';
export { MemberList } from './MemberList';
export { MovableArea, MovableItem } from './Movable';
export { MovableArea, MovableItem } from './shared/Movable';
export { NavTab } from './NavTab';
export { NavTabs } from './NavTabs';
export { Output } from './Output';
export { OutputList } from './OutputList';
export { ProjectItem } from './ProjectItem';
export { ProjectList } from './ProjectList';
export { OutputList } from './project/OutputList';
export { ProjectList } from './project-list/ProjectList';
export { ProjectSetCreateForm } from './ProjectSetCreateForm';
export { ProjectSetEditForm } from './ProjectSetEditForm';
export { ProjectSetList } from './ProjectSetList';
export { ProjectSetSettingBase } from './ProjectSetSettingBase';
export { RoleRadioGroup } from './RoleRadioGroup';
export { RoleSelect } from './RoleSelect';
export { Spin } from './Spin';
export { Spin } from './shared/Spin';
export { TabBarM } from './TabBarM';
export { TeamCreateForm } from './TeamCreateForm';
export { TeamEditForm } from './TeamEditForm';
Expand All @@ -58,7 +54,7 @@ export { TeamInsightUserList } from './TeamInsightUserList';
export { TeamList } from './TeamList';
export { TeamSearchList } from './TeamSearchList';
export { TeamSettingBase } from './TeamSettingBase';
export { Tooltip } from './Tooltip';
export { Tooltip } from './shared/Tooltip';
export { TranslationProgress } from './TranslationProgress';
export { TypeRadioGroup } from './TypeRadioGroup';
export { UserEmailEditForm } from './UserEmailEditForm';
Expand Down
Loading
Loading