Skip to content

Commit

Permalink
#93 common setting for collection
Browse files Browse the repository at this point in the history
  • Loading branch information
brookshi committed Jun 3, 2018
1 parent 8dbbf61 commit 0df97c6
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 37 deletions.
12 changes: 12 additions & 0 deletions api/interfaces/dto_collection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DtoRecord } from './dto_record';
import { DtoHeader } from './dto_header';

export interface DtoCollection {

Expand All @@ -14,9 +15,20 @@ export interface DtoCollection {

projectId: string;

commonSetting: DtoCommonSetting;

description: string;
}

export interface DtoCommonSetting {

prescript: string;

test: string;

headers: DtoHeader[];
}

export interface DtoCollectionWithRecord {

collections: _.Dictionary<DtoCollection>;
Expand Down
10 changes: 10 additions & 0 deletions api/models/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Entity, PrimaryColumn, Column, CreateDateColumn, OneToOne, OneToMany, J
import { Record } from './record';
import { User } from './user';
import { Project } from './project';
import { DtoCommonSetting } from '../interfaces/dto_collection';

@Entity()
export class Collection {
Expand Down Expand Up @@ -41,6 +42,15 @@ export class Collection {
@Column({ default: true })
public: boolean;

@Column('json', { nullable: true })
commonSetting: DtoCommonSetting;

compatibleCommonPreScript = () => this.commonSetting ? (this.commonSetting.prescript || '') : (this.commonPreScript || '');

commonTest = () => this.commonSetting ? (this.commonSetting.test || '') : '';

commonHeaders = () => this.commonSetting ? (this.commonSetting.headers || []) : [];

@CreateDateColumn()
createDate: Date;

Expand Down
11 changes: 5 additions & 6 deletions api/services/collection_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class CollectionService {
collection.reqStrictSSL = dtoCollection.reqStrictSSL;
collection.reqFollowRedirect = dtoCollection.reqFollowRedirect;
collection.description = dtoCollection.description;
collection.commonSetting = dtoCollection.commonSetting;
collection.project = new Project();
collection.project.id = dtoCollection.projectId;
collection.records = [];
Expand All @@ -58,16 +59,14 @@ export class CollectionService {
const connection = await ConnectionManager.getInstance();

await connection.getRepository(Collection)
.createQueryBuilder('collection')
.where('id=:id', { id: dtoCollection.id })
.update({
.update({ id: dtoCollection.id }, {
name: dtoCollection.name,
description: dtoCollection.description,
commonPreScript: dtoCollection.commonPreScript,
reqStrictSSL: !!dtoCollection.reqStrictSSL,
reqFollowRedirect: !!dtoCollection.reqFollowRedirect
})
.execute();
reqFollowRedirect: !!dtoCollection.reqFollowRedirect,
commonSetting: dtoCollection.commonSetting
});
return { success: true, message: Message.get('collectionUpdateSuccess') };
}

Expand Down
1 change: 1 addition & 0 deletions api/services/importer/swagger_import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class SwaggerImport implements RequestsImport {
const dtoCollection: DtoCollection = {
name: swaggerData.info.title,
commonPreScript: '',
commonSetting: { prescript: '', test: '', headers: [] },
projectId: projectId,
id: StringUtil.generateUID(),
description: swaggerData.info.description
Expand Down
9 changes: 5 additions & 4 deletions api/services/record_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,23 +362,24 @@ export class RecordService {
.execute();
}

static async combineScript(record: Record): Promise<Record> {
static async combineScriptAndHeaders(record: Record): Promise<Record> {
const { globalFunction } = (await ProjectService.getProjectByCollectionId(record.collection.id)) || { globalFunction: '' };
const commonPreScript = record.collection ? record.collection.commonPreScript : '';

const prescript = `
${globalFunction || ''};
${commonPreScript || ''};
${record.collection ? record.collection.compatibleCommonPreScript() : ''};
${record.prescript || ''};
`;

const test = `
${globalFunction || ''};
${record.collection.commonTest()};
${record.test || ''};
`;

return {
...record,
headers: [...record.collection.commonHeaders().map(h => HeaderService.fromDto(h)), ...record.headers],
prescript,
test
};
Expand All @@ -396,7 +397,7 @@ export class RecordService {

for (let r of records) {
cm.push('Combine scripts');
let newRecord = { ...(await RecordService.combineScript(r)) };
let newRecord = { ...(await RecordService.combineScriptAndHeaders(r)) };
cm.push('Get project info');
const { id: pid } = (await ProjectService.getProjectByCollectionId(r.collection.id)) || { id: '' };
cm.push('Apply environment variables');
Expand Down
3 changes: 2 additions & 1 deletion api/services/stress_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,13 @@ export class StressService {
return ScriptTransform.toES5(isPre ? (
`
${globalFunction || ''}
${record.collection.commonPreScript || ''}
${record.collection.compatibleCommonPreScript()}
${record.prescript || ''}
`
) : (
`
${globalFunction || ''}
${record.collection.commonTest()}
${record.test || ''}
`
));
Expand Down
168 changes: 168 additions & 0 deletions client/src/components/common_setting_dialog/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React from 'react';
import { Modal, Tabs, Badge, Dropdown, Icon, Button, Menu } from 'antd';
import Editor from '../editor';
import { DtoCommonSetting } from '../../../../api/interfaces/dto_collection';
import { nameWithTag } from '../name_with_tag/index';
import { normalBadgeStyle } from '../../style/theme';
import Msg from '../../locales';
import KeyValueList from '../key_value';
import { KeyValueEditMode, KeyValueEditType } from '../../common/custom_type';
import { getTestSnippets } from '../../common/test_snippet';
import * as _ from 'lodash';
import { DtoHeader } from '../../../../api/interfaces/dto_header';

const TabPane = Tabs.TabPane;

interface CommonSettingDialogProps {

type: 'Folder' | 'Collection';

isOpen: boolean;

commonSetting: DtoCommonSetting;

onOk(commonSetting: DtoCommonSetting);

onCancel();
}

interface CommonSettingDialogState {

commonSetting: DtoCommonSetting;

activeTabKey: string;

headersEditMode: KeyValueEditMode;
}

class CommonSettingDialog extends React.Component<CommonSettingDialogProps, CommonSettingDialogState> {

constructor(props: CommonSettingDialogProps) {
super(props);
this.state = {
commonSetting: props.commonSetting,
activeTabKey: 'headers',
headersEditMode: KeyValueEditType.keyValueEdit
};
}

public componentWillReceiveProps(nextProps: CommonSettingDialogProps) {
if (!this.props.isOpen) {
this.setState({ ...this.state, commonSetting: nextProps.commonSetting });
}
}

private onTabChanged = (key) => {
this.setState({ ...this.state, activeTabKey: key });
}

private onHeaderModeChanged = () => {
this.setState({ ...this.state, headersEditMode: KeyValueEditType.getReverseMode(this.state.headersEditMode) });
}

private onSelectSnippet = (e) => {
const snippet = getTestSnippets()[e.key];
let test = this.state.commonSetting.test;
test = test && test.length > 0 ? (`${test}\n\n${snippet}`) : snippet;
this.changeCommonSetting({ test });
}

private snippetsMenu = (
<Menu onClick={this.onSelectSnippet}>
{Object.keys(getTestSnippets()).map(s => <Menu.Item key={s}>{s}</Menu.Item>)}
</Menu>
);

private changeCommonSetting = (newSetting: any) => {
this.setState({ ...this.state, commonSetting: { ...this.state.commonSetting, ...newSetting } });
}

private onHeadersChanged = (data: DtoHeader[]) => {
data.forEach((v, i) => v.sort = i);
this.changeCommonSetting({ headers: data });
}

private extraContent = () => {

let { activeTabKey, headersEditMode } = this.state;

switch (activeTabKey) {
case 'test': {
return (
<Dropdown overlay={this.snippetsMenu} trigger={['click']}>
<a className="ant-dropdown-link" href="#">
{Msg('Collection.Snippets')} <Icon type="down" />
</a>
</Dropdown>
);
}
case 'headers': {
return (
<Button className="tab-extra-button" onClick={this.onHeaderModeChanged}>
{KeyValueEditType.getReverseMode(headersEditMode)}
</Button>
);
}
default: return null;
}
}

public render() {

const { type, isOpen, onOk, onCancel } = this.props;
const { activeTabKey, commonSetting, headersEditMode } = this.state;
const { headers, prescript, test } = commonSetting;

return (
<Modal
title={`${type} common setting`}
visible={isOpen}
maskClosable={false}
width={800}
onOk={() => onOk(this.state.commonSetting)}
onCancel={onCancel}
>
<Tabs
className="req-res-tabs"
defaultActiveKey="headers"
activeKey={activeTabKey}
animated={false}
onChange={this.onTabChanged}
tabBarExtraContent={this.extraContent()}
>
<TabPane tab={nameWithTag(Msg('Collection.Headers'), headers ? (Math.max(0, headers.length)).toString() : '')} key="headers">
<KeyValueList
mode={headersEditMode}
onHeadersChanged={this.onHeadersChanged}
isAutoComplete={true}
headers={_.sortBy(_.cloneDeep(headers) || [], 'sort')}
showDescription={true}
/>
</TabPane>
<TabPane
tab={(
<Badge style={normalBadgeStyle} dot={!!prescript && prescript.length > 0} count="">
{Msg('Collection.PreRequestScript')}
</Badge>
)}
key="prescript"
>
<Editor type="javascript" height={300} fixHeight={true} value={prescript || ''} onChange={v => this.changeCommonSetting({ 'prescript': v })} />
</TabPane>
<TabPane
tab={(
<Badge style={normalBadgeStyle} dot={!!test && test.length > 0} count="">
{Msg('Collection.Test')}
</Badge>
)}
key="test"
>
<Editor type="javascript" height={300} fixHeight={true} value={test} onChange={v => this.changeCommonSetting({ 'test': v })} />
</TabPane>
</Tabs>
</Modal>
);
}
}

export default CommonSettingDialog;
1 change: 1 addition & 0 deletions client/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"Collection.CloseAll": "Close All",
"Collection.ReduceAlgorithm": "Pairwise Algorithm",
"Collection.ParamCopied": "Parameter copied, could be used in test script!",
"Collection.commonSetting": "Common settings",

"Project.DeleteEnvironment": "Delete environment",
"Project.DeleteThisEnvironment": "delete environment: {name}",
Expand Down
1 change: 1 addition & 0 deletions client/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"Collection.CloseAll": "关掉所有标签",
"Collection.ReduceAlgorithm": "Pairwise算法",
"Collection.ParamCopied": "Parameter复制成功, 可以用在test脚本里!",
"Collection.commonSetting": "通用设置",

"Project.DeleteEnvironment": "删除环境",
"Project.DeleteThisEnvironment": "删除环境: {name}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface CollectionItemProps {

shareCollection(collectionId: string);

editPreRequestScript();
editCommonSetting();

editReqStrictSSL();

Expand Down Expand Up @@ -88,8 +88,8 @@ class CollectionItem extends React.Component<CollectionItemProps, CollectionItem
{/*<Menu.Item key="share">
<Icon type="share-alt" /> Share
</Menu.Item>*/}
<Menu.Item key="editPreRequestScript">
<Icon type="code-o" /> {Msg('Collection.CommonPreRequestScript')}
<Menu.Item key="commonSetting">
<Icon type="code-o" /> {Msg('Collection.commonSetting')}
</Menu.Item>
<Menu.Item key="editReqStrictSSL">
<span>
Expand Down Expand Up @@ -128,7 +128,7 @@ class CollectionItem extends React.Component<CollectionItemProps, CollectionItem

createRecord = () => this.props.createRecord({ ...getDefaultRecord(false), collectionId: this.props.collection.id, id: StringUtil.generateUID() });

editPreRequestScript = () => this.props.editPreRequestScript();
commonSetting = () => this.props.editCommonSetting();

editReqStrictSSL = () => this.props.editReqStrictSSL();

Expand Down
Loading

0 comments on commit 0df97c6

Please sign in to comment.