mirror of
https://gitee.com/eolink_admin/postcat.git
synced 2024-11-30 02:37:57 +08:00
fix:tab some bug
This commit is contained in:
parent
521896a919
commit
6a22e79508
@ -1,4 +1,4 @@
|
||||
import { Component, Input, Output, EventEmitter, OnChanges, AfterViewInit, ViewChild } from '@angular/core';
|
||||
import { Component, Input, Output, EventEmitter, OnChanges, AfterViewInit, ViewChild, OnInit } from '@angular/core';
|
||||
import { NzMessageService } from 'ng-zorro-antd/message';
|
||||
import { AceConfigInterface, AceComponent, AceDirective } from 'ngx-ace-wrapper';
|
||||
import { whatTextType } from '../../../utils';
|
||||
@ -44,7 +44,7 @@ const eventHash = new Map()
|
||||
templateUrl: './eo-editor.component.html',
|
||||
styleUrls: ['./eo-editor.component.scss'],
|
||||
})
|
||||
export class EoEditorComponent implements AfterViewInit, OnChanges {
|
||||
export class EoEditorComponent implements AfterViewInit, OnInit, OnChanges {
|
||||
@Input() eventList: EventType[] = [];
|
||||
@Input() hiddenList: string[] = [];
|
||||
@Input() code: string;
|
||||
@ -82,15 +82,7 @@ export class EoEditorComponent implements AfterViewInit, OnChanges {
|
||||
|
||||
constructor(private message: NzMessageService) {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
// To get the Ace instance:
|
||||
this.buttonList = this.eventList
|
||||
.filter((it) => it !== 'type')
|
||||
.map((it) => ({
|
||||
event: it,
|
||||
...eventHash.get(it),
|
||||
}));
|
||||
}
|
||||
ngAfterViewInit(): void {}
|
||||
ngOnChanges() {
|
||||
// * update root type
|
||||
if (this.eventList.includes('type') && !this.hiddenList.includes('type')) {
|
||||
@ -101,6 +93,15 @@ export class EoEditorComponent implements AfterViewInit, OnChanges {
|
||||
}
|
||||
}
|
||||
}
|
||||
ngOnInit() {
|
||||
// To get the Ace instance:
|
||||
this.buttonList = this.eventList
|
||||
.filter((it) => it !== 'type')
|
||||
.map((it) => ({
|
||||
event: it,
|
||||
...eventHash.get(it),
|
||||
}));
|
||||
}
|
||||
log(event, txt) {
|
||||
console.log('ace event', event, txt);
|
||||
}
|
||||
|
@ -20,15 +20,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_container {{ this.id ? 'has_tab_page' : '' }}">
|
||||
<nz-tabset class="inside_page_tab" *ngIf="this.id" nzLinkRouter>
|
||||
<nz-tab>
|
||||
<a *nzTabLink nz-tab-link [routerLink]="['detail']" queryParamsHandling="merge"> 文档 </a>
|
||||
</nz-tab>
|
||||
<nz-tab>
|
||||
<a *nzTabLink nz-tab-link [routerLink]="['edit']" queryParamsHandling="merge"> 编辑 </a>
|
||||
</nz-tab>
|
||||
<nz-tab>
|
||||
<a *nzTabLink nz-tab-link [routerLink]="['test']" queryParamsHandling="merge"> 测试 </a>
|
||||
<nz-tabset class="inside_page_tab" *ngIf="this.id" nzLinkRouter>
|
||||
<nz-tab *ngFor="let tab of TABS">
|
||||
<a
|
||||
*nzTabLink
|
||||
nz-tab-link
|
||||
(click)="clickContentMenu(tab)"
|
||||
[routerLink]="[tab.routerLink]"
|
||||
queryParamsHandling="merge"
|
||||
>{{ tab.title }}</a
|
||||
>
|
||||
</nz-tab>
|
||||
</nz-tabset>
|
||||
<router-outlet></router-outlet>
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree';
|
||||
import { Message, MessageService } from '../../shared/services/message';
|
||||
import { ApiTabComponent } from './tab/api-tab.component';
|
||||
import { GroupService } from '../../shared/services/group/group.service';
|
||||
import { NzModalService } from 'ng-zorro-antd/modal';
|
||||
import { ApiDataService } from '../../shared/services/api-data/api-data.service';
|
||||
@ -13,15 +12,15 @@ import { GroupApiDataModel, GroupTreeItem } from '../../shared/models';
|
||||
import { ApiData } from '../../shared/services/api-data/api-data.model';
|
||||
import { Group } from '../../shared/services/group/group.model';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { ApiTabService } from './tab/api-tab.service';
|
||||
@Component({
|
||||
selector: 'eo-api',
|
||||
templateUrl: './api.component.html',
|
||||
styleUrls: ['./api.component.scss'],
|
||||
})
|
||||
export class ApiComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(ApiTabComponent) apiTabComponent: ApiTabComponent;
|
||||
/**
|
||||
* Default projectID.
|
||||
*/
|
||||
@ -49,13 +48,28 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
id: number;
|
||||
|
||||
TABS = [
|
||||
{
|
||||
routerLink: 'detail',
|
||||
title: '文档',
|
||||
},
|
||||
{
|
||||
routerLink: 'edit',
|
||||
title: '编辑',
|
||||
},
|
||||
{
|
||||
routerLink: 'test',
|
||||
title: '测试',
|
||||
},
|
||||
];
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private groupService: GroupService,
|
||||
private apiDataService: ApiDataService,
|
||||
private messageService: MessageService,
|
||||
private modalService: NzModalService
|
||||
private modalService: NzModalService,
|
||||
private tabSerive: ApiTabService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -93,7 +107,7 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
getApis() {
|
||||
this.apiDataService.loadAllByProjectID(this.projectID).subscribe((items: Array<ApiData>) => {
|
||||
let apiItems={};
|
||||
let apiItems = {};
|
||||
items.forEach((item) => {
|
||||
delete item.updatedAt;
|
||||
apiItems[item.uuid] = item;
|
||||
@ -106,7 +120,7 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
isLeaf: true,
|
||||
});
|
||||
});
|
||||
this.apiDataItems=apiItems;
|
||||
this.apiDataItems = apiItems;
|
||||
this.generateGroupTreeData();
|
||||
});
|
||||
}
|
||||
@ -119,6 +133,9 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
this.id = Number(params.get('uuid'));
|
||||
});
|
||||
}
|
||||
clickContentMenu(data) {
|
||||
this.tabSerive.apiEvent$.next({ action: 'beforeChangeRouter', data: data });
|
||||
}
|
||||
/**
|
||||
* Event emit from group tree component.
|
||||
*
|
||||
@ -132,27 +149,16 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
case 'loadAllGroup':
|
||||
this.buildGroupTreeData();
|
||||
break;
|
||||
case 'testApi':
|
||||
this.testApi(event.node);
|
||||
break;
|
||||
case 'detailApi':
|
||||
this.detailApi(event.node);
|
||||
break;
|
||||
case 'editApi':
|
||||
this.editApi(event.node);
|
||||
break;
|
||||
case 'copyApi':
|
||||
this.copyApi(event.node);
|
||||
break;
|
||||
case 'deleteApi':
|
||||
this.deleteApi(event.node);
|
||||
break;
|
||||
case 'newApi':
|
||||
this.newApi(event.node);
|
||||
break;
|
||||
case 'newApiTest':
|
||||
this.newApiTest();
|
||||
default: {
|
||||
this.tabSerive.apiEvent$.next({ action: event.eventName, data: event.node });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,42 +171,29 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((data: Message) => {
|
||||
switch (data.type) {
|
||||
case 'apiAdd':
|
||||
case 'editApi':
|
||||
case 'addApi':
|
||||
case 'editApi':
|
||||
{
|
||||
this.tabSerive.apiEvent$.next({ action: `${data.type}Finish`,data:data.data});
|
||||
this.buildGroupTreeData();
|
||||
break;
|
||||
}
|
||||
case 'groupAdd':
|
||||
case 'groupEdit':
|
||||
case 'groupDelete':
|
||||
this.buildGroupTreeData();
|
||||
break;
|
||||
case 'apiDelete':
|
||||
this.watchApiDelete(data.data);
|
||||
let tmpApi = data.data;
|
||||
this.tabSerive.apiEvent$.next({ action: 'removeApiDataTabs', data: [tmpApi.uuid] });
|
||||
this.buildGroupTreeData();
|
||||
break;
|
||||
case 'apiBatchDelete':
|
||||
this.watchApiBatchDelete(data.data);
|
||||
this.tabSerive.apiEvent$.next({ action: 'removeApiDataTabs', data: data.data.uuids });
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete api data tabs after item removed.
|
||||
*
|
||||
* @param data object
|
||||
*/
|
||||
watchApiDelete(data) {
|
||||
this.apiTabComponent.removeApiDataTabs([data.uuid]);
|
||||
this.buildGroupTreeData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete api data tabs after items removed.
|
||||
*
|
||||
* @param data object
|
||||
*/
|
||||
watchApiBatchDelete(data) {
|
||||
this.apiTabComponent.removeApiDataTabs(data.uuids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate group tree nodes.
|
||||
*/
|
||||
@ -209,51 +202,6 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
this.treeNodes = [];
|
||||
listToTree(this.treeItems, this.treeNodes, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new tab of add new api data.
|
||||
*
|
||||
* @param item GroupTreeItem
|
||||
*/
|
||||
newApi(node?: NzTreeNode): void {
|
||||
console.log('newApi',node)
|
||||
this.apiTabComponent.appendTab('edit', node ? { groupID: node.key } : {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new tab of add new api test.
|
||||
*/
|
||||
newApiTest(): void {
|
||||
this.apiTabComponent.appendTab('test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test api data.
|
||||
*
|
||||
* @param node NzTreeNode
|
||||
*/
|
||||
testApi(node: NzTreeNode): void {
|
||||
this.apiTabComponent.appendTab('test', node.origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* View api data.
|
||||
*
|
||||
* @param node NzTreeNode
|
||||
*/
|
||||
detailApi(node: NzTreeNode): void {
|
||||
this.apiTabComponent.appendTab('detail', node.origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit api data.
|
||||
*
|
||||
* @param node NzTreeNode
|
||||
*/
|
||||
editApi(node: NzTreeNode): void {
|
||||
this.apiTabComponent.appendTab('edit', node.origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy api data.
|
||||
*
|
||||
@ -264,13 +212,9 @@ export class ApiComponent implements OnInit, OnDestroy {
|
||||
delete data.uuid;
|
||||
delete data.createdAt;
|
||||
data.name += ' Copy';
|
||||
this.apiDataService.create(data).subscribe((result: ApiData) => {
|
||||
this.buildGroupTreeData();
|
||||
this.apiTabComponent.appendTab('edit', {
|
||||
title: result.name,
|
||||
key: result.uuid,
|
||||
method: result.method,
|
||||
});
|
||||
window.sessionStorage.setItem('apiDataWillbeSave', JSON.stringify(data));
|
||||
this.tabSerive.apiEvent$.next({
|
||||
action: 'newApi',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
|
@ -17,7 +17,7 @@
|
||||
<p class="api_line">Rest 参数</p>
|
||||
<eo-api-detail-rest [model]="apiData.restParams"></eo-api-detail-rest>
|
||||
</div>
|
||||
<div *ngIf="apiData.requestBody && apiData.requestBody.length">
|
||||
<div *ngIf="apiData.requestBody?.length">
|
||||
<div class="api_line">
|
||||
Body 请求参数<nz-tag class="ml10" nzColor="default">{{ CONST.BODY_TYPE[apiData.requestBodyType] }}</nz-tag>
|
||||
<nz-tag *ngIf="apiData.requestBodyType==='json'" nzColor="default">最外层结构为:{{ CONST.JSON_ROOT_TYPE[apiData.requestBodyJsonType] }}</nz-tag>
|
||||
|
@ -51,7 +51,9 @@
|
||||
<nz-tab [nzTitle]="headerTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #headerTitleTmp>
|
||||
请求头部
|
||||
<span class="eo-tab-icon">{{ apiData.requestHeaders | apiParamsNum }}</span>
|
||||
<span class="eo-tab-icon" *ngIf="bindGetApiParamNum(apiData.requestHeaders)">{{
|
||||
apiData.requestHeaders | apiParamsNum
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-edit-header class="eo_theme_iblock bbd bld brd" [model]="apiData.requestHeaders"></eo-api-edit-header>
|
||||
</nz-tab>
|
||||
@ -59,7 +61,14 @@
|
||||
<nz-tab [nzTitle]="bodyTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #bodyTitleTmp>
|
||||
请求体
|
||||
<span class="eo-tab-icon">{{ apiData.requestBody | apiParamsNum }}</span>
|
||||
<span
|
||||
class="iconfont icon-circle eo-tab-theme-icon"
|
||||
*ngIf="
|
||||
['formData', 'json', 'xml'].includes(apiData.requestBodyType)
|
||||
? bindGetApiParamNum(apiData.requestBody)
|
||||
: apiData.requestBody?.length
|
||||
"
|
||||
></span>
|
||||
</ng-template>
|
||||
<eo-api-edit-body
|
||||
class="eo_theme_iblock bbd bld brd"
|
||||
@ -72,32 +81,38 @@
|
||||
<nz-tab [nzTitle]="queryTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #queryTitleTmp>
|
||||
Query 参数
|
||||
<span class="eo-tab-icon">{{ apiData.queryParams | apiParamsNum }}</span>
|
||||
<span class="eo-tab-icon" *ngIf="bindGetApiParamNum(apiData.queryParams)">{{
|
||||
apiData.queryParams | apiParamsNum
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-edit-query class="eo_theme_iblock bbd bld brd" [model]="apiData.queryParams"></eo-api-edit-query>
|
||||
</nz-tab>
|
||||
<nz-tab [nzTitle]="restTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #restTitleTmp>
|
||||
REST 参数
|
||||
<span class="eo-tab-icon">{{ apiData.restParams | apiParamsNum }}</span>
|
||||
<span class="eo-tab-icon" *ngIf="bindGetApiParamNum(apiData.restParams)">{{
|
||||
apiData.restParams | apiParamsNum
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-edit-rest class="eo_theme_iblock bbd bld brd" [model]="apiData.restParams"></eo-api-edit-rest>
|
||||
</nz-tab>
|
||||
</nz-tabset>
|
||||
</nz-collapse-panel>
|
||||
</nz-collapse>
|
||||
<!-- 响应参数 -->
|
||||
<!-- 响应内容 -->
|
||||
<nz-collapse class="eo_collapse mt40" [nzGhost]="true">
|
||||
<nz-collapse-panel #panel [nzActive]="true" nzHeader="响应内容" nzShowArrow="false" [nzExtra]="extraTpl">
|
||||
<ng-template #extraTpl>
|
||||
{{ panel.nzActive ? '收缩' : '展开' }}
|
||||
<span class="iconfont icon-chevron-{{ panel.nzActive ? 'up' : 'down' }}"></span>
|
||||
<nz-collapse-panel #panelRes [nzActive]="true" nzHeader="响应内容" nzShowArrow="false" [nzExtra]="extraTplRes">
|
||||
<ng-template #extraTplRes>
|
||||
{{ panelRes.nzActive ? '收缩' : '展开' }}
|
||||
<span class="iconfont icon-chevron-{{ panelRes.nzActive ? 'up' : 'down' }}"></span>
|
||||
</ng-template>
|
||||
<nz-tabset [nzAnimated]="false" [nzSelectedIndex]="1" class="mt10">
|
||||
<nz-tab [nzTitle]="responseHeaderTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #responseHeaderTitleTmp>
|
||||
返回头部
|
||||
<span class="eo-tab-icon">{{ apiData.responseHeaders | apiParamsNum }}</span>
|
||||
<span class="eo-tab-icon" *ngIf="bindGetApiParamNum(apiData.responseHeaders)">{{
|
||||
apiData.responseHeaders | apiParamsNum
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-edit-header
|
||||
class="eo_theme_iblock bbd bld brd"
|
||||
@ -107,7 +122,14 @@
|
||||
<nz-tab [nzTitle]="responseTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #responseTitleTmp>
|
||||
返回结果
|
||||
<span class="eo-tab-icon">{{ apiData.responseBody | apiParamsNum }}</span>
|
||||
<span
|
||||
class="iconfont icon-circle eo-tab-theme-icon"
|
||||
*ngIf="
|
||||
['formData', 'json', 'xml'].includes(apiData.responseBodyType)
|
||||
? bindGetApiParamNum(apiData.responseBody)
|
||||
: apiData.responseBody?.length
|
||||
"
|
||||
></span>
|
||||
</ng-template>
|
||||
<eo-api-edit-body
|
||||
class="eo_theme_iblock bbd bld brd"
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
import { NzMessageService } from 'ng-zorro-antd/message';
|
||||
import { NzTreeSelectComponent } from 'ng-zorro-antd/tree-select';
|
||||
|
||||
import { Observable, of, Subject } from 'rxjs';
|
||||
import { switchMap, debounceTime, take, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, take, takeUntil, pairwise, filter } from 'rxjs/operators';
|
||||
|
||||
import { ApiEditRest } from '../../../shared/services/api-data/api-edit-params.model';
|
||||
import { ApiData, RequestProtocol, RequestMethod } from '../../../shared/services/api-data/api-data.model';
|
||||
@ -15,10 +15,12 @@ import { MessageService } from '../../../shared/services/message';
|
||||
|
||||
import { Group } from '../../../shared/services/group/group.model';
|
||||
import { GroupService } from '../../../shared/services/group/group.service';
|
||||
import { ApiTabService } from '../tab/api-tab.service';
|
||||
|
||||
import { objectToArray,getRest } from '../../../utils';
|
||||
import { objectToArray } from '../../../utils';
|
||||
import { getRest } from '../../../utils/api';
|
||||
import { treeToListHasLevel, listToTree, listToTreeHasLevel } from '../../../utils/tree';
|
||||
|
||||
import { ApiParamsNumPipe } from '../../../shared/pipes/api-param-num.pipe';
|
||||
@Component({
|
||||
selector: 'eo-api-edit-edit',
|
||||
templateUrl: './api-edit.component.html',
|
||||
@ -33,7 +35,6 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
REQUEST_METHOD = objectToArray(RequestMethod);
|
||||
REQUEST_PROTOCOL = objectToArray(RequestProtocol);
|
||||
|
||||
private api$: Observable<object>;
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
private changeGroupID$: Subject<string | number> = new Subject();
|
||||
|
||||
@ -41,10 +42,10 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
private storage: ApiDataService,
|
||||
private route: ActivatedRoute,
|
||||
private fb: FormBuilder,
|
||||
private router: Router,
|
||||
private message: NzMessageService,
|
||||
private messageService: MessageService,
|
||||
private groupService: GroupService
|
||||
private groupService: GroupService,
|
||||
private apiTab: ApiTabService
|
||||
) {}
|
||||
getApiGroup() {
|
||||
this.groups = [];
|
||||
@ -115,22 +116,37 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.editApi(formData);
|
||||
}
|
||||
|
||||
bindGetApiParamNum(params) {
|
||||
return new ApiParamsNumPipe().transform(params);
|
||||
}
|
||||
ngOnInit(): void {
|
||||
this.getApiGroup();
|
||||
this.resetApi();
|
||||
this.initApi(Number(this.route.snapshot.queryParams.uuid));
|
||||
this.watchTabChange();
|
||||
this.watchGroupIDChange();
|
||||
this.watchUri();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
private initApi(id) {
|
||||
this.resetForm();
|
||||
this.initBasicForm();
|
||||
if (this.route.snapshot.queryParams.uuid) {
|
||||
//Edit
|
||||
this.watchQueryChange();
|
||||
} else {
|
||||
let testData = window.sessionStorage.getItem('testDataToAPI');
|
||||
if (testData) {
|
||||
//Add From Test
|
||||
Object.assign(
|
||||
this.apiData,
|
||||
JSON.parse(testData)
|
||||
);
|
||||
//recovery from tab
|
||||
if (this.apiTab.currentTab && this.apiTab.tabCache[this.apiTab.tabID]) {
|
||||
let tabData = this.apiTab.tabCache[this.apiTab.tabID];
|
||||
this.apiData = tabData.apiData;
|
||||
return;
|
||||
}
|
||||
if (!id) {
|
||||
let tmpApiData = window.sessionStorage.getItem('apiDataWillbeSave');
|
||||
if (tmpApiData) {
|
||||
//Add From Test|Copy Api
|
||||
window.sessionStorage.removeItem('apiDataWillbeSave');
|
||||
Object.assign(this.apiData, JSON.parse(tmpApiData));
|
||||
this.validateForm.patchValue(this.apiData);
|
||||
} else {
|
||||
//Add directly
|
||||
Object.assign(this.apiData, {
|
||||
@ -146,70 +162,56 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
responseBody: [],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.getApi(id);
|
||||
}
|
||||
|
||||
}
|
||||
private watchTabChange() {
|
||||
this.apiTab.tabChange$
|
||||
.pipe(
|
||||
pairwise(),
|
||||
//actually change tab,not init tab
|
||||
filter((data) => data[0].uuid !== data[1].uuid),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
.subscribe(([nowTab, nextTab]) => {
|
||||
this.apiTab.saveTabData$.next({
|
||||
tab: nowTab,
|
||||
data: {
|
||||
apiData: this.apiData,
|
||||
},
|
||||
});
|
||||
this.initApi(nextTab.key);
|
||||
});
|
||||
}
|
||||
private watchGroupIDChange() {
|
||||
this.changeGroupID$.pipe(debounceTime(500), take(1)).subscribe((id) => {
|
||||
this.apiData.groupID = (this.apiData.groupID === 0 ? -1 : this.apiData.groupID).toString();
|
||||
this.expandGroup();
|
||||
});
|
||||
this.validateForm
|
||||
.get('uri')
|
||||
.valueChanges.pipe(debounceTime(500), takeUntil(this.destroy$))
|
||||
.subscribe((url) => {
|
||||
this.changeUri(url);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
private watchQueryChange() {
|
||||
this.api$ = this.route.queryParamMap.pipe(
|
||||
switchMap((params) => {
|
||||
const id = Number(params.get('uuid'));
|
||||
if (!id) {
|
||||
const groupID = params.get('groupID');
|
||||
if (groupID) {
|
||||
return of({
|
||||
groupID,
|
||||
});
|
||||
}
|
||||
return of();
|
||||
}
|
||||
return of({ id });
|
||||
}),
|
||||
takeUntil(this.destroy$)
|
||||
);
|
||||
this.api$.subscribe({
|
||||
next: (inArg: any = {}) => {
|
||||
if (inArg.id) {
|
||||
this.getApi(inArg.id);
|
||||
}
|
||||
if (inArg.groupID) {
|
||||
this.apiData.groupID = inArg.groupID;
|
||||
this.changeGroupID$.next(this.apiData.groupID);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Generate Rest Param From Url
|
||||
*/
|
||||
private changeUri(url) {
|
||||
const rests = getRest(url);
|
||||
rests.forEach((newRest) => {
|
||||
if (this.apiData.restParams.find((val: ApiEditRest) => val.name === newRest)) {
|
||||
return;
|
||||
}
|
||||
const restItem: ApiEditRest = {
|
||||
name: newRest,
|
||||
required: true,
|
||||
example: '',
|
||||
description: '',
|
||||
};
|
||||
this.apiData.restParams.splice(this.apiData.restParams.length - 1, 0, restItem);
|
||||
});
|
||||
private watchUri() {
|
||||
this.validateForm
|
||||
.get('uri')
|
||||
.valueChanges.pipe(debounceTime(500), takeUntil(this.destroy$))
|
||||
.subscribe((url) => {
|
||||
const rests = getRest(url);
|
||||
rests.forEach((newRest) => {
|
||||
if (this.apiData.restParams.find((val: ApiEditRest) => val.name === newRest)) {
|
||||
return;
|
||||
}
|
||||
const restItem: ApiEditRest = {
|
||||
name: newRest,
|
||||
required: true,
|
||||
example: '',
|
||||
description: '',
|
||||
};
|
||||
this.apiData.restParams.splice(this.apiData.restParams.length - 1, 0, restItem);
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Reset Group ID after group list load
|
||||
@ -250,25 +252,24 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
/**
|
||||
* Init API data structure
|
||||
*/
|
||||
private resetApi() {
|
||||
private resetForm() {
|
||||
this.apiData = {
|
||||
name: '',
|
||||
projectID: 1,
|
||||
uri: '/',
|
||||
groupID: this.route.snapshot.queryParams.groupID||'-1',
|
||||
groupID: this.route.snapshot.queryParams.groupID || '-1',
|
||||
protocol: RequestProtocol.HTTP,
|
||||
method: RequestMethod.POST,
|
||||
};
|
||||
}
|
||||
|
||||
private editApi(formData) {
|
||||
const busEvent = formData.uuid ? 'editApi' : 'apiAdd';
|
||||
const busEvent = formData.uuid ? 'editApi' : 'addApi';
|
||||
const title = busEvent === 'editApi' ? '编辑成功' : '新增成功';
|
||||
this.storage[busEvent === 'editApi' ? 'update' : 'create'](formData, this.apiData.uuid).subscribe(
|
||||
(result: ApiData) => {
|
||||
this.message.success(title);
|
||||
this.messageService.send({ type: busEvent, data: result });
|
||||
this.router.navigate(['/home/api/detail'], { queryParams: { uuid: result.uuid } });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -213,11 +213,12 @@ export class ApiEditService {
|
||||
{
|
||||
key: '插入',
|
||||
operateName: 'insert',
|
||||
itemExpression: `ng-if="!($ctrl.mainObject.setting.munalHideOperateColumn&&$first)"`,
|
||||
itemExpression: `ng-if="!($ctrl.mainObject.setting.munalHideOperateColumn&&$first)"`
|
||||
},
|
||||
{
|
||||
key: '删除',
|
||||
operateName: 'delete',
|
||||
itemExpression: 'ng-if="!($ctrl.mainObject.setting.munalHideOperateColumn&&$first)"'
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -22,7 +22,7 @@
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
<ul nz-menu>
|
||||
<li nz-menu-item (click)="onClick({ event: $event, eventName: 'newApi' })"><a>新建API</a></li>
|
||||
<li nz-menu-item (click)="onClick({ event: $event, eventName: 'newApiTest' })"><a>新建测试</a></li>
|
||||
<!-- <li nz-menu-item (click)="onClick({ event: $event, eventName: 'newApiTest' })"><a>新建测试</a></li> -->
|
||||
<li nz-menu-item (click)="newGroup()"><a>新建分组</a></li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
@ -48,7 +48,7 @@
|
||||
<div class="tree_node f_row f_js_ac" *ngIf="!node.isLeaf">
|
||||
<div class="f_row_ac">
|
||||
<span class="iconfont icon-folder-outline fs16 mr5"></span>
|
||||
<span>{{ node.title }}</span>
|
||||
<span class="text_omit node_title">{{ node.title }}</span>
|
||||
</div>
|
||||
<span class="tree_node_operate">
|
||||
<button nz-dropdown [nzDropdownMenu]="groupMenu">
|
||||
@ -75,8 +75,10 @@
|
||||
<!-- Leaf -->
|
||||
<div class="tree_node f_row f_js_ac" *ngIf="node.isLeaf">
|
||||
<div class="f_row_ac">
|
||||
<b class="method_text method_text_{{ node.origin.method }} mr5" *ngIf="node.origin.method">{{node.origin.method.slice(0, 4)}}</b>
|
||||
{{ node.title }}
|
||||
<b class="method_text method_text_{{ node.origin.method }} mr5" *ngIf="node.origin.method">{{
|
||||
node.origin.method.slice(0, 4)
|
||||
}}</b>
|
||||
<span class="text_omit node_title">{{ node.title }}</span>
|
||||
</div>
|
||||
<span class="tree_node_operate">
|
||||
<button>
|
||||
|
@ -9,6 +9,9 @@
|
||||
.method_text{
|
||||
width: 32px;
|
||||
}
|
||||
.node_title{
|
||||
max-width: 145px;
|
||||
}
|
||||
.tree_node {
|
||||
font-size: 12px;
|
||||
.tree_node_operate {
|
||||
|
@ -6,7 +6,6 @@
|
||||
(nzSelectChange)="switchTab()"
|
||||
[nzTabBarExtraContent]="extraTemplate"
|
||||
>
|
||||
|
||||
<nz-tab *ngFor="let tab of tabs; let i = index" nzClosable [nzTitle]="titleTemplate">
|
||||
<ng-template #titleTemplate>
|
||||
<span class="mr5 method_text_{{ tab.method }}" *ngIf="tab.method">{{ tab.method.slice(0, 4) }}</span>
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
}
|
||||
.ant-tabs-nav-wrap {
|
||||
width: calc(100% - 135px);
|
||||
max-width: calc(100% - 135px);
|
||||
flex: none;
|
||||
}
|
||||
.ant-tabs-nav-add {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { Component, OnInit, Input, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';
|
||||
|
||||
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
||||
|
||||
import { TabItem } from './tab.model';
|
||||
import { ApiTabService } from './api-tab.service';
|
||||
import { filter } from 'rxjs';
|
||||
import { filter, Subject, takeUntil } from 'rxjs';
|
||||
@Component({
|
||||
selector: 'eo-api-tab',
|
||||
templateUrl: './api-tab.component.html',
|
||||
styleUrls: ['./api-tab.component.scss'],
|
||||
})
|
||||
export class ApiTabComponent implements OnInit, OnChanges {
|
||||
export class ApiTabComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() apiDataItems;
|
||||
id: number;
|
||||
/**
|
||||
@ -32,30 +32,20 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
};
|
||||
MAX_LIMIT = 15;
|
||||
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
constructor(private router: Router, private route: ActivatedRoute, private tabSerive: ApiTabService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.watchChangeRouter();
|
||||
this.watchApiAction();
|
||||
}
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.apiDataItems && changes.apiDataItems.currentValue) {
|
||||
if (changes.apiDataItems && !changes.apiDataItems.previousValue && changes.apiDataItems.currentValue) {
|
||||
this.initTab();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* path change
|
||||
*/
|
||||
watchChangeRouter() {
|
||||
this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe((event: NavigationEnd) => {
|
||||
this.id = Number(this.route.snapshot.queryParams.uuid);
|
||||
if (!this.id) return;
|
||||
this.tabs[this.selectedIndex] = Object.assign(
|
||||
{
|
||||
uuid: this.tabs[this.selectedIndex].uuid,
|
||||
},
|
||||
this.getTabInfoByID(this.id)
|
||||
);
|
||||
});
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
/**
|
||||
* Create a new tab.
|
||||
@ -67,14 +57,16 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
* Init tab data after load or update.
|
||||
*/
|
||||
initTab() {
|
||||
this.id = Number(this.route.snapshot.queryParams.uuid);
|
||||
if (this.id) {
|
||||
let apiHasDelete = !this.apiDataItems[this.id];
|
||||
if (apiHasDelete) {
|
||||
let apiID = Number(this.route.snapshot.queryParams.uuid);
|
||||
if (apiID) {
|
||||
let hasApiExist = this.apiDataItems[apiID];
|
||||
if (!hasApiExist) {
|
||||
this.closeTab({ index: this.selectedIndex });
|
||||
return;
|
||||
}
|
||||
const tab = this.getTabInfoByID(this.id);
|
||||
const tab = this.getTabInfo({
|
||||
id: apiID,
|
||||
});
|
||||
this.appendTab('unset', tab);
|
||||
} else {
|
||||
let module = Object.keys(this.defaultTabs).find((keyName) =>
|
||||
@ -88,7 +80,7 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
*
|
||||
* @param tab TabItem
|
||||
*/
|
||||
appendTab(which = 'test', apiData = {}): void {
|
||||
appendTab(which = 'test', apiData: any = {}): void {
|
||||
if (this.tabs.length >= this.MAX_LIMIT) return;
|
||||
let tab: TabItem = Object.assign(
|
||||
{
|
||||
@ -100,15 +92,20 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
let existTabIndex = this.tabs.findIndex((val) => val.key === tab.key);
|
||||
if (tab.key && existTabIndex !== -1) {
|
||||
this.selectedIndex = existTabIndex;
|
||||
if (this.tabs[existTabIndex].path !== tab.path) {
|
||||
//exist api(same tab) change page
|
||||
this.tabs[existTabIndex].path = tab.path;
|
||||
this.switchTab();
|
||||
}
|
||||
return;
|
||||
}
|
||||
let hasTab = this.tabs.length > 0;
|
||||
this.tabs.push(tab);
|
||||
if (hasTab) {
|
||||
this.selectedIndex = this.tabs.length - 1;
|
||||
} else {
|
||||
// if index no change,manual change reflesh content
|
||||
if (this.selectedIndex === this.tabs.length - 1) {
|
||||
this.switchTab();
|
||||
return;
|
||||
}
|
||||
this.selectedIndex = this.tabs.length - 1;
|
||||
}
|
||||
/**
|
||||
* Remove api data tabs.
|
||||
@ -118,7 +115,7 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
removeApiDataTabs(uuids: Array<string | number>): void {
|
||||
const items = [];
|
||||
this.tabs.forEach((tab: TabItem, index: number) => {
|
||||
if (uuids.indexOf(tab.key)) {
|
||||
if (uuids.includes(tab.key)) {
|
||||
items.push({ index });
|
||||
}
|
||||
});
|
||||
@ -127,19 +124,27 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Close current tab.
|
||||
* Close Tab and keep tab status
|
||||
*
|
||||
* @param index number
|
||||
*/
|
||||
closeTab({ index }: { index: number }): void {
|
||||
this.tabSerive.removeData(this.tabs[index].uuid);
|
||||
if (this.tabs[index]) {
|
||||
this.tabSerive.removeData(this.tabs[index].uuid);
|
||||
}
|
||||
this.tabs.splice(index, 1);
|
||||
//no tab left
|
||||
if (0 === this.tabs.length) {
|
||||
this.newTab();
|
||||
return;
|
||||
}
|
||||
//selectedIndex no change
|
||||
if (this.selectedIndex < this.tabs.length) {
|
||||
this.switchTab();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Switch the tab.
|
||||
* router change after switch the tab or tab content
|
||||
* @param {TabItem} inArg.tab
|
||||
* @param inArg.index
|
||||
*/
|
||||
@ -148,7 +153,61 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
this.tabSerive.tabChange$.next(tab);
|
||||
this.activeRoute(tab);
|
||||
}
|
||||
|
||||
/**
|
||||
* Api Operation triggle tab change
|
||||
*/
|
||||
private watchApiAction() {
|
||||
this.tabSerive.apiEvent$.pipe(takeUntil(this.destroy$)).subscribe((inArg) => {
|
||||
console.log('watchApiAction', inArg);
|
||||
switch (inArg.action) {
|
||||
case 'newApiTest':
|
||||
case 'testApi':
|
||||
this.appendTab('test', inArg.data.origin);
|
||||
break;
|
||||
case 'detailApi':
|
||||
this.appendTab('detail', inArg.data.origin);
|
||||
break;
|
||||
case 'editApi':
|
||||
this.appendTab('edit', inArg.data.origin);
|
||||
break;
|
||||
case 'newApi':
|
||||
this.appendTab('edit', inArg.data ? { groupID: inArg.data.key } : {});
|
||||
break;
|
||||
case 'addApiFromTest': {
|
||||
this.changeCurrentTab(
|
||||
this.getTabInfo({
|
||||
path: this.defaultTabs['edit'].path,
|
||||
apiData: inArg.data,
|
||||
})
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'addApiFinish':
|
||||
case 'editApiFinish': {
|
||||
this.changeCurrentTab(
|
||||
this.getTabInfo({
|
||||
path: this.defaultTabs['detail'].path,
|
||||
apiData: inArg.data,
|
||||
})
|
||||
);
|
||||
this.switchTab();
|
||||
break;
|
||||
}
|
||||
case 'removeApiDataTabs': {
|
||||
this.removeApiDataTabs(inArg.data);
|
||||
break;
|
||||
}
|
||||
case 'beforeChangeRouter': {
|
||||
this.changeCurrentTab(
|
||||
this.getTabInfo({
|
||||
id: Number(this.route.snapshot.queryParams.uuid),
|
||||
})
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Action new tab route.
|
||||
*
|
||||
@ -161,13 +220,22 @@ export class ApiTabComponent implements OnInit, OnChanges {
|
||||
})
|
||||
.finally();
|
||||
}
|
||||
|
||||
private getTabInfoByID(id) {
|
||||
private changeCurrentTab(tabInfo) {
|
||||
this.tabs[this.selectedIndex] = Object.assign(this.tabs[this.selectedIndex], tabInfo);
|
||||
}
|
||||
/**
|
||||
* Get tab info by api id or api data
|
||||
* @param inArg.id exist api id
|
||||
* @param apiData tab content api data
|
||||
* @returns {TabItem}
|
||||
*/
|
||||
private getTabInfo(inArg: { id?: number; apiData?: any; path?: string }) {
|
||||
let apiData = inArg.apiData || this.apiDataItems[inArg.id];
|
||||
const result = {
|
||||
path: this.router.url.split('?')[0],
|
||||
title: this.apiDataItems[id].name,
|
||||
method: this.apiDataItems[id].method,
|
||||
key: this.apiDataItems[id].uuid,
|
||||
path: inArg.path || this.router.url.split('?')[0],
|
||||
title: apiData.name,
|
||||
method: apiData.method,
|
||||
key: apiData.uuid,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
@ -4,9 +4,12 @@ import { TabItem } from './tab.model';
|
||||
export class ApiTabService {
|
||||
currentTab: TabItem;
|
||||
tabCache = {};
|
||||
/**
|
||||
* Tab Or Tab Content Change
|
||||
*/
|
||||
tabChange$: ReplaySubject<TabItem> = new ReplaySubject(1);
|
||||
saveTabData$: Subject<{ tab: TabItem; data: any }> = new Subject();
|
||||
|
||||
apiEvent$: Subject<{ action: string; data?: any }> = new Subject();
|
||||
get tabID(): number {
|
||||
return this.currentTab.uuid;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
<input
|
||||
type="text"
|
||||
name="uri"
|
||||
id="uri"
|
||||
nz-input
|
||||
formControlName="uri"
|
||||
[(ngModel)]="apiData.uri"
|
||||
@ -33,7 +32,16 @@
|
||||
{{ status === 'testing' ? '终止' : '发送' }}
|
||||
<span *ngIf="status === 'testing' && waitSeconds" class="ml5">{{ waitSeconds }}</span>
|
||||
</button>
|
||||
<button type="button" *ngIf="!apiData.uuid" nz-button nzType="default" (click)="saveTestDataToApi()" class="ml10">保存为新 API</button>
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="!apiData.uuid"
|
||||
nz-button
|
||||
nzType="default"
|
||||
(click)="saveTestDataToApi()"
|
||||
class="ml10"
|
||||
>
|
||||
保存为新 API
|
||||
</button>
|
||||
</nz-input-group>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
@ -45,7 +53,9 @@
|
||||
<nz-tab [nzTitle]="headerTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #headerTitleTmp>
|
||||
请求头部
|
||||
<span class="eo-tab-icon">{{ apiData.requestHeaders | apiParamsNum }}</span>
|
||||
<span class="eo-tab-icon" *ngIf="bindGetApiParamNum(apiData.requestHeaders)">{{
|
||||
apiData.requestHeaders | apiParamsNum
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-test-header class="eo_theme_iblock bbd" [model]="apiData.requestHeaders"></eo-api-test-header>
|
||||
</nz-tab>
|
||||
@ -53,7 +63,14 @@
|
||||
<nz-tab [nzTitle]="bodyTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #bodyTitleTmp>
|
||||
请求体
|
||||
<span class="eo-tab-icon">{{ apiData.requestBody | apiParamsNum }}</span>
|
||||
<span
|
||||
class="iconfont icon-circle eo-tab-theme-icon"
|
||||
*ngIf="
|
||||
['formData', 'json', 'xml'].includes(apiData.requestBodyType)
|
||||
? bindGetApiParamNum(apiData.requestBody)
|
||||
: apiData.requestBody?.length
|
||||
"
|
||||
></span>
|
||||
</ng-template>
|
||||
<eo-api-test-body
|
||||
class="eo_theme_iblock bbd"
|
||||
@ -66,7 +83,9 @@
|
||||
<nz-tab [nzTitle]="queryTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #queryTitleTmp>
|
||||
Query 参数
|
||||
<span class="eo-tab-icon">{{ apiData.queryParams | apiParamsNum }}</span>
|
||||
<span class="eo-tab-icon" *ngIf="bindGetApiParamNum(apiData.queryParams)">{{
|
||||
apiData.queryParams | apiParamsNum
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-test-query
|
||||
class="eo_theme_iblock bbd"
|
||||
@ -77,7 +96,9 @@
|
||||
<nz-tab [nzTitle]="restTitleTmp" [nzForceRender]="true">
|
||||
<ng-template #restTitleTmp>
|
||||
REST 参数
|
||||
<span class="eo-tab-icon">{{ apiData.restParams | apiParamsNum }}</span>
|
||||
<span class="eo-tab-icon" *ngIf="bindGetApiParamNum(apiData.restParams)">{{
|
||||
apiData.restParams | apiParamsNum
|
||||
}}</span>
|
||||
</ng-template>
|
||||
<eo-api-test-rest class="eo_theme_iblock bbd" [model]="apiData.restParams"></eo-api-test-rest>
|
||||
</nz-tab>
|
||||
@ -85,7 +106,7 @@
|
||||
<!-- 响应信息 -->
|
||||
<nz-tabset
|
||||
[nzTabBarStyle]="{ 'padding-left': '10px' }"
|
||||
[(nzSelectedIndex)]="this.tabIndexRes"
|
||||
[(nzSelectedIndex)]="tabIndexRes"
|
||||
[nzAnimated]="false"
|
||||
class="mt10"
|
||||
>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, OnInit, OnDestroy, ChangeDetectorRef, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Select } from '@ngxs/store';
|
||||
|
||||
@ -8,7 +8,7 @@ import { ApiData, RequestMethod, RequestProtocol } from '../../../shared/service
|
||||
import { MessageService } from '../../../shared/services/message';
|
||||
|
||||
import { interval, Subscription, Observable, of, Subject } from 'rxjs';
|
||||
import { take, takeUntil, distinctUntilChanged, pairwise } from 'rxjs/operators';
|
||||
import { take, takeUntil, distinctUntilChanged, pairwise, filter } from 'rxjs/operators';
|
||||
|
||||
import { ApiTestHistoryComponent } from './history/api-test-history.component';
|
||||
|
||||
@ -19,6 +19,7 @@ import { ApiTabService } from '../tab/api-tab.service';
|
||||
import { objectToArray } from '../../../utils';
|
||||
|
||||
import { EnvState } from '../../../shared/store/env.state';
|
||||
import { ApiParamsNumPipe } from '../../../shared/pipes/api-param-num.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'eo-api-test',
|
||||
@ -47,18 +48,16 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
|
||||
private status$: Subject<string> = new Subject<string>();
|
||||
private timer$: Subscription;
|
||||
private api$: Observable<object>;
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private router: Router,
|
||||
private testServerService: TestServerService,
|
||||
private storage: ApiDataService,
|
||||
private route: ActivatedRoute,
|
||||
private messageService: MessageService,
|
||||
private ref: ChangeDetectorRef,
|
||||
private apiTest: ApiTestService,
|
||||
private apiTab: ApiTabService
|
||||
private apiTab: ApiTabService,
|
||||
private testServerService: TestServerService,
|
||||
private messageService: MessageService
|
||||
) {
|
||||
this.testServer = this.testServerService.getService();
|
||||
this.testServer.init((message) => {
|
||||
@ -105,8 +104,8 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
history: this.testResult,
|
||||
testData: this.apiData,
|
||||
});
|
||||
window.sessionStorage.setItem('testDataToAPI', JSON.stringify(apiData));
|
||||
this.router.navigate(['/home/api/edit']);
|
||||
window.sessionStorage.setItem('apiDataWillbeSave', JSON.stringify(apiData));
|
||||
this.apiTab.apiEvent$.next({action:'addApiFromTest',data:apiData})
|
||||
}
|
||||
changeQuery() {
|
||||
this.apiData.uri = this.apiTest.transferUrlAndQuery(this.apiData.uri, this.apiData.queryParams, {
|
||||
@ -120,6 +119,9 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
replaceType: 'replace',
|
||||
}).query;
|
||||
}
|
||||
bindGetApiParamNum(params) {
|
||||
return new ApiParamsNumPipe().transform(params);
|
||||
}
|
||||
ngOnInit(): void {
|
||||
this.initApi(Number(this.route.snapshot.queryParams.uuid));
|
||||
this.watchTabChange();
|
||||
@ -215,16 +217,23 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
private watchTabChange() {
|
||||
this.apiTab.tabChange$.pipe(pairwise(), takeUntil(this.destroy$)).subscribe(([nowTab, nextTab]) => {
|
||||
this.apiTab.saveTabData$.next({
|
||||
tab: nowTab,
|
||||
data: {
|
||||
apiData: this.apiData,
|
||||
testResult: this.testResult,
|
||||
},
|
||||
this.apiTab.tabChange$
|
||||
.pipe(
|
||||
pairwise(),
|
||||
//actually change tab,not init tab
|
||||
filter((data) => data[0].uuid !== data[1].uuid),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
.subscribe(([nowTab, nextTab]) => {
|
||||
this.apiTab.saveTabData$.next({
|
||||
tab: nowTab,
|
||||
data: {
|
||||
apiData: this.apiData,
|
||||
testResult: this.testResult,
|
||||
},
|
||||
});
|
||||
this.initApi(nextTab.key);
|
||||
});
|
||||
this.initApi(nextTab.key);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Init API data structure
|
||||
|
@ -146,7 +146,7 @@ export class ApiTestService {
|
||||
* @description Add query to URL and read query form url
|
||||
* @param {string} url - whole url include query
|
||||
* @param {object} query - ui query param
|
||||
* @param {string} opts.priority - who's priority higher,url or query
|
||||
* @param {string} opts.priority - which as priority higher,url or query
|
||||
* @param {string} opts.replaceType - replace means only keep replace array,merge means union
|
||||
* @returns {object} - {url:"",query:[]}
|
||||
*/
|
||||
@ -252,7 +252,6 @@ export class ApiTestService {
|
||||
* @returns {ApiData}
|
||||
*/
|
||||
getApiFromTestData(inData) {
|
||||
console.log('getApiFromTestData=>', inData);
|
||||
let testToEditParams = (arr) => {
|
||||
let result = [];
|
||||
arr.forEach((val) => {
|
||||
@ -265,7 +264,7 @@ export class ApiTestService {
|
||||
};
|
||||
let result = {
|
||||
...inData.testData,
|
||||
responseHeaders: [],
|
||||
responseHeaders: inData.history.response.headers,
|
||||
responseBodyType: 'json',
|
||||
responseBodyJsonType: 'object',
|
||||
responseBody: [],
|
||||
@ -281,7 +280,6 @@ export class ApiTestService {
|
||||
result.responseBodyType=bodyInfo.textType;
|
||||
result.responseBodyJsonType=bodyInfo.rootType;
|
||||
}
|
||||
console.log('getApiFromTestData=>', result);
|
||||
return result;
|
||||
}
|
||||
getTestDataFromApi(inData) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({
|
||||
name: 'apiParamsNum',
|
||||
pure: false,
|
||||
|
@ -154,7 +154,6 @@ export class TestServerAPIKitService implements TestServer {
|
||||
env: formatEnv(opts.env),
|
||||
testTime: formatDate(new Date(), 'YYYY-MM-dd HH:mm:ss', this.locale),
|
||||
};
|
||||
console.log(data,result)
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
|
21
src/app/utils/api.ts
Normal file
21
src/app/utils/api.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* get rest param from url,format like {restName}
|
||||
* @param url
|
||||
* @returns {Array[string]}
|
||||
*/
|
||||
export const getRest: (url: string) => string[] = (url) => {
|
||||
return [...url.replace(/{{(.*?)}}/g, '').matchAll(/{(.*?)}/g)].map((val) => val[1]);
|
||||
};
|
||||
|
||||
export const addEnvPrefix = (prefix, uri) => {
|
||||
// * 需要先判断uri是否已经包含 http:// 前缀
|
||||
if (prefix == null) {
|
||||
return uri;
|
||||
}
|
||||
const hasPrefix = /(http|https):\/{2}.+/.test(uri);
|
||||
if (hasPrefix) {
|
||||
return uri;
|
||||
}
|
||||
// * 添加前缀
|
||||
return prefix + uri;
|
||||
};
|
@ -1,25 +1,5 @@
|
||||
export const uuid = (): string => Math.random().toString(36).slice(-8);
|
||||
/**
|
||||
* get rest param from url,format like {restName}
|
||||
* @param url
|
||||
* @returns {Array[string]}
|
||||
*/
|
||||
export const getRest: (url: string) => string[] = (url) => {
|
||||
return [...url.replace(/{{(.*?)}}/g, '').matchAll(/{(.*?)}/g)].map((val) => val[1]);
|
||||
};
|
||||
|
||||
export const addEnvPrefix = (prefix, uri) => {
|
||||
// * 需要先判断uri是否已经包含 http:// 前缀
|
||||
if (prefix == null) {
|
||||
return uri;
|
||||
}
|
||||
const hasPrefix = /(http|https):\/{2}.+/.test(uri);
|
||||
if (hasPrefix) {
|
||||
return uri;
|
||||
}
|
||||
// * 添加前缀
|
||||
return prefix + uri;
|
||||
};
|
||||
|
||||
// const DOMAIN_REGEX =
|
||||
// '(^((http|wss|ws|ftp|https)://))|(^(((http|wss|ws|ftp|https)://)|)(([\\w\\-_]+([\\w\\-\\.]*)?(\\.(' +
|
||||
|
@ -47,7 +47,7 @@ export const treeToListHasLevel = (tree, opts: { listDepth: number; mapItem?: (v
|
||||
val = opts.mapItem(val);
|
||||
}
|
||||
result.push(val);
|
||||
if (val.children && val.children.length) {
|
||||
if (val.children?.length) {
|
||||
result = result.concat(
|
||||
treeToListHasLevel(val.children, {
|
||||
listDepth: opts.listDepth + 1,
|
||||
|
Loading…
Reference in New Issue
Block a user