From 9c1b187809bb38ca2f1c943b1a3f34537804198d Mon Sep 17 00:00:00 2001 From: yehong <58927640+yehong-z@users.noreply.github.com> Date: Sat, 12 Aug 2023 14:38:31 +0800 Subject: [PATCH] feat: fix frontend ci (#2) --- web/craco.config.js | 21 + web/package.json | 7 +- web/src/App.js | 2 +- web/src/App.less | 2 +- web/src/Avatar.js | 24 +- web/src/Header.js | 28 +- web/src/admin/AdminFooterEdit.js | 2 +- web/src/admin/AdminFrontConf.js | 48 +- web/src/admin/AdminNode.js | 68 +- web/src/admin/AdminTopic.js | 153 +- web/src/admin/AdminTranslation.js | 474 +- web/src/i18n.js | 2 +- web/src/index.js | 1 + web/src/main/BalanceBox.js | 488 +- web/src/main/EditBox.js | 2 +- web/src/main/FavoritesBox.js | 130 +- web/src/main/NodeBox.js | 2 + web/src/main/NotificationBox.js | 132 +- web/src/main/SearchTag.js | 1 + web/src/main/SelectEditorTypeBox.js | 1 + web/src/main/SelectLanguageBox.js | 1 + web/src/main/TopicBox.js | 1 + web/src/main/TopicList.js | 34 +- web/src/rightbar/RightCommunityHealthBox.js | 1 + web/src/rightbar/RightSigninBox.js | 1 + web/src/serviceWorker.js | 10 +- web/yarn.lock | 25424 +++++++++--------- 27 files changed, 12902 insertions(+), 14158 deletions(-) diff --git a/web/craco.config.js b/web/craco.config.js index c53faff..69a4685 100644 --- a/web/craco.config.js +++ b/web/craco.config.js @@ -14,4 +14,25 @@ module.exports = { }, }, ], + module: { + rules: [ + { + test: /\.less$/, + use: [ + "style-loader", + "css-loader", + "less-loader", + ], + }, + ], + }, + webpack: { + configure: { + resolve: { + fallback: { + "path": false, + }, + }, + }, + }, }; diff --git a/web/package.json b/web/package.json index 249e7b1..6025d8d 100644 --- a/web/package.json +++ b/web/package.json @@ -13,6 +13,7 @@ "braft-editor": "^2.3.9", "browser-image-size": "^1.1.0", "casdoor-js-sdk": "^0.5.1", + "classnames": "^2.3.2", "codemirror": "^5.54.0", "craco-less": "^2.0.0", "i18next": "^19.6.0", @@ -49,7 +50,7 @@ "crowdin:sync": "crowdin upload && crowdin download", "preinstall": "node -e \"if (process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('Use yarn for installing: https://yarnpkg.com/en/docs/install')\"", "fix": "eslint --fix src/**/*.{js,jsx,ts,tsx}", - "lint:css": "stylelint src/**/*.{css,less} --fix" + "lintcss": "stylelint src/**/*.{css,scss} --fix --custom-syntax postcss-scss" }, "eslintConfig": { "extends": "react-app" @@ -69,12 +70,14 @@ "devDependencies": { "@babel/core": "^7.18.13", "@babel/eslint-parser": "^7.18.9", + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.18.6", - "eslint": "8.22.0", + "eslint": "^8.47.0", "eslint-plugin-react": "^7.31.1", "eslint-plugin-unused-imports": "^2.0.0", "husky": "^4.3.8", "lint-staged": "^13.0.3", + "postcss-scss": "^4.0.6", "stylelint": "^14.11.0", "stylelint-config-recommended-less": "^1.0.4", "stylelint-config-standard": "^28.0.0" diff --git a/web/src/App.js b/web/src/App.js index 35f60ad..d0d3368 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -14,9 +14,9 @@ import React, {Component} from "react"; import classNames from "classnames"; -import "./App.less"; import "codemirror/lib/codemirror.css"; import {BackTop, Spin} from "antd"; +import "./App.less"; import * as Setting from "./Setting"; import {Route, Switch} from "react-router-dom"; import TopicPage from "./TopicPage"; diff --git a/web/src/App.less b/web/src/App.less index 6e47ebd..a2596f2 100644 --- a/web/src/App.less +++ b/web/src/App.less @@ -1,5 +1,5 @@ /*@import "~antd/lib/back-top/style/index.css";*/ -@import "~antd/dist/antd.less"; +@import "~antd/dist/reset.css"; #logo { width: 94px; diff --git a/web/src/Avatar.js b/web/src/Avatar.js index e77c418..d490c7a 100644 --- a/web/src/Avatar.js +++ b/web/src/Avatar.js @@ -28,18 +28,18 @@ class Avatar extends React.Component { render() { let style; switch (this.props.size) { - case "small": - style = {width: "24px", height: "24px"}; - break; - case "middle": - style = {width: "36px", height: "36px"}; - break; - case "large": - style = {width: "73px", height: "73px"}; - break; - default: - style = {width: "48px", height: "48px"}; - break; + case "small": + style = {width: "24px", height: "24px"}; + break; + case "middle": + style = {width: "36px", height: "36px"}; + break; + case "large": + style = {width: "73px", height: "73px"}; + break; + default: + style = {width: "48px", height: "48px"}; + break; } let src; diff --git a/web/src/Header.js b/web/src/Header.js index 61d4810..9972818 100644 --- a/web/src/Header.js +++ b/web/src/Header.js @@ -316,20 +316,20 @@ class Header extends React.Component { renderSearchEngine() { let searchUrl; switch (Conf.DefaultSearchSite) { - case "google": - case "Google": - searchUrl = `https://www.google.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`; - break; - case "bing": - case "Bing": - searchUrl = `https://cn.bing.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`; - break; - case "baidu": - case "Baidu": - searchUrl = `https://www.baidu.com/s?q6=${Conf.Domain}&q3=${this.state.searchValue}`; - break; - default: - searchUrl = "/search?keyword=" + this.state.searchValue; + case "google": + case "Google": + searchUrl = `https://www.google.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`; + break; + case "bing": + case "Bing": + searchUrl = `https://cn.bing.com/search?q=site:${Conf.Domain}/t ${this.state.searchValue}`; + break; + case "baidu": + case "Baidu": + searchUrl = `https://www.baidu.com/s?q6=${Conf.Domain}&q3=${this.state.searchValue}`; + break; + default: + searchUrl = "/search?keyword=" + this.state.searchValue; } return ( diff --git a/web/src/admin/AdminFooterEdit.js b/web/src/admin/AdminFooterEdit.js index 874f1ae..d6c72f7 100644 --- a/web/src/admin/AdminFooterEdit.js +++ b/web/src/admin/AdminFooterEdit.js @@ -51,7 +51,6 @@ class AdminFrontConf extends React.Component { getContent(id) { ConfBackend.getFrontConfById(id).then((res) => { - console.log(res.data.value); this.setState({ content: res.data.value, }); @@ -77,6 +76,7 @@ class AdminFrontConf extends React.Component { getFrontConf(id) { ConfBackend.getFrontConfById(id).then((res) => { + // eslint-disable-next-line no-console console.log(res.data[0]); }); } diff --git a/web/src/admin/AdminFrontConf.js b/web/src/admin/AdminFrontConf.js index 4883903..f321eb6 100644 --- a/web/src/admin/AdminFrontConf.js +++ b/web/src/admin/AdminFrontConf.js @@ -138,30 +138,30 @@ class AdminFrontConf extends React.Component { convert(s) { let str; switch (s) { - case "forumName": - str = i18next.t("frontConf:Forum name"); - break; - case "logoImage": - str = i18next.t("frontConf:Logo image"); - break; - case "footerLogoImage": - str = i18next.t("frontConf:Footer Logo image"); - break; - case "footerLogoUrl": - str = i18next.t("frontConf:Footer Logo URL"); - break; - case "signinBoxStrong": - str = i18next.t("frontConf:Right title"); - break; - case "signinBoxSpan": - str = i18next.t("frontConf:Right subtitle"); - break; - case "footerDeclaration": - str = i18next.t("frontConf:Footer title"); - break; - case "footerAdvise": - str = i18next.t("frontConf:Footer subtitle"); - break; + case "forumName": + str = i18next.t("frontConf:Forum name"); + break; + case "logoImage": + str = i18next.t("frontConf:Logo image"); + break; + case "footerLogoImage": + str = i18next.t("frontConf:Footer Logo image"); + break; + case "footerLogoUrl": + str = i18next.t("frontConf:Footer Logo URL"); + break; + case "signinBoxStrong": + str = i18next.t("frontConf:Right title"); + break; + case "signinBoxSpan": + str = i18next.t("frontConf:Right subtitle"); + break; + case "footerDeclaration": + str = i18next.t("frontConf:Footer title"); + break; + case "footerAdvise": + str = i18next.t("frontConf:Footer subtitle"); + break; } return str; } diff --git a/web/src/admin/AdminNode.js b/web/src/admin/AdminNode.js index b39659a..3a340d5 100644 --- a/web/src/admin/AdminNode.js +++ b/web/src/admin/AdminNode.js @@ -441,26 +441,26 @@ class AdminNode extends React.Component { let value, data; switch (item) { - case "node": - value = this.getIndexFromNodeId(this.state.form.parentNode); - data = this.state.nodes.map((node, i) => { - return {text: `${node.nodeInfo.name} / ${node.nodeInfo.id}`, id: i}; - }); - break; - case "tab": - value = this.getIndexFromTabId(this.state.form.tab); - data = this.state.tabs.map((tab, i) => { - return {text: `${tab.name} / ${tab.id}`, id: i}; - }); - break; - case "plane": - value = this.getIndexFromPlaneId(this.state.form.planeId); - data = this.state.planes.map((plane, i) => { - return {text: `${plane.name} / ${plane.id}`, id: i}; - }); - break; - default: - break; + case "node": + value = this.getIndexFromNodeId(this.state.form.parentNode); + data = this.state.nodes.map((node, i) => { + return {text: `${node.nodeInfo.name} / ${node.nodeInfo.id}`, id: i}; + }); + break; + case "tab": + value = this.getIndexFromTabId(this.state.form.tab); + data = this.state.tabs.map((tab, i) => { + return {text: `${tab.name} / ${tab.id}`, id: i}; + }); + break; + case "plane": + value = this.getIndexFromPlaneId(this.state.form.planeId); + data = this.state.planes.map((plane, i) => { + return {text: `${plane.name} / ${plane.id}`, id: i}; + }); + break; + default: + break; } return ( @@ -479,20 +479,20 @@ class AdminNode extends React.Component { const index = parseInt(s); switch (item) { - case "node": - const nodeId = this.state.nodes[index].nodeInfo.id; - this.updateFormField("parentNode", nodeId); - break; - case "tab": - const tab = this.state.tabs[index].id; - this.updateFormField("tab", tab); - break; - case "plane": - const planeId = this.state.planes[index].id; - this.updateFormField("planeId", planeId); - break; - default: - break; + case "node": + const nodeId = this.state.nodes[index].nodeInfo.id; + this.updateFormField("parentNode", nodeId); + break; + case "tab": + const tab = this.state.tabs[index].id; + this.updateFormField("tab", tab); + break; + case "plane": + const planeId = this.state.planes[index].id; + this.updateFormField("planeId", planeId); + break; + default: + break; } }} options={{ diff --git a/web/src/admin/AdminTopic.js b/web/src/admin/AdminTopic.js index 7a49f5e..1466223 100644 --- a/web/src/admin/AdminTopic.js +++ b/web/src/admin/AdminTopic.js @@ -215,70 +215,70 @@ class AdminTopic extends React.Component { renderRadioButton(type) { switch (type) { - case "sdt": - return ( - - this.setState({sdt: 1})} checked={this.state.sdt === 1} name="sdt" /> - {i18next.t("admin:Show")} this.setState({sdt: 0})} checked={this.state.sdt === 0} name="sdt" /> - {i18next.t("admin:Hidden")} - - ); - case "us": - return ( - - this.setState({us: 1})} checked={this.state.us === 1} name="us" /> - {i18next.t("admin:Asc")} this.setState({us: 2})} checked={this.state.us === 2} name="us" /> - {i18next.t("admin:Desc")} this.setState({us: 0})} checked={this.state.us === 0} name="us" /> - {i18next.t("admin:Ignore")} - - ); - case "cs": - return ( - - this.setState({cs: 1})} checked={this.state.cs === 1} name="cs" /> - {i18next.t("admin:Asc")} this.setState({cs: 2})} checked={this.state.cs === 2} name="cs" /> - {i18next.t("admin:Desc")} this.setState({cs: 0})} checked={this.state.cs === 0} name="cs" /> - {i18next.t("admin:Ignore")} - - ); - case "lrs": - return ( - - this.setState({lrs: 1})} checked={this.state.lrs === 1} name="lrs" /> - {i18next.t("admin:Asc")} this.setState({lrs: 2})} checked={this.state.lrs === 2} name="lrs" /> - {i18next.t("admin:Desc")} this.setState({lrs: 0})} checked={this.state.lrs === 0} name="lrs" /> - {i18next.t("admin:Ignore")} - - ); - case "rcs": - return ( - - this.setState({rcs: 1})} checked={this.state.rcs === 1} name="rcs" /> - {i18next.t("admin:Asc")} this.setState({rcs: 2})} checked={this.state.rcs === 2} name="rcs" /> - {i18next.t("admin:Desc")} this.setState({rcs: 0})} checked={this.state.rcs === 0} name="rcs" /> - {i18next.t("admin:Ignore")} - - ); - case "hs": - return ( - - this.setState({hs: 1})} checked={this.state.hs === 1} name="hs" /> - {i18next.t("admin:Asc")} this.setState({hs: 2})} checked={this.state.hs === 2} name="hs" /> - {i18next.t("admin:Desc")} this.setState({hs: 0})} checked={this.state.hs === 0} name="hs" /> - {i18next.t("admin:Ignore")} - - ); - case "fcs": - return ( - - this.setState({fcs: 1})} checked={this.state.fcs === 1} name="fcs" /> - {i18next.t("admin:Asc")} this.setState({fcs: 2})} checked={this.state.fcs === 2} name="fcs" /> - {i18next.t("admin:Desc")} this.setState({fcs: 0})} checked={this.state.fcs === 0} name="fcs" /> - {i18next.t("admin:Ignore")} - - ); - default: - return null; + case "sdt": + return ( + + this.setState({sdt: 1})} checked={this.state.sdt === 1} name="sdt" /> + {i18next.t("admin:Show")} this.setState({sdt: 0})} checked={this.state.sdt === 0} name="sdt" /> + {i18next.t("admin:Hidden")} + + ); + case "us": + return ( + + this.setState({us: 1})} checked={this.state.us === 1} name="us" /> + {i18next.t("admin:Asc")} this.setState({us: 2})} checked={this.state.us === 2} name="us" /> + {i18next.t("admin:Desc")} this.setState({us: 0})} checked={this.state.us === 0} name="us" /> + {i18next.t("admin:Ignore")} + + ); + case "cs": + return ( + + this.setState({cs: 1})} checked={this.state.cs === 1} name="cs" /> + {i18next.t("admin:Asc")} this.setState({cs: 2})} checked={this.state.cs === 2} name="cs" /> + {i18next.t("admin:Desc")} this.setState({cs: 0})} checked={this.state.cs === 0} name="cs" /> + {i18next.t("admin:Ignore")} + + ); + case "lrs": + return ( + + this.setState({lrs: 1})} checked={this.state.lrs === 1} name="lrs" /> + {i18next.t("admin:Asc")} this.setState({lrs: 2})} checked={this.state.lrs === 2} name="lrs" /> + {i18next.t("admin:Desc")} this.setState({lrs: 0})} checked={this.state.lrs === 0} name="lrs" /> + {i18next.t("admin:Ignore")} + + ); + case "rcs": + return ( + + this.setState({rcs: 1})} checked={this.state.rcs === 1} name="rcs" /> + {i18next.t("admin:Asc")} this.setState({rcs: 2})} checked={this.state.rcs === 2} name="rcs" /> + {i18next.t("admin:Desc")} this.setState({rcs: 0})} checked={this.state.rcs === 0} name="rcs" /> + {i18next.t("admin:Ignore")} + + ); + case "hs": + return ( + + this.setState({hs: 1})} checked={this.state.hs === 1} name="hs" /> + {i18next.t("admin:Asc")} this.setState({hs: 2})} checked={this.state.hs === 2} name="hs" /> + {i18next.t("admin:Desc")} this.setState({hs: 0})} checked={this.state.hs === 0} name="hs" /> + {i18next.t("admin:Ignore")} + + ); + case "fcs": + return ( + + this.setState({fcs: 1})} checked={this.state.fcs === 1} name="fcs" /> + {i18next.t("admin:Asc")} this.setState({fcs: 2})} checked={this.state.fcs === 2} name="fcs" /> + {i18next.t("admin:Desc")} this.setState({fcs: 0})} checked={this.state.fcs === 0} name="fcs" /> + {i18next.t("admin:Ignore")} + + ); + default: + return null; } } @@ -405,6 +405,7 @@ class AdminTopic extends React.Component { } renderTopicStatus(status, homePageTopTime, tabTopTime, nodeTopTime) { + // eslint-disable-next-line no-console console.log(status); if (status === false) { status = 1; @@ -422,18 +423,18 @@ class AdminTopic extends React.Component { } switch (status) { - case 1: - return {i18next.t("topic:Normal")}; - case 2: - return {i18next.t("topic:Deleted")}; - case 3: - return {i18next.t("topic:Node Topping")}; - case 4: - return {i18next.t("topic:Tab Topping")}; - case 5: - return {i18next.t("topic:Homepage Topping")}; - default: - return {i18next.t("topic:Unknown status")}; + case 1: + return {i18next.t("topic:Normal")}; + case 2: + return {i18next.t("topic:Deleted")}; + case 3: + return {i18next.t("topic:Node Topping")}; + case 4: + return {i18next.t("topic:Tab Topping")}; + case 5: + return {i18next.t("topic:Homepage Topping")}; + default: + return {i18next.t("topic:Unknown status")}; } } diff --git a/web/src/admin/AdminTranslation.js b/web/src/admin/AdminTranslation.js index 56e0a60..efc88ab 100644 --- a/web/src/admin/AdminTranslation.js +++ b/web/src/admin/AdminTranslation.js @@ -275,26 +275,26 @@ class AdminTranslation extends React.Component { changeEvent(event) { switch (event) { - case "config": - this.getAll(); - break; - case "create": - this.setState({ - form: { - id: "", - name: "", - translator: "", - key: "", - enable: false, - visible: false, - }, - }); - break; - case "manage": - this.getAll(); - break; - default: - break; + case "config": + this.getAll(); + break; + case "create": + this.setState({ + form: { + id: "", + name: "", + translator: "", + key: "", + enable: false, + visible: false, + }, + }); + break; + case "manage": + this.getAll(); + break; + default: + break; } this.setState({ @@ -391,232 +391,232 @@ class AdminTranslation extends React.Component { render() { switch (this.state.event) { - case "config": - return this.renderFormBox( -
- {i18next.t("translator:Translation Platform")} - | -- {this.renderSelectPlatform()} - | -
- {i18next.t("translator:Key")} - | -- { - const targetVal = event.target.value; - this.setState((prevState) => { - prevState.form.key = targetVal; - return prevState; - }); - }} - value={this.state.form?.key} - style={{width: 300}} - /> - | -
- {i18next.t("translator:Visible")} - | -- { - this.setState((prevState) => { - prevState.form.visible = true; - return prevState; - }); - }} - checked={this.state.form?.visible} - name="visible" - /> - {i18next.t("tab:show")}{" "} - { - this.setState((prevState) => { - prevState.form.visible = false; - return prevState; - }); - }} - checked={!this.state.form?.visible} - name="visible" - /> - {i18next.t("tab:hidden")} - | -
- | - this.updateTranslator()} /> - | -
+ {i18next.t("translator:Translation Platform")} + | ++ {this.renderSelectPlatform()} + | +
+ {i18next.t("translator:Key")} + | ++ { + const targetVal = event.target.value; + this.setState((prevState) => { + prevState.form.key = targetVal; + return prevState; + }); + }} + value={this.state.form?.key} + style={{width: 300}} + /> + | +
+ {i18next.t("translator:Visible")} + | ++ { + this.setState((prevState) => { + prevState.form.visible = true; + return prevState; + }); + }} + checked={this.state.form?.visible} + name="visible" + /> + {i18next.t("tab:show")}{" "} + { + this.setState((prevState) => { + prevState.form.visible = false; + return prevState; + }); + }} + checked={!this.state.form?.visible} + name="visible" + /> + {i18next.t("tab:hidden")} + | +
+ | + this.updateTranslator()} /> + | +
- {i18next.t("translator:Translation Platform ID")} - | -- { - const targetVal = event.target.value; - this.setState((prevState) => { - prevState.form.id = targetVal; - return prevState; - }); - }} - value={this.state.form.id} - style={{width: 300}} - /> - | -
- {i18next.t("translator:Translation Platform Name")} - | -- { - const targetVal = event.target.value; - this.setState((prevState) => { - prevState.form.name = targetVal; - return prevState; - }); - }} - value={this.state.form.name} - style={{width: 300}} - /> - | -
- {i18next.t("translator:Translation API")} - | -- {this.renderSelectAPI()} - | -
- {i18next.t("translator:Key")} - | -- { - const targetVal = event.target.value; - this.setState((prevState) => { - prevState.form.key = targetVal; - return prevState; - }); - }} - value={this.state.form.key} - style={{width: 300}} - /> - | -
- {i18next.t("translator:Visible")} - | -- { - this.setState((prevState) => { - prevState.form.visible = true; - return prevState; - }); - }} - checked={this.state.form.visible} - name="visible" - /> - {i18next.t("tab:show")}{" "} - { - this.setState((prevState) => { - prevState.form.visible = false; - return prevState; - }); - }} - checked={!this.state.form.visible} - name="visible" - /> - {i18next.t("tab:hidden")} - | -
- | - this.addTranslator()} /> - | -
+ {i18next.t("translator:Translation Platform ID")} + | ++ { + const targetVal = event.target.value; + this.setState((prevState) => { + prevState.form.id = targetVal; + return prevState; + }); + }} + value={this.state.form.id} + style={{width: 300}} + /> + | +
+ {i18next.t("translator:Translation Platform Name")} + | ++ { + const targetVal = event.target.value; + this.setState((prevState) => { + prevState.form.name = targetVal; + return prevState; + }); + }} + value={this.state.form.name} + style={{width: 300}} + /> + | +
+ {i18next.t("translator:Translation API")} + | ++ {this.renderSelectAPI()} + | +
+ {i18next.t("translator:Key")} + | ++ { + const targetVal = event.target.value; + this.setState((prevState) => { + prevState.form.key = targetVal; + return prevState; + }); + }} + value={this.state.form.key} + style={{width: 300}} + /> + | +
+ {i18next.t("translator:Visible")} + | ++ { + this.setState((prevState) => { + prevState.form.visible = true; + return prevState; + }); + }} + checked={this.state.form.visible} + name="visible" + /> + {i18next.t("tab:show")}{" "} + { + this.setState((prevState) => { + prevState.form.visible = false; + return prevState; + }); + }} + checked={!this.state.form.visible} + name="visible" + /> + {i18next.t("tab:hidden")} + | +
+ | + this.addTranslator()} /> + | +