Updated npm commands, removed unused imports,

added key prop in Header.js, and introduced eslint
for linting
This commit is contained in:
cktsun1031 2023-11-06 21:08:03 +08:00
parent fa008e7196
commit d017e2de2b
26 changed files with 2669 additions and 37 deletions

43
.github/workflows/lint.yml vendored Normal file
View File

@ -0,0 +1,43 @@
name: Code Checking
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
jobs:
checking:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
cache: npm
node-version: 20
- uses: actions/setup-go@v4
with:
go-version: "stable"
- name: Test Build
env:
CI: ""
run: |
cd web
npm ci
npm run build
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
install-mode: binary
version: latest
- name: Test Build of Go
run: go build

View File

@ -14,6 +14,11 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
cache: npm
node-version: 20
- name: Translate
run: |
python ./i18n/translate.py --repository_path . --json_file_path ./i18n/en.json
@ -22,13 +27,13 @@ jobs:
CI: ""
run: |
cd web
npm install
npm ci
REACT_APP_VERSION=$(git describe --tags) npm run build
cd ..
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ">=1.18.0"
go-version: "stable"
- name: Build Backend (amd64)
run: |
go mod download

View File

@ -13,18 +13,24 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
cache: npm
node-version: 20
- name: Build Frontend
env:
CI: ""
run: |
cd web
npm install
npm ci
REACT_APP_VERSION=$(git describe --tags) npm run build
cd ..
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ">=1.18.0"
go-version: "stable"
- name: Build Backend (amd64)
run: |
go mod download

View File

@ -13,18 +13,24 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
cache: npm
node-version: 20
- name: Build Frontend
env:
CI: ""
run: |
cd web
npm install
npm ci
REACT_APP_VERSION=$(git describe --tags) npm run build
cd ..
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ">=1.18.0"
go-version: "stable"
- name: Build Backend
run: |
go mod download

View File

@ -16,18 +16,24 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
cache: npm
node-version: 20
- name: Build Frontend
env:
CI: ""
run: |
cd web
npm install
npm ci
REACT_APP_VERSION=$(git describe --tags) npm run build
cd ..
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ">=1.18.0"
go-version: "stable"
- name: Build Backend
run: |
go mod download

View File

@ -135,7 +135,7 @@ The initial account username is `root` and password is `123456`.
# Build the frontend
cd one-api/web
npm install
npm ci
npm run build
# Build the backend

View File

@ -136,7 +136,7 @@ sudo service nginx restart
# フロントエンドのビルド
cd one-api/web
npm install
npm ci
npm run build
# バックエンドのビルド

View File

@ -188,7 +188,7 @@ sudo service nginx restart
# 构建前端
cd one-api/web
npm install
npm ci
npm run build
# 构建后端

48
web/.eslintrc.json Normal file
View File

@ -0,0 +1,48 @@
{
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:react/recommended"
],
"plugins": [
"unused-imports",
"react",
"import"
],
"parserOptions": {
"ecmaVersion": 2023,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"es6": true,
"browser": true,
"node": true
},
"globals": {
"localStorage": true,
"fetch": true
},
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"react/prop-types": "off",
"react/react-in-jsx-scope": "off",
"no-unused-vars": "off", // or "@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
"vars": "all",
"varsIgnorePattern": "^_",
"args": "after-used",
"argsIgnorePattern": "^_"
}
]
}
}

2513
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,8 @@
},
"scripts": {
"start": "vite preview",
"build": "vite build"
"build": "npm run lint && vite build",
"lint": "eslint --ext .js,.jsx,.ts,.tsx src"
},
"eslintConfig": {
"extends": [
@ -42,6 +43,11 @@
]
},
"devDependencies": {
"eslint": "^8.53.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-unused-imports": "^3.0.0",
"prettier": "^3.0.3"
},
"prettier": {

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Input, Label, Message, Pagination, Popup, Table } from 'semantic-ui-react';
import { Button, Form, Input, Label, Pagination, Popup, Table } from 'semantic-ui-react';
import { Link } from 'react-router-dom';
import { API, setPromptShown, shouldShowPrompt, showError, showInfo, showSuccess, timestamp2string } from '../helpers';
import { API, showError, showInfo, showSuccess, timestamp2string } from '../helpers';
import { CHANNEL_OPTIONS, ITEMS_PER_PAGE } from '../constants';
import { renderGroup, renderNumber } from '../helpers/render';
@ -55,7 +55,6 @@ const ChannelsTable = () => {
const [searchKeyword, setSearchKeyword] = useState('');
const [searching, setSearching] = useState(false);
const [updatingBalance, setUpdatingBalance] = useState(false);
const [showPrompt, setShowPrompt] = useState(shouldShowPrompt("channel-test"));
const loadChannels = async (startIdx) => {
const res = await API.get(`/api/channel/?p=${startIdx}`);

View File

@ -101,6 +101,7 @@ const Header = () => {
if (isMobile) {
return (
<Menu.Item
key={button.name}
onClick={() => {
navigate(button.to);
setShowSidebar(false);

View File

@ -2,7 +2,7 @@ import React, { useContext, useEffect, useState } from 'react';
import { Button, Divider, Form, Grid, Header, Image, Message, Modal, Segment } from 'semantic-ui-react';
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { UserContext } from '../context/User';
import { API, getLogo, showError, showSuccess, showWarning } from '../helpers';
import { API, showInfo, getLogo, showError, showSuccess, showWarning } from '../helpers';
import Turnstile from 'react-turnstile';
import { onGitHubOAuthClicked } from './utils';
@ -21,8 +21,8 @@ const LoginForm = () => {
const [turnstileToken, setTurnstileToken] = useState('');
let navigate = useNavigate();
const [status, setStatus] = useState({});
const logo = getLogo();
const logo = getLogo();
useEffect(() => {
if (searchParams.get('expired')) {
showError('未登录或登录已过期,请重新登录!');

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Button, Divider, Form, Grid, Header, Message, Modal } from 'semantic-ui-react';
import { Button, Divider, Form, Grid, Header, Modal } from 'semantic-ui-react';
import { API, showError, showSuccess } from '../helpers';
import { marked } from 'marked';

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react';
import { API, copy, showError, showInfo, showNotice, showSuccess } from '../helpers';
import { API, copy, showError, showNotice } from '../helpers';
import { useSearchParams } from 'react-router-dom';
const PasswordResetConfirm = () => {

View File

@ -1,7 +1,7 @@
import React, { useContext, useEffect, useState } from 'react';
import { Button, Divider, Form, Header, Image, Message, Modal } from 'semantic-ui-react';
import { Link, useNavigate } from 'react-router-dom';
import { API, copy, showError, showInfo, showNotice, showSuccess } from '../helpers';
import { API, copy, showError, showInfo, showSuccess } from '../helpers';
import Turnstile from 'react-turnstile';
import { UserContext } from '../context/User';
import { onGitHubOAuthClicked } from './utils';

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Label, Popup, Pagination, Table } from 'semantic-ui-react';
import { Link } from 'react-router-dom';
import { API, copy, showError, showInfo, showSuccess, showWarning, timestamp2string } from '../helpers';
import { API, copy, showError, showSuccess, showWarning, timestamp2string } from '../helpers';
import { ITEMS_PER_PAGE } from '../constants';
import { renderQuota } from '../helpers/render';

View File

@ -474,7 +474,7 @@ const SystemSetting = () => {
配置 GitHub OAuth App
<Header.Subheader>
用以支持通过 GitHub 进行登录注册
<a href='https://github.com/settings/developers' target='_blank'>
<a href='https://github.com/settings/developers' target='_blank' rel="noreferrer">
点击此处
</a>
管理你的 GitHub OAuth App
@ -514,7 +514,7 @@ const SystemSetting = () => {
用以支持通过微信进行登录注册
<a
href='https://github.com/songquanpeng/wechat-server'
target='_blank'
target='_blank' rel="noreferrer"
>
点击此处
</a>
@ -556,7 +556,7 @@ const SystemSetting = () => {
配置 Discord OAuth 应用程序
<Header.Subheader>
用以支持通过 Discord 进行登录注册
<a href='https://discord.com/developers/applications' target='_blank'>
<a href='https://discord.com/developers/applications' target='_blank' rel="noreferrer">
点击此处
</a>
管理你的 Discord OAuth App
@ -594,7 +594,7 @@ const SystemSetting = () => {
配置 Google OAuth 应用程序
<Header.Subheader>
用以支持通过 Google 进行登录注册
<a href='https://console.cloud.google.com/' target='_blank'>
<a href='https://console.cloud.google.com/' target='_blank' rel="noreferrer">
点击此处
</a>
管理你的 Google OAuth App
@ -632,7 +632,7 @@ const SystemSetting = () => {
配置 Turnstile
<Header.Subheader>
用以支持用户校验
<a href='https://dash.cloudflare.com/' target='_blank'>
<a href='https://dash.cloudflare.com/' target='_blank' rel="noreferrer">
点击此处
</a>
管理你的 Turnstile Sites推荐选择 Invisible Widget Type

View File

@ -16,11 +16,11 @@ export function renderGroup(group) {
return <>
{groups.map((group) => {
if (group === 'vip' || group === 'pro') {
return <Label color='yellow'>{group}</Label>;
return <Label key={group} color='yellow'>{group}</Label>;
} else if (group === 'svip' || group === 'premium') {
return <Label color='red'>{group}</Label>;
return <Label key={group}color='red'>{group}</Label>;
}
return <Label>{group}</Label>;
return <Label key={group}>{group}</Label>;
})}
</>;
}

View File

@ -258,7 +258,7 @@ const EditChannel = () => {
<Message>
注意<strong>模型部署名称必须和模型名称保持一致</strong> One API model
参数替换为你的部署名称模型名称中的点会被剔除<a target='_blank'
href='https://github.com/songquanpeng/one-api/issues/133?notification_referrer_id=NT_kwDOAmJSYrM2NjIwMzI3NDgyOjM5OTk4MDUw#issuecomment-1571602271'>图片演示</a>
href='https://github.com/songquanpeng/one-api/issues/133?notification_referrer_id=NT_kwDOAmJSYrM2NjIwMzI3NDgyOjM5OTk4MDUw#issuecomment-1571602271' rel="noreferrer">图片演示</a>
</Message>
<Form.Field>
<Form.Input

View File

@ -5,7 +5,7 @@ import { StatusContext } from '../../context/Status';
import { marked } from 'marked';
const Home = () => {
const [statusState, statusDispatch] = useContext(StatusContext);
const [statusState] = useContext(StatusContext);
const [homePageContentLoaded, setHomePageContentLoaded] = useState(false);
const [homePageContent, setHomePageContent] = useState('');
@ -70,7 +70,7 @@ const Home = () => {
源码
<a
href='https://github.com/songquanpeng/one-api'
target='_blank'
target='_blank' rel="noreferrer"
>
https://github.com/songquanpeng/one-api
</a>

View File

@ -1,5 +1,4 @@
import React from 'react';
import { Header, Segment } from 'semantic-ui-react';
import LogsTable from '../../components/LogsTable';
const Token = () => (

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Segment } from 'semantic-ui-react';
import { useParams, useNavigate } from 'react-router-dom';
import { API, downloadTextAsFile, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
import { renderQuotaWithPrompt } from '../../helpers/render';
const EditRedemption = () => {
const params = useParams();

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Message, Segment } from 'semantic-ui-react';
import { useParams, useNavigate } from 'react-router-dom';
import { API, showError, showSuccess, timestamp2string } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
import { renderQuotaWithPrompt } from '../../helpers/render';
const EditToken = () => {
const params = useParams();

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Segment } from 'semantic-ui-react';
import { useParams, useNavigate } from 'react-router-dom';
import { API, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
import { renderQuotaWithPrompt } from '../../helpers/render';
const EditUser = () => {
const params = useParams();