Merge branch 'feat/preview' of github.com:eolinker/eoapi into feat/preview

This commit is contained in:
scarqin 2022-06-30 18:56:36 +08:00
commit caacb923e9
8 changed files with 47 additions and 49 deletions

View File

@ -5,7 +5,7 @@
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve -c web -o", "start": "ng serve -c web -o",
"start:cn":"ng serve -c webCn -o", "start:cn": "ng serve -c webCn -o",
"build": "node ./build/build.js", "build": "node ./build/build.js",
"build:web": "node ./build/build.js web", "build:web": "node ./build/build.js web",
"ng:serve": "ng serve -c web -o", "ng:serve": "ng serve -c web -o",
@ -76,7 +76,6 @@
"karma-coverage-istanbul-reporter": "3.0.3", "karma-coverage-istanbul-reporter": "3.0.3",
"karma-jasmine": "5.1.0", "karma-jasmine": "5.1.0",
"karma-jasmine-html-reporter": "2.0.0", "karma-jasmine-html-reporter": "2.0.0",
"lodash": "4.17.21",
"node-polyfill-webpack-plugin": "2.0.0", "node-polyfill-webpack-plugin": "2.0.0",
"postcss": "8.4.14", "postcss": "8.4.14",
"tailwindcss": "3.1.4", "tailwindcss": "3.1.4",

View File

@ -3,11 +3,10 @@ import { SafeResourceUrl } from '@angular/platform-browser';
import { SidebarService } from 'eo/workbench/browser/src/app/shared/components/sidebar/sidebar.service'; import { SidebarService } from 'eo/workbench/browser/src/app/shared/components/sidebar/sidebar.service';
import { Message } from 'eo/workbench/browser/src/app/shared/services/message/message.model'; import { Message } from 'eo/workbench/browser/src/app/shared/services/message/message.model';
import { MessageService } from 'eo/workbench/browser/src/app/shared/services/message/message.service'; import { MessageService } from 'eo/workbench/browser/src/app/shared/services/message/message.service';
import { Subject, takeUntil } from 'rxjs'; import { Subject, takeUntil, debounceTime } from 'rxjs';
import { isElectron } from 'eo/shared/common/common'; import { isElectron } from 'eo/shared/common/common';
import { RemoteService } from 'eo/workbench/browser/src/app/shared/services/remote/remote.service'; import { RemoteService } from 'eo/workbench/browser/src/app/shared/services/remote/remote.service';
import { IS_SHOW_REMOTE_SERVER_NOTIFICATION } from 'eo/workbench/browser/src/app/shared/services/storage/storage.service'; import { IS_SHOW_REMOTE_SERVER_NOTIFICATION } from 'eo/workbench/browser/src/app/shared/services/storage/storage.service';
import { debounce } from 'lodash';
@Component({ @Component({
selector: 'eo-pages', selector: 'eo-pages',
@ -26,6 +25,7 @@ export class PagesComponent implements OnInit {
return this.remoteService.dataSourceText; return this.remoteService.dataSourceText;
} }
private destroy$: Subject<void> = new Subject<void>(); private destroy$: Subject<void> = new Subject<void>();
private rawChange$: Subject<string> = new Subject<string>();
get isShowNotification() { get isShowNotification() {
return !this.isRemote && this.isShow; return !this.isRemote && this.isShow;
} }
@ -35,11 +35,15 @@ export class PagesComponent implements OnInit {
public sidebar: SidebarService, public sidebar: SidebarService,
private messageService: MessageService, private messageService: MessageService,
private remoteService: RemoteService private remoteService: RemoteService
) {} ) {
this.rawChange$.pipe(debounceTime(500), takeUntil(this.destroy$)).subscribe(() => {
this.updateState();
});
}
ngOnInit(): void { ngOnInit(): void {
this.watchSidebarItemChange(); this.watchSidebarItemChange();
this.watchRemoteServerChange(); this.watchRemoteServerChange();
this.updateState(); this.rawChange$.next('');
} }
private watchSidebarItemChange() { private watchSidebarItemChange() {
this.sidebar.appChanged$.subscribe(() => { this.sidebar.appChanged$.subscribe(() => {
@ -48,7 +52,7 @@ export class PagesComponent implements OnInit {
setTimeout(() => { setTimeout(() => {
//add loading //add loading
this.loadedIframe = false; this.loadedIframe = false;
let iframe = document.getElementById('app_iframe') as HTMLIFrameElement; const iframe = document.getElementById('app_iframe') as HTMLIFrameElement;
//load resource //load resource
iframe.src = this.sidebar.currentModule.main; iframe.src = this.sidebar.currentModule.main;
//loading finish //loading finish
@ -65,7 +69,7 @@ export class PagesComponent implements OnInit {
this.remoteService.switchDataSource(); this.remoteService.switchDataSource();
}; };
updateState = debounce(async () => { updateState = async () => {
if (!this.isRemote && localStorage.getItem(IS_SHOW_REMOTE_SERVER_NOTIFICATION) !== 'false') { if (!this.isRemote && localStorage.getItem(IS_SHOW_REMOTE_SERVER_NOTIFICATION) !== 'false') {
const [isSuccess] = await this.remoteService.pingRmoteServerUrl(); const [isSuccess] = await this.remoteService.pingRmoteServerUrl();
this.isShow = isSuccess; this.isShow = isSuccess;
@ -73,7 +77,7 @@ export class PagesComponent implements OnInit {
// if (!) { // if (!) {
// this.isClose = false; // this.isClose = false;
// } // }
}, 500); };
private watchRemoteServerChange() { private watchRemoteServerChange() {
this.messageService this.messageService
@ -82,7 +86,7 @@ export class PagesComponent implements OnInit {
.subscribe((inArg: Message) => { .subscribe((inArg: Message) => {
switch (inArg.type) { switch (inArg.type) {
case 'onDataSourceChange': { case 'onDataSourceChange': {
this.updateState(); this.rawChange$.next(inArg.type);
break; break;
} }
} }

View File

@ -1,3 +1,3 @@
export { DataStorageComponent } from './data-storage.component'; export { DataStorageComponent } from './data-storage.component';
export { LanguageSwticherComponent } from './language-swtcher.componet'; export { LanguageSwticherComponent } from './language-swtcher.component';
export { AboutComponent } from './about.component'; export { AboutComponent } from './about.component';

View File

@ -3,10 +3,9 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { SelectionModel } from '@angular/cdk/collections'; import { SelectionModel } from '@angular/cdk/collections';
import { FlatTreeControl } from '@angular/cdk/tree'; import { FlatTreeControl } from '@angular/cdk/tree';
import { NzTreeFlatDataSource, NzTreeFlattener } from 'ng-zorro-antd/tree-view'; import { NzTreeFlatDataSource, NzTreeFlattener } from 'ng-zorro-antd/tree-view';
import { debounce, cloneDeep } from 'lodash';
import { eoapiSettings } from './eoapi-settings/'; import { eoapiSettings } from './eoapi-settings/';
import { Message, MessageService } from '../../../shared/services/message'; import { Message, MessageService } from '../../../shared/services/message';
import { Subject, takeUntil } from 'rxjs'; import { Subject, takeUntil, debounceTime } from 'rxjs';
import { NzMessageService } from 'ng-zorro-antd/message'; import { NzMessageService } from 'ng-zorro-antd/message';
import { RemoteService } from 'eo/workbench/browser/src/app/shared/services/remote/remote.service'; import { RemoteService } from 'eo/workbench/browser/src/app/shared/services/remote/remote.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
@ -48,11 +47,11 @@ export class SettingComponent implements OnInit {
} }
@Output() isShowModalChange = new EventEmitter<any>(); @Output() isShowModalChange = new EventEmitter<any>();
objectKeys = Object.keys; objectKeys = Object.keys;
/** 是否远程数据源 */ /** Whether the remote data source */
get isRemote() { get isRemote() {
return this.remoteService.isRemote; return this.remoteService.isRemote;
} }
/** 当前数据源对应的文本 */ /** The text corresponding to the current data source */
get dataSourceText() { get dataSourceText() {
return this.remoteService.dataSourceText; return this.remoteService.dataSourceText;
} }
@ -94,7 +93,7 @@ export class SettingComponent implements OnInit {
get settings() { get settings() {
return this.$settings; return this.$settings;
} }
treeNodes = [ readonly treeNodes = [
{ {
name: $localize`:@@DataSource:Data Storage`, name: $localize`:@@DataSource:Data Storage`,
moduleID: 'eoapi-common', moduleID: 'eoapi-common',
@ -159,7 +158,7 @@ export class SettingComponent implements OnInit {
hasChild = (_: number, node: FlatNode): boolean => node.expandable; hasChild = (_: number, node: FlatNode): boolean => node.expandable;
/** /**
* * switch data source
*/ */
switchDataSource() { switchDataSource() {
this.switchDataSourceLoading = true; this.switchDataSourceLoading = true;
@ -170,16 +169,16 @@ export class SettingComponent implements OnInit {
} }
/** /**
* * set data
* *
* @param properties * @param properties
*/ */
private setSettingsModel(properties, controls) { private setSettingsModel(properties, controls) {
// 平级配置对象 // Flat configuration object
Object.keys(properties).forEach((fieldKey) => { Object.keys(properties).forEach((fieldKey) => {
const props = properties[fieldKey]; const props = properties[fieldKey];
this.settings[fieldKey] = this.localSettings?.[fieldKey] ?? props.default; this.settings[fieldKey] = this.localSettings?.[fieldKey] ?? props.default;
// 可扩展加入更多默认校验 // Extensible to add more default checks
if (props.required) { if (props.required) {
controls[fieldKey] = [null, [Validators.required]]; controls[fieldKey] = [null, [Validators.required]];
} else { } else {
@ -207,7 +206,7 @@ export class SettingComponent implements OnInit {
} }
/** /**
* key路径获取对应的配置的值 * Get the value of the corresponding configuration according to the key path
* *
* @param key * @param key
* @returns * @returns
@ -216,7 +215,7 @@ export class SettingComponent implements OnInit {
// return key.split('.').reduce((p, k) => p?.[k], this.nestedSettings); // return key.split('.').reduce((p, k) => p?.[k], this.nestedSettings);
} }
/** /**
* * Get the title of the module
* *
* @param module * @param module
* @returns * @returns
@ -234,15 +233,15 @@ export class SettingComponent implements OnInit {
} }
/** /**
* * Parse the configuration information of all modules
*/ */
private init() { private init() {
// if (!window.eo && !window.eo?.getFeature) { // if (!window.eo && !window.eo?.getFeature) {
// return; // return;
// } // }
// ! this.isVisible = true; // ! this.isVisible = true;
// 获取本地设置 // Get local settings
this.settings = this.localSettings = JSON.parse(localStorage.getItem('localSettings') || '{}'); this.settings = this.localSettings = this.remoteService.getSettings();
// @ts-ignore // @ts-ignore
window.getConfiguration = this.remoteService.getConfiguration; window.getConfiguration = this.remoteService.getConfiguration;
console.log('localSettings', this.localSettings); console.log('localSettings', this.localSettings);
@ -251,9 +250,9 @@ export class SettingComponent implements OnInit {
// const extensitonConfigurations = [...modules.values()].filter((n) => n.contributes?.configuration); // const extensitonConfigurations = [...modules.values()].filter((n) => n.contributes?.configuration);
const extensitonConfigurations = [...modules.values()].filter((n) => n.features?.configuration); const extensitonConfigurations = [...modules.values()].filter((n) => n.features?.configuration);
const controls = {}; const controls = {};
// 所有设置 // All settings
const allSettings = cloneDeep([eoapiSettings['eoapi-extensions']]); const allSettings = structuredClone([eoapiSettings['eoapi-extensions']]);
// 所有配置 // All configure
const allConfiguration = allSettings.map((n) => { const allConfiguration = allSettings.map((n) => {
const configuration = n.features?.configuration || n.contributes?.configuration; const configuration = n.features?.configuration || n.contributes?.configuration;
if (Array.isArray(configuration)) { if (Array.isArray(configuration)) {
@ -275,14 +274,14 @@ export class SettingComponent implements OnInit {
extensionsConfiguration.push(configuration); extensionsConfiguration.push(configuration);
} }
}); });
// 给插件的属性前面追加模块ID // Appends the module ID to the plug-in property
const appendModuleID = (properties, moduleID) => const appendModuleID = (properties, moduleID) =>
Object.keys(properties).reduce((prev, key) => { Object.keys(properties).reduce((prev, key) => {
prev[`${moduleID}.${key}`] = properties[key]; prev[`${moduleID}.${key}`] = properties[key];
return prev; return prev;
}, {}); }, {});
/** 根据configuration配置生成settings model */ /** Generate settings model based on configuration configuration */
allConfiguration.forEach((item) => { allConfiguration.forEach((item) => {
if (Array.isArray(item)) { if (Array.isArray(item)) {
item.forEach((n) => { item.forEach((n) => {
@ -295,7 +294,7 @@ export class SettingComponent implements OnInit {
} }
}); });
type Configuration = typeof allConfiguration[number] | Array<typeof allConfiguration[number]>; type Configuration = typeof allConfiguration[number] | Array<typeof allConfiguration[number]>;
// 递归生成设置树 // Recursively generate the setup tree
const generateTreeData = (configurations: Configuration = []) => const generateTreeData = (configurations: Configuration = []) =>
[].concat(configurations).reduce<TreeNode[]>((prev, curr) => { [].concat(configurations).reduce<TreeNode[]>((prev, curr) => {
if (Array.isArray(curr)) { if (Array.isArray(curr)) {
@ -307,8 +306,8 @@ export class SettingComponent implements OnInit {
}; };
return prev.concat(treeItem); return prev.concat(treeItem);
}, []); }, []);
// 所有设置项 // All settings
const treeData = cloneDeep(this.treeNodes); const treeData = structuredClone(this.treeNodes);
const extensions = treeData.find((n) => n.moduleID === 'eoapi-extensions'); const extensions = treeData.find((n) => n.moduleID === 'eoapi-extensions');
const extensionConfiguration = allSettings[0].features?.configuration || allSettings[0].contributes?.configuration; const extensionConfiguration = allSettings[0].features?.configuration || allSettings[0].contributes?.configuration;
extensions.children = generateTreeData(extensionConfiguration); extensions.children = generateTreeData(extensionConfiguration);
@ -316,8 +315,8 @@ export class SettingComponent implements OnInit {
this.dataSource.setData(treeData); this.dataSource.setData(treeData);
this.treeControl.expandAll(); this.treeControl.expandAll();
this.validateForm = this.fb.group(controls); this.validateForm = this.fb.group(controls);
this.validateForm.valueChanges.subscribe(debounce(this.handleSave.bind(this), 300)); this.validateForm.valueChanges.pipe(debounceTime(300)).subscribe(this.handleSave);
// 默认选中第一项 // The first item is selected by default
this.selectModule(this.treeControl.dataNodes.at(0)); this.selectModule(this.treeControl.dataNodes.at(0));
} }
@ -331,7 +330,7 @@ export class SettingComponent implements OnInit {
this.isShowModal = true; this.isShowModal = true;
} }
handleSave(): void { handleSave = () => {
// for (const i in this.validateForm.controls) { // for (const i in this.validateForm.controls) {
// if (this.validateForm.controls.hasOwnProperty(i)) { // if (this.validateForm.controls.hasOwnProperty(i)) {
// this.validateForm.controls[i].markAsDirty(); // this.validateForm.controls[i].markAsDirty();
@ -343,7 +342,7 @@ export class SettingComponent implements OnInit {
// } // }
localStorage.setItem('localSettings', JSON.stringify(this.settings)); localStorage.setItem('localSettings', JSON.stringify(this.settings));
window.eo?.saveSettings?.({ ...this.settings }); window.eo?.saveSettings?.({ ...this.settings });
} };
async handleCancel() { async handleCancel() {
try { try {
@ -351,15 +350,11 @@ export class SettingComponent implements OnInit {
this.remoteServerUrl !== this.settings['eoapi-common.remoteServer.url'] || this.remoteServerUrl !== this.settings['eoapi-common.remoteServer.url'] ||
this.remoteServerToken !== this.settings['eoapi-common.remoteServer.token'] || this.remoteServerToken !== this.settings['eoapi-common.remoteServer.token'] ||
this.oldDataStorage !== this.settings['eoapi-common.dataStorage']; this.oldDataStorage !== this.settings['eoapi-common.dataStorage'];
console.log(
'isUpdateRemoteInfo',
isUpdateRemoteInfo,
this.settings,
this.remoteServerUrl,
this.remoteServerToken
);
if (isUpdateRemoteInfo) { if (isUpdateRemoteInfo) {
this.message.success('你已修改数据源相关信息页面将在2秒后刷新...'); this.message.success(
'You have modified the data source related information, the page will refresh in 2 seconds...'
);
setTimeout(() => { setTimeout(() => {
this.remoteService.switchDataSource(); this.remoteService.switchDataSource();
this.remoteService.refreshComponent(); this.remoteService.refreshComponent();

View File

@ -80,7 +80,7 @@ export class RemoteService {
} }
/** /**
* * Test if remote server address is available
*/ */
async pingRmoteServerUrl(): Promise<[boolean, any]> { async pingRmoteServerUrl(): Promise<[boolean, any]> {
const { url: remoteUrl, token } = window.eo?.getModuleSettings('eoapi-common.remoteServer') || {}; const { url: remoteUrl, token } = window.eo?.getModuleSettings('eoapi-common.remoteServer') || {};
@ -126,7 +126,7 @@ export class RemoteService {
} }
/** /**
* key路径获取对应的配置的值 * Get the value of the corresponding configuration according to the key path
* *
* @param key * @param key
* @returns * @returns

View File

@ -110,7 +110,7 @@ export interface ApiTestHistoryResponse {
body: string; body: string;
contentType: string; contentType: string;
responseType: 'text' | 'longText' | 'stream'; responseType: 'text' | 'longText' | 'stream';
blobFileName?:string; blobFileName?: string;
responseLength: number; responseLength: number;
testDeny: string; testDeny: string;
/** /**

View File

@ -8064,7 +8064,7 @@ lodash.without@~4.4.0:
resolved "https://registry.npmmirror.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" resolved "https://registry.npmmirror.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
integrity sha512-M3MefBwfDhgKgINVuBJCO1YR3+gf6s9HNJsIiZ/Ru77Ws6uTb9eBuvrkpzO+9iLoAaRodGuq7tyrPCx+74QYGQ== integrity sha512-M3MefBwfDhgKgINVuBJCO1YR3+gf6s9HNJsIiZ/Ru77Ws6uTb9eBuvrkpzO+9iLoAaRodGuq7tyrPCx+74QYGQ==
lodash@4.17.21, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21:
version "4.17.21" version "4.17.21"
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==