From 80267598f5f785c8f517c60efbc63773e73a5819 Mon Sep 17 00:00:00 2001 From: bigfengyu Date: Fri, 27 Sep 2019 14:58:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=87=E6=A1=A3=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/actions/repository.ts | 8 - src/actions/types.ts | 8 +- src/components/account/RegisterForm.tsx | 16 +- src/components/editor/InterfaceSummary.tsx | 16 +- src/components/editor/ModuleList.tsx | 9 +- src/components/editor/RepositoryEditor.tsx | 52 +++--- .../repository/ExportPostmanForm.tsx | 150 ++++++++++-------- src/relatives/RepositoryRelative.tsx | 33 ---- src/relatives/services/Foreign.ts | 120 -------------- 10 files changed, 130 insertions(+), 283 deletions(-) delete mode 100644 src/relatives/services/Foreign.ts diff --git a/package.json b/package.json index 8868cd0..db96b1e 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@types/json5": "^0.0.30", "animate.css": "3.7.2", "awesome-debounce-promise": "^2.1.0", + "buc-client": "^3.12.5", "chart.js": "^2.8.0", "classnames": "^2.2.6", "clipboard-copy": "^3.1.0", diff --git a/src/actions/repository.ts b/src/actions/repository.ts index 424d143..06d700b 100644 --- a/src/actions/repository.ts +++ b/src/actions/repository.ts @@ -40,11 +40,3 @@ export const fetchJoinedRepositoryList = ( ) => ({ type: 'JOINED_REPOSITORY_LIST_FETCH', user, name }) export const fetchJoinedRepositoryListSucceeded = (repositories: any) => ({ type: 'JOINED_REPOSITORY_LIST_FETCH_SUCCEEDED', repositories }) export const fetchJoinedRepositoryListFailed = (message: any) => ({ type: 'JOINED_REPOSITORY_LIST_FETCH_FAILED', message }) - -export const fetchForeignInterfaces = ({ id, itf } = {id: '', itf: ''}) => ({ type: 'FOREIGN_INTERFACE_FETCH', id, itf }) -export const fetchForeignInterfacesSuccessed = (data: any) => ({ type: 'FOREIGN_INTERFACE_FETCH_SUCCEEDED', data }) -export const fetchForeignInterfacesFailed = (message: any) => ({ type: 'FOREIGN_INTERFACE_FETCH_FAILED', message }) - -export const addForeignRoomCase = ({ id, itf, name } = { id: '', itf: '', name: ''}) => ({ type: 'ADD_FOREIGN_ROOM_CASE', id, itf, name }) -export const addForeignRoomCaseSuccessed = ({ id, itf } = { id: '', itf: ''}) => ({ type: 'ADD_FOREIGN_ROOM_CASE_SUCCEEDED', id, itf }) -export const addForeignRoomCaseFailed = ({ id, itf, message }: any) => ({ type: 'ADD_FOREIGN_ROOM_CASE_FAILED', id, itf, message }) diff --git a/src/actions/types.ts b/src/actions/types.ts index f55368a..b974271 100644 --- a/src/actions/types.ts +++ b/src/actions/types.ts @@ -15,7 +15,6 @@ export interface RootState { counter: any logs: any - foreign: any loading: boolean message: IMessage } @@ -56,6 +55,13 @@ export interface INumItem { label: string } +export interface IConfig { + serve: string + keys: string[] + session: { + key: string + } +} export interface Repository { id: number diff --git a/src/components/account/RegisterForm.tsx b/src/components/account/RegisterForm.tsx index 8995d9a..115bcb7 100644 --- a/src/components/account/RegisterForm.tsx +++ b/src/components/account/RegisterForm.tsx @@ -21,11 +21,17 @@ type Props = { // 模拟数据 const mockUser = () => - Mock.mock({ - fullname: '@CNAME', - email: '@email', - password: '@string(6)', - }) + process.env.NODE_ENV === 'development' + ? Mock.mock({ + fullname: '@CNAME', + email: '@email', + password: '@string(6)', + }) + : { + fullname: '', + email: '', + password: '', + } // 展示组件 class RegisterForm extends Component { diff --git a/src/components/editor/InterfaceSummary.tsx b/src/components/editor/InterfaceSummary.tsx index 4a8ed5c..c867006 100644 --- a/src/components/editor/InterfaceSummary.tsx +++ b/src/components/editor/InterfaceSummary.tsx @@ -12,7 +12,6 @@ import { METHODS, STATUS_LIST } from './InterfaceForm' import { CopyToClipboard } from '../utils/' import { getRelativeUrl } from '../../utils/URLUtils' import './InterfaceSummary.css' -import { RootState } from 'actions/types' import { showMessage, MSG_TYPE } from 'actions/common' import { TextField, @@ -109,7 +108,6 @@ class InterfaceSummary extends Component< InterfaceSummaryState > { static contextTypes = { - // onAddForeignRoomCase: PropTypes.func.isRequired, onDeleteInterface: PropTypes.func.isRequired, } constructor(props: any) { @@ -490,20 +488,8 @@ class InterfaceSummary extends Component< } } handleUpdate = () => { /** empty */ } - // createCase = (e: any, repositoryId: any, interfaceId: any, name: any) => { - // e.preventDefault() - // this.setState({ name }) - // const { onAddForeignRoomCase } = this.context - // onAddForeignRoomCase({ - // id: repositoryId, - // itf: interfaceId, - // name, - // }) - // // itf.repositoryId - // } } -const mapStateToProps = (state: RootState) => ({ - room: state.foreign, +const mapStateToProps = () => ({ }) const mapDispatchToProps = { replace, diff --git a/src/components/editor/ModuleList.tsx b/src/components/editor/ModuleList.tsx index b2162ba..d1b9698 100644 --- a/src/components/editor/ModuleList.tsx +++ b/src/components/editor/ModuleList.tsx @@ -84,15 +84,17 @@ interface ModuleListProps { mod?: Module repository: Repository } -function ModuleList(props: ModuleListProps, context: any) { +function ModuleList(props: ModuleListProps) { const [open, setOpen] = useState(false) + const dispatch = useDispatch() const auth = useSelector((state: RootState) => state.auth) const { repository, mods = [], mod } = props const isOwned = repository.owner!.id === auth.id const isJoined = repository.members!.find((item: any) => item.id === auth.id) const handleSort = (_: any, sortable: any) => { - const { onSortModuleList } = context - onSortModuleList(sortable.toArray()) + dispatch(sortModuleList(sortable.toArray(), () => { + /** empty */ + })) } return ( @@ -136,7 +138,6 @@ const mapStateToProps = (state: RootState) => ({ }) const mapDispatchToProps = ({ replace, - onSortModuleList: sortModuleList, }) export default connect( mapStateToProps, diff --git a/src/components/editor/RepositoryEditor.tsx b/src/components/editor/RepositoryEditor.tsx index 49b6576..ce5ad80 100644 --- a/src/components/editor/RepositoryEditor.tsx +++ b/src/components/editor/RepositoryEditor.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react' import { PropTypes, connect, Link, replace, _ } from '../../family' import { serve } from '../../relatives/services/constant' -import { RModal, Spin } from '../utils' +import { Spin } from '../utils' import RepositoryForm from '../repository/RepositoryForm' import RepositorySearcher from './RepositorySearcher' import ModuleList from './ModuleList' @@ -25,7 +25,7 @@ import { updateInterface, deleteInterface, lockInterface, - unlockInterface, + unlockInterface } from '../../actions/interface' import { addProperty, @@ -39,7 +39,6 @@ import { GoPlug, GoDatabase, GoJersey, - GoChecklist, GoLinkExternal, GoPencil } from 'react-icons/go' @@ -100,7 +99,6 @@ class RepositoryEditor extends Component { render() { const { location: { params }, - room, auth, } = this.props let { repository } = this.props @@ -161,17 +159,15 @@ class RepositoryEditor extends Component { 编辑 ) : null} - - { - ok && this.handleUpdate() - this.setState({ update: false }) - }} - title="编辑仓库" - repository={repository} - /> - + { + ok && this.handleUpdate() + this.setState({ update: false }) + }} + title="编辑仓库" + repository={repository} + /> { > 测试 - {room && - room[repository.id] && - typeof room[repository.id].coverage !== 'undefined' && ( - - Room用例覆盖:{' '} - {Math.round(room[repository.id].coverage * 100)}% - - )} this.setState({ exportPostman: true })} > - 导出Postman Collection + 导出 - this.setState({ exportPostman: false })} - onResolve={() => this.setState({ exportPostman: false })} - > - - + />
{repository.description}
diff --git a/src/components/repository/ExportPostmanForm.tsx b/src/components/repository/ExportPostmanForm.tsx index d7d2c1c..f716451 100644 --- a/src/components/repository/ExportPostmanForm.tsx +++ b/src/components/repository/ExportPostmanForm.tsx @@ -1,70 +1,94 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { RParsley } from '../utils' +import React from 'react' import config from '../../config' +import { + Button, + Dialog, + DialogTitle, + DialogContent, + Slide +} from '@material-ui/core' +import { TransitionProps } from '@material-ui/core/transitions/transition' -class ExportPostmanForm extends Component { - static contextTypes = { - rmodal: PropTypes.object.isRequired, - } - static propTypes = { - repoId: PropTypes.number, - } - rparsley: any - render() { - const { rmodal } = this.context - const { repoId } = this.props - return ( -
-
- {this.props.title} -
- { this.rparsley = rparsley }}> -
false} > -
-
- 请在Postman中点击导入(Import),选择从链接导入(Import From Link),输入如下链接即可。 -
-
{config.serve}/postman/export?id={repoId}
+const Transition = React.forwardRef((props, ref) => { + return +}) + +export default function ExportPostmanForm(props: { + repoId: number; + open: boolean; + onClose: () => void; + title: string; +}) { + const { repoId, open, onClose, title } = props + const markdownLink = `${config.serve}/export/markdown?id=${repoId}&origin=${window.location.origin}` + const docxLink = `${config.serve}/export/docx?id=${repoId}&origin=${window.location.origin}` + // const pdfLink = `${config.serve}/export/pdf?id=${repoId}&origin=${window.location.origin}` + return ( + onClose()} + TransitionComponent={Transition} + > + {title} + + false}> +
+
+ Postman:
+
+ {' '} + {config.serve}/export/postman?id={repoId}{' '} +
+
请在 Postman 中点击导入(Import),选择从链接导入(Import + From Link),输入以上链接即可。
+
+ +
+
Markdown:
+ -
-
-
+
+ +
+
Docx:
+ - - -
- ) - } - componentDidUpdate() { - this.context.rmodal.reposition() - } - handleSubmit = (e: any) => { - e.preventDefault() + - if (!this.rparsley.isValid()) { return } + {/*
+
PDF:
+
+ {pdfLink} +
+
*/} - const { onAddRepository, onUpdateRepository } = this.context - const onAddOrUpdateRepository = this.state.id ? onUpdateRepository : onAddRepository - const { organization } = this.props - const repository: any = { - ...this.state, - // ownerId: owner.id, // DONE 2.2 支持转移仓库 - organizationId: organization ? organization.id : null, - memberIds: (this.state.members || []).map((user: any) => user.id), - } - const { owner, newOwner } = this.state - if (newOwner && newOwner.id !== owner.id) { repository.ownerId = newOwner.id } - const { rmodal } = this.context - rmodal.close() - onAddOrUpdateRepository(repository, () => { - if (rmodal) { rmodal.resolve() } - }) - } +
+ +
+ + + + ) } - -export default ExportPostmanForm diff --git a/src/relatives/RepositoryRelative.tsx b/src/relatives/RepositoryRelative.tsx index d3560b1..752ad26 100644 --- a/src/relatives/RepositoryRelative.tsx +++ b/src/relatives/RepositoryRelative.tsx @@ -401,39 +401,6 @@ export default { return state } }, - foreign(state: any = null, action: any) { - switch (action.type) { - case 'FOREIGN_INTERFACE_FETCH': - return { - ...state, - [action.itf ? action.id + '_' + action.itf : action.id]: 'pending', - } - case 'FOREIGN_INTERFACE_FETCH_SUCCEEDED': - return { - ...state, - [action.data.interfaceId - ? action.data.repositoryId + '_' + action.data.interfaceId - : action.data.repositoryId]: action.data, - } - case 'ADD_FOREIGN_ROOM_CASE': - return { - ...state, - ['+' + action.id + '_' + action.itf]: 'pending', - } - case 'ADD_FOREIGN_ROOM_CASE_SUCCEEDED': - return { - ...state, - ['+' + action.id + '_' + action.itf]: 'success', - } - case 'ADD_FOREIGN_ROOM_CASE_FAILED': - return { - ...state, - ['+' + action.id + '_' + action.itf]: 'failed', - } - default: - return state - } - }, }, sagas: { [RepositoryAction.addRepository(undefined, undefined).type]: diff --git a/src/relatives/services/Foreign.ts b/src/relatives/services/Foreign.ts deleted file mode 100644 index 82c5273..0000000 --- a/src/relatives/services/Foreign.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { CREDENTIALS, serve } from './constant' - -export default { - getInterfaces({ id, itf }: any) { - let roomProjectId: any - let hostname: any - let interfaces: any[] = [] - const caseMap: any = {} - const roomCases = new Set() - return fetch(`${serve}/foreign/room?repositoryId=${id}`, - { ...CREDENTIALS } - ) - .then(res => res.json()) - .then(json => { - if (json.error) { - throw new Error('接口请求失败: ' + json.error) - } - roomProjectId = json.data.roomProjectId - interfaces = json.data.interfaces - hostname = json.data.hostname - if (itf) { - interfaces = interfaces.filter(({ id }) => id === +itf) - } - return requestRoom('module/moduledetail?projectId=' + roomProjectId, undefined) - }) - .then(roomCaseBatches => { - roomCaseBatches.reduce( - (prev: any, curr: any) => prev.concat(curr.cases), [] - ).filter((item: any) => !!item).forEach((theCase: any) => { - const anchor = document.createElement('a') - anchor.href = theCase.path - const { pathname } = anchor - if (!caseMap[pathname]) { - caseMap[pathname] = [] - } - - caseMap[pathname].push(theCase.caseId) - roomCases.add(caseMap[pathname]) - }) - - const arr = interfaces.map( (item: any) => { - const { url } = item - const newItem: any = { url } - newItem.id = item.id - newItem.cases = item.url in caseMap ? caseMap[item.url] : [] - return newItem - }) - - return { - list: arr, - coverage: arr.length && arr.reduce((prev, curr) => prev + (!!curr.cases.length), 0) / arr.length, - hostname, - roomProjectId, - repositoryId: id, - interfaceId: itf, - } - }) - }, - addForeignRoomCase({ id, itf, name }: any) { - let module - let cases: any = [] - return fetch(`${serve}/foreign/room/params?repositoryId=${id}&interfaceId=${itf}&name=${encodeURIComponent(name)}`) - .then(res => res.json()) - .then(json => { - if (json.error) { - throw new Error('接口请求失败: ' + json.error) - } - module = json.data.module - cases = json.data.cases - return requestRoom('module', module, 'post') - }) - .then(moduleId => { - cases.forEach((theCase: any) => { - theCase.moduleId = moduleId - }) - return Promise.all(cases.map((theCase: any) => requestRoom('case', theCase, 'post'))) - }) - }, -} - -async function requestRoom(path: any, body: any, method: any = 'get') { - if (typeof body === 'object' && method === 'get') { - path = path + '?' + formatKV(body) - body = null - } - if (path[0] !== '/') { - path = '/' + path - } - - const resp = await fetch('http://room.daily.taobao.net/api' + path, { - method: method, - body: body && formatKV(body), - // @ts-ignore - headers: new window.Headers({ - 'Content-Type': 'application/x-www-form-urlencoded', - }), - }) - const { status } = resp - - if (status !== 200) { - throw new Error(`Request Failed for ${path}\nStatus Code: ${status}`) - } - - const json = await resp.json() - - if (!json || !json.info || !json.info.ok) { - throw new Error('Error from room remote: ' + json.info.message) - } - - return (json && json.data && json.data.result) || json.info.message - - function formatKV(obj: any) { - let str = '' - for (const key of Object.keys(obj)) { - str && (str += '&') - str += key + '=' + encodeURIComponent(obj[key]) - } - return str - } -}