@@ -42,19 +38,11 @@

环境变量:在接口文档或测试的过程中,使用{{ varName }}即可引用该环境变量

- + - + diff --git a/src/workbench/browser/src/app/shared/components/env/env.component.scss b/src/workbench/browser/src/app/shared/components/env/env.component.scss index 675c770f7..f34e4075b 100644 --- a/src/workbench/browser/src/app/shared/components/env/env.component.scss +++ b/src/workbench/browser/src/app/shared/components/env/env.component.scss @@ -1,7 +1,15 @@ +$boxHeight: 60vh; +@mixin item-active { + color: var(--MAIN_THEME_COLOR); + background-color: #f4f4f4; + border-color: transparent; + border-radius: 5px; +} + .flex { display: flex; width: 100%; - height: 60vh; + height: $boxHeight; } .b-2 { @@ -11,16 +19,34 @@ .side_bar { display: flex; width: 240px; - overflow-y: auto; .list { width: 100%; + ::ng-deep .ant-list-items { + overflow-y: auto; + max-height: calc($boxHeight - 42px); + } .list_item { cursor: pointer; display: flex; align-items: center; justify-content: space-between; - .active { - color: var(--MAIN_THEME_COLOR); + transition: background-color 0.15s; + + &:hover { + background-color: #f4f4f4; + border-radius: 5px; + } + &:not(:first-of-type) { + border-top: 1px solid #f0f0f0; + } + &:not(:last-of-type) { + border-bottom-color: transparent; + } + &.active { + @include item-active; + &:not(:last-of-type) + .list_item { + border-top-color: transparent; + } } } .footer { @@ -31,8 +57,8 @@ i { color: var(--MAIN_THEME_COLOR); } - &:hover { - background-color: #f4f4f4; + &.active { + @include item-active; } } } diff --git a/src/workbench/browser/src/app/shared/components/setting/common/ConfigurationRegistry.ts b/src/workbench/browser/src/app/shared/components/setting/common/ConfigurationRegistry.ts new file mode 100644 index 000000000..836406cd1 --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/common/ConfigurationRegistry.ts @@ -0,0 +1,8 @@ +/** + * 注册配置项 + */ +class ConfigurationRegistry { + constructor() {} +} + +export const configurationRegistry = new ConfigurationRegistry(); diff --git a/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/common-settings.json b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/common-settings.json new file mode 100644 index 000000000..7292d342b --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/common-settings.json @@ -0,0 +1,24 @@ +{ + "private": true, + "name": "Eoapi-Common", + "version": "0.0.1", + "moduleName": "通用", + "moduleID": "eoapi-common", + "author": "eoapi", + "publisher": "eoapi", + "contributes": { + "configuration": { + "type": "object", + "title": "通用", + "order": 1, + "properties": { + "common.app.autoUpdate": { + "type": "boolean", + "default": true, + "label": "自动升级", + "description": "勾选后,检测到应用升级后自动从远程下载最新的应用更新" + } + } + } + } +} diff --git a/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/extensiton-settings.json b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/extensiton-settings.json new file mode 100644 index 000000000..550fde0d2 --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/extensiton-settings.json @@ -0,0 +1,12 @@ +{ + "private": true, + "name": "Eoapi-Extensions", + "version": "0.0.1", + "moduleName": "扩展", + "moduleID": "Eoapi-Extensions", + "author": "eoapi", + "publisher": "eoapi", + "contributes": { + "configuration": [] + } +} diff --git a/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/feature-settings.json b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/feature-settings.json new file mode 100644 index 000000000..41628b1b0 --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/feature-settings.json @@ -0,0 +1,39 @@ +{ + "private": true, + "name": "Eoapi-Features", + "version": "0.0.1", + "moduleName": "功能", + "moduleID": "Eoapi-Features", + "author": "eoapi", + "publisher": "eoapi", + "contributes": { + "configuration": [ + { + "type": "object", + "title": "API测试", + "order": 1, + "properties": { + "features.remoteServer.redirctUrl": { + "type": "boolean", + "default": false, + "label": "自动重定向", + "description": "自动重定向至redirect url" + } + } + }, + { + "type": "object", + "title": "扩展", + "order": 2, + "properties": { + "features.remoteServer.autoUpdate": { + "type": "boolean", + "default": true, + "label": "自动更新", + "description": "勾选后,检测到拓展升级后自动从远程下载最新的插件更新" + } + } + } + ] + } +} diff --git a/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/index.ts b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/index.ts new file mode 100644 index 000000000..f1b1bd93b --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/index.ts @@ -0,0 +1,19 @@ +import commonSettings from './common-settings.json'; +import extensitonSettings from './extensiton-settings.json'; +import featureSettings from './feature-settings.json'; +import themeSettings from './theme-settings.json'; + +export type eoapiSettingsKey = keyof typeof eoapiSettings; + +export const eoapiSettings = { + /** 通用设置 */ + 'Eoapi-Common': commonSettings, + /** 功能设置 */ + 'Eoapi-Extensions': extensitonSettings, + /** 扩展配置 */ + 'Eoapi-Features': featureSettings, + /** 主题配置 */ + 'Eoapi-theme': themeSettings, +} as const; + +export default eoapiSettings; diff --git a/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/theme-settings.json b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/theme-settings.json new file mode 100644 index 000000000..7a14385eb --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/theme-settings.json @@ -0,0 +1,22 @@ +{ + "private": true, + "name": "Eoapi-theme", + "version": "0.0.1", + "moduleName": "主题", + "moduleID": "eoapi-theme", + "author": "eoapi", + "publisher": "eoapi", + "contributes": { + "configuration": { + "type": "object", + "order": 1, + "properties": { + "select.theme": { + "type": "component", + "label": "主题列表", + "default": "eo-select-theme" + } + } + } + } +} diff --git a/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/types.ts b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/types.ts new file mode 100644 index 000000000..fcc85dcf1 --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/eoapi-settings/types.ts @@ -0,0 +1,36 @@ +export type JSONSchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'null' | 'array' | 'object'; + +/** 设置模块实体 */ +export type TOCEntry = { + id: string; + label: string; + order?: number; + children?: TOCEntry[]; + settings?: Array; +}; + +export type Setting = {}; + +export type ConfigurationProperty = { + [prop: string]: { + /** 配置项的值类型 */ + type?: JSONSchemaType | JSONSchemaType[]; + /** 枚举,用于下拉框 */ + enum?: any[]; + /** 用于对枚举项的说明 */ + enumDescriptions?: string[]; + /** 配置项默认值 */ + default?: any; + /** 配置项描述 */ + description?: string; + }; +}; + +export type ConfigurationNode = { + id?: string; + order?: number; + type?: string | string[]; + title?: string; + description?: string; + properties?: ConfigurationProperty; +}; diff --git a/src/workbench/browser/src/app/shared/components/setting/setting.component.html b/src/workbench/browser/src/app/shared/components/setting/setting.component.html index 391dcd73a..0501487e1 100644 --- a/src/workbench/browser/src/app/shared/components/setting/setting.component.html +++ b/src/workbench/browser/src/app/shared/components/setting/setting.component.html @@ -1,24 +1,82 @@ - - - + + + + + + +
+ + + + + {{ node.title }} + + + + + + + + + {{ node.title }} + + + + +
+
+

{{ module.title }}

+ + + + {{module.properties[field]?.label }} + + + +
+ {{module.properties[field]?.description }} +
+ + + + + + + + + + + + + + + {{module.properties[field]?.description}} + + + + + + - -
- - - - - {{ field.label }} - - - - - -
- -
+
+ + + + 暂无配置项 + + +
+ + + +
+
diff --git a/src/workbench/browser/src/app/shared/components/setting/setting.component.scss b/src/workbench/browser/src/app/shared/components/setting/setting.component.scss index 8c1064c52..c7f321615 100644 --- a/src/workbench/browser/src/app/shared/components/setting/setting.component.scss +++ b/src/workbench/browser/src/app/shared/components/setting/setting.component.scss @@ -2,15 +2,39 @@ font-size: 20px; position: absolute; padding: 15px; - bottom: 0; + cursor: pointer; + bottom: var(--FOOTER_HEIGHT, 0); } -.flex { - display: flex; - width: 100%; +.container { + display: grid; + grid-template-columns: minmax(200px, min-content) 25px auto; height: 60vh; + .divider { + height: 100%; + } } +.tree-view, .form { + overflow: auto; +} +.form { + padding-right: 10px; +} .footer { text-align: right; -} \ No newline at end of file +} + +.title { + font-size: 16px; + font-weight: 700; +} +.label { + padding: 0; + font-weight: 700; + color: rgba(0, 0, 0, 0.9); +} +.description { + margin-bottom: 3px; + color: rgb(102, 102, 102); +} diff --git a/src/workbench/browser/src/app/shared/components/setting/setting.component.ts b/src/workbench/browser/src/app/shared/components/setting/setting.component.ts index 1cb41d8fe..d761b16c9 100644 --- a/src/workbench/browser/src/app/shared/components/setting/setting.component.ts +++ b/src/workbench/browser/src/app/shared/components/setting/setting.component.ts @@ -1,6 +1,27 @@ import { Component, OnInit } from '@angular/core'; import { NzTabPosition } from 'ng-zorro-antd/tabs'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { SelectionModel } from '@angular/cdk/collections'; +import { FlatTreeControl } from '@angular/cdk/tree'; +import { NzTreeFlatDataSource, NzTreeFlattener } from 'ng-zorro-antd/tree-view'; +import { debounce, cloneDeep } from 'lodash'; +import { eoapiSettings } from './eoapi-settings/'; + +interface TreeNode { + name: string; + title: string; + moduleID?: string; + disabled?: boolean; + children?: TreeNode[]; + configuration?: any[]; +} + +interface FlatNode { + expandable: boolean; + name: string; + level: number; + disabled: boolean; +} @Component({ selector: 'eo-setting', @@ -8,94 +29,313 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; styleUrls: ['./setting.component.scss'], }) export class SettingComponent implements OnInit { + objectKeys = Object.keys; + private transformer = (node: TreeNode, level: number): FlatNode => ({ + ...node, + expandable: !!node.children && node.children.length > 0, + name: node.name, + level, + disabled: !!node.disabled, + }); + selectListSelection = new SelectionModel(); + + treeControl = new FlatTreeControl( + (node) => node.level, + (node) => node.expandable + ); + + treeFlattener = new NzTreeFlattener( + this.transformer, + (node) => node.level, + (node) => node.expandable, + (node) => node.children + ); + + dataSource = new NzTreeFlatDataSource(this.treeControl, this.treeFlattener); + + /** 当前配置项 */ + currentConfiguration = []; isVisible = false; - isModal = false; + _isShowModal = false; position: NzTabPosition = 'left'; - modules = []; + /** 所有配置 */ settings = {}; + /** 本地配置 */ + localSettings = { settings: {}, nestedSettings: {} }; + /** 深层嵌套的配置 */ + nestedSettings = {}; validateForm!: FormGroup; - constructor( - private fb: FormBuilder, - ) {} + + get isShowModal() { + return this._isShowModal; + } + + set isShowModal(val) { + this._isShowModal = val; + if (val) { + this.init(); + } + } + + constructor(private fb: FormBuilder) {} ngOnInit(): void { this.init(); + // this.parseSettings(); + } + + hasChild = (_: number, node: FlatNode): boolean => node.expandable; + + /** + * 设置数据 + * @param properties + */ + private setSettingsModel(properties, controls) { + // 平级配置对象 + Object.keys(properties).forEach((fieldKey) => { + const props = properties[fieldKey]; + this.settings[fieldKey] = this.localSettings?.settings?.[fieldKey] ?? props.default; + // 可扩展加入更多默认校验 + if (props.required) { + controls[fieldKey] = [null, [Validators.required]]; + } else { + controls[fieldKey] = [null]; + } + }); + // 深层嵌套的配置对象 + Object.keys(properties).forEach((fieldKey) => { + const keyArr = fieldKey.split('.'); + const keyArrL = keyArr.length - 1; + keyArr.reduce((p, k, i) => { + const isLast = i === keyArrL; + p[k] ??= isLast ? this.settings[fieldKey] : {}; + return p[k]; + }, this.nestedSettings); + // 当settings变化时,将值同步到nestedSettings + Object.defineProperty(this.settings, fieldKey, { + get: () => { + return this.getConfiguration(fieldKey); + }, + set: (newVal) => { + const target = keyArr.slice(0, -1).reduce((p, k) => p[k], this.nestedSettings); + target[keyArr[keyArrL]] = newVal; + }, + }); + }); } + /** + * 根据key路径获取对应的配置的值 + * @param key + * @returns + */ + getConfiguration(key: string) { + return key.split('.').reduce((p, k) => p[k], this.nestedSettings); + } + /** + * 获取模块的标题 + * @param module + * @returns + */ + getModuleTitle(module: any): string { + const title = module?.moduleName ?? module?.contributes?.title ?? module?.title; + return title; + } + + selectModule(node) { + // console.log('selectModule', node); + this.currentConfiguration = node.configuration || []; + // console.log('this.currentConfiguration', this.currentConfiguration); + this.selectListSelection.select(node); + } + + /** + * 解析所有模块的配置信息 + */ private init() { - if (window.eo && window.eo.getFeature) { - this.isVisible = true; - this.settings = window.eo.getSettings(); - const featureList = window.eo.getFeature('configuration'); - const controls = {}; - featureList?.forEach((feature: object, key: string) => { - if (!feature['title'] || !feature['properties'] || typeof feature['properties'] !== 'object') { - return true; - } - if (!this.settings[key] || typeof this.settings[key] !== 'object') { - this.settings[key] = {}; - } - const fields = []; - for (let field_key in feature['properties']) { - let field = feature['properties'][field_key]; - // 加入允许的type限制 - if (!field['type'] || !field['label']) { - continue; - } - if ('select' === field['type'] && !field['options']) { - continue; - } - const name = key + '_' + field_key; - field = Object.assign({ - name: name, - key: field_key, - required: false, - default: '', - description: '' - }, field); - fields.push(field); - if (!this.settings[key][field_key]) { - this.settings[key][field_key] = field['default']; - } - // 可扩展加入更多默认校验 - if (field.required) { - controls[name] = [null, [Validators.required]]; - } else { - controls[name] = [null]; - } - } - this.modules.push({ - key: key, - title: feature['title'], - fields: fields, + if (!window.eo && !window.eo.getFeature) return; + this.isVisible = true; + this.settings = {}; + this.nestedSettings = {}; + // 获取本地设置 + this.localSettings = window.eo.getSettings(); + // const featureList = window.eo.getFeature('configuration'); + const modules = window.eo.getModules(); + const extensitonConfigurations = [...modules.values()].filter((n) => n.contributes?.configuration); + console.log('localSettings', this.localSettings); + console.log('extensitonConfigurations', extensitonConfigurations); + const controls = {}; + // 所有设置 + const allSettings = cloneDeep([ + eoapiSettings['Eoapi-Common'], + eoapiSettings['Eoapi-theme'], + eoapiSettings['Eoapi-Extensions'], + // eoapiSettings['Eoapi-Features'], + ]); + // 所有配置 + const allConfiguration = allSettings.map((n) => { + const configuration = n.contributes.configuration; + if (!Array.isArray(configuration)) { + configuration.moduleID ??= n.moduleID; + } + return configuration; + }); + // 第三方扩展 + const extensionsModule = allSettings.find((n) => n.moduleID === 'Eoapi-Extensions'); + extensitonConfigurations.forEach((item) => { + const configuration = item?.contributes?.configuration; + if (configuration) { + configuration.title = item.moduleName ?? configuration.title; + configuration.moduleID = item.moduleID; + extensionsModule.contributes.configuration.push(configuration); + } + }); + // 给插件的属性前面追加模块ID + const appendModuleID = (properties, moduleID) => { + return Object.keys(properties).reduce((prev, key) => { + prev[`${moduleID}.${key}`] = properties[key]; + return prev; + }, {}); + }; + /** 根据configuration配置生成settings model */ + allConfiguration.forEach((item) => { + if (Array.isArray(item)) { + item.forEach((n) => { + n.properties = appendModuleID(n.properties, n.moduleID); + this.setSettingsModel(n.properties, controls); }); - }); - this.validateForm = this.fb.group(controls); - } + } else { + item.properties = appendModuleID(item.properties, item.moduleID); + this.setSettingsModel(item.properties, controls); + } + }); + type Configuration = typeof allConfiguration[number] | Array; + // 递归生成设置树 + const generateTreeData = (configurations: Configuration = []) => { + return [].concat(configurations).reduce((prev, curr) => { + if (Array.isArray(curr)) { + return prev.concat(generateTreeData(curr)); + } + const treeItem: TreeNode = { + name: curr.title, + title: curr.title, + configuration: [].concat(curr), + }; + return prev.concat(treeItem); + }, []); + }; + // 所有设置项 + const treeData = allSettings.reduce((prev, curr) => { + let treeItem: TreeNode; + const configuration = curr.contributes.configuration; + if (Array.isArray(configuration)) { + treeItem = { + name: curr.name, + moduleID: curr.moduleID, + title: curr.moduleName || curr.name, + children: generateTreeData(configuration), + configuration, + }; + } else { + treeItem = { + name: curr.name, + moduleID: curr.moduleID, + title: curr.moduleName || configuration.title || curr.name, + configuration: [configuration], + }; + } + return prev.concat(treeItem); + }, []); + console.log('treeData', treeData); + console.log('setings', this.settings); + console.log('nestedSettings', this.nestedSettings); + console.log('controls', controls); + + this.dataSource.setData(treeData); + this.treeControl.expandAll(); + this.validateForm = this.fb.group(controls); + this.validateForm.valueChanges.subscribe(debounce(this.handleSave.bind(this), 300)); + // 默认选中第一项 + this.selectModule(this.treeControl.dataNodes.at(0)); } + // private init() { + // if (window.eo && window.eo.getFeature) { + // this.isVisible = true; + // this.settings = window.eo.getSettings(); + // const featureList = window.eo.getFeature('configuration'); + // const controls = {}; + // featureList?.forEach((feature: object, key: string) => { + // if (!feature['title'] || !feature['properties'] || typeof feature['properties'] !== 'object') { + // return true; + // } + // if (!this.settings[key] || typeof this.settings[key] !== 'object') { + // this.settings[key] = {}; + // } + // const fields = []; + // for (let field_key in feature['properties']) { + // let field = feature['properties'][field_key]; + // // 加入允许的type限制 + // if (!field['type'] || !field['label']) { + // continue; + // } + // if ('select' === field['type'] && !field['options']) { + // continue; + // } + // const name = key + '_' + field_key; + // field = Object.assign( + // { + // name: name, + // key: field_key, + // required: false, + // default: '', + // description: '', + // }, + // field + // ); + // fields.push(field); + // if (!this.settings[key][field_key]) { + // this.settings[key][field_key] = field['default']; + // } + // // 可扩展加入更多默认校验 + // if (field.required) { + // controls[name] = [null, [Validators.required]]; + // } else { + // controls[name] = [null]; + // } + // } + // // this.modules.push({ + // // key: key, + // // title: feature['title'], + // // fields: fields, + // // }); + // }); + // this.validateForm = this.fb.group(controls); + // } + // } + handleShowModal() { - this.isModal = true; + this.isShowModal = true; } handleSave(): void { - for (const i in this.validateForm.controls) { - if (this.validateForm.controls.hasOwnProperty(i)) { - this.validateForm.controls[i].markAsDirty(); - this.validateForm.controls[i].updateValueAndValidity(); - } - } - if (this.validateForm.status === 'INVALID') { - return; - } + // for (const i in this.validateForm.controls) { + // if (this.validateForm.controls.hasOwnProperty(i)) { + // this.validateForm.controls[i].markAsDirty(); + // this.validateForm.controls[i].updateValueAndValidity(); + // } + // } + // if (this.validateForm.status === 'INVALID') { + // return; + // } // 加入根据返回显示提示消息 - const saved = window.eo.saveSettings(this.settings); + const saved = window.eo.saveSettings({ settings: this.settings, nestedSettings: this.nestedSettings }); if (saved) { - this.handleCancel(); + // this.handleCancel(); } } handleCancel(): void { - this.isModal = false; + this.isShowModal = false; } } diff --git a/src/workbench/browser/src/app/shared/components/setting/setting.module.ts b/src/workbench/browser/src/app/shared/components/setting/setting.module.ts index e06b5bf6e..9846a0066 100644 --- a/src/workbench/browser/src/app/shared/components/setting/setting.module.ts +++ b/src/workbench/browser/src/app/shared/components/setting/setting.module.ts @@ -7,11 +7,17 @@ import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzIconModule } from 'ng-zorro-antd/icon'; import { NzListModule } from 'ng-zorro-antd/list'; import { NzInputModule } from 'ng-zorro-antd/input'; +import { NzCheckboxModule } from 'ng-zorro-antd/checkbox'; +import { NzInputNumberModule } from 'ng-zorro-antd/input-number'; import { NzFormModule } from 'ng-zorro-antd/form'; import { NzSelectModule } from 'ng-zorro-antd/select'; import { NzDividerModule } from 'ng-zorro-antd/divider'; +import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzTabsModule } from 'ng-zorro-antd/tabs'; +import { NzTreeViewModule } from 'ng-zorro-antd/tree-view'; + import { ElectronService } from '../../../core/services'; +import { SharedModule } from '../../shared.module'; const ANTDMODULES = [ NzModalModule, @@ -23,10 +29,14 @@ const ANTDMODULES = [ NzSelectModule, NzDividerModule, NzTabsModule, + NzTreeViewModule, + NzCheckboxModule, + NzInputNumberModule, + NzEmptyModule, ]; @NgModule({ declarations: [SettingComponent], - imports: [FormsModule, ReactiveFormsModule, CommonModule, ...ANTDMODULES], + imports: [FormsModule, ReactiveFormsModule, SharedModule, CommonModule, ...ANTDMODULES], exports: [SettingComponent], providers: [ElectronService], }) diff --git a/src/workbench/browser/src/app/shared/components/setting/settingLayout.ts b/src/workbench/browser/src/app/shared/components/setting/settingLayout.ts new file mode 100644 index 000000000..ace6d10ca --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/setting/settingLayout.ts @@ -0,0 +1,20 @@ +export type TOCEntry = { + id: string; + label: string; + order?: number; + children?: TOCEntry[]; + settings?: Array; +}; + +export const tocData: TOCEntry[] = [ + { + id: 'common', + label: '通用', + settings: ['common.*'], + }, + { + id: 'extension', + label: '扩展', + settings: ['extension.*'], + }, +]; diff --git a/src/workbench/browser/src/app/shared/components/sync-api/push.ts b/src/workbench/browser/src/app/shared/components/sync-api/push.ts deleted file mode 100644 index fe53ffc97..000000000 --- a/src/workbench/browser/src/app/shared/components/sync-api/push.ts +++ /dev/null @@ -1,24 +0,0 @@ -import http from 'ky'; -const URL = `http://apis.apikit.deveolink.com/api/v2/api_studio/management/api/importOpenApi`; - -export const sync_to_remote = async (data, { projectId, SecretKey }) => { - const formData = new FormData(); - formData.append( - 'file[]', - new Blob([JSON.stringify(data)], { - type: 'application/json', - }) - ); - formData.append('project_id', projectId); - formData.append('update_type', 'all'); - formData.append('api_status', '0'); - const response = await http - .post(URL, { - headers: { - 'Eo-Secret-Key': SecretKey, - }, - body: formData, - }) - .json(); - return response; -}; diff --git a/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.html b/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.html index 425a85c9a..44ed21654 100644 --- a/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.html +++ b/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.html @@ -1,3 +1,3 @@ - + diff --git a/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.ts b/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.ts index 982304102..fefee90cd 100644 --- a/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.ts +++ b/src/workbench/browser/src/app/shared/components/sync-api/sync-api.component.ts @@ -1,6 +1,8 @@ import { Component, OnInit } from '@angular/core'; import { NzModalRef } from 'ng-zorro-antd/modal'; +import { StorageHandleResult, StorageHandleStatus } from '../../../../../../../platform/browser/IndexedDB'; import { StorageService } from '../../services/storage'; +import packageJson from '../../../../../../../../package.json'; @Component({ selector: 'eo-sync-api', @@ -8,31 +10,46 @@ import { StorageService } from '../../services/storage'; styleUrls: ['./sync-api.component.scss'], }) export class SyncApiComponent implements OnInit { - exportType: string = 'eolink'; + pushType: ''; supportList: any[] = []; + featureList = window.eo.getFeature('apimanager.sync'); constructor(private modalRef: NzModalRef, private storage: StorageService) {} ngOnInit(): void { - const extensionList = window.eo.getModules(); - this.supportList = Object.values([...extensionList]) - .map((it) => it[1]) - .filter((it) => it.moduleType === 'feature') - .filter((it) => it.features['apimanager.sync']) - .map((it: any) => ({ - key: it.moduleName, - image: it.logo, - title: it.features['apimanager.sync'].label, - })); + this.featureList?.forEach((feature: object, key: string) => { + this.supportList.push({ + key: key, + image: feature['icon'], + title: feature['label'], + }); + }); } async submit() { - console.log('sync'); - // const res = await sync_to_remote( - // { a: 1 }, - // { - // projectId: 'ZXXhzTG756db7e34a8d7c803f001edf1a1c545bcbf27719', - // SecretKey: 'SgAZ5Lk60f776c1a235a3c3e62543c3793c36d6cc511db9', - // } - // ); - // console.log(res); + const feature = this.featureList.get(this.pushType); + const action = feature.action || null; + const module = window.eo.loadFeatureModule(this.pushType); + // TODO 临时取值方式需要修改 + const { + url, + token: secretKey, + projectId, + } = window.eo.getModuleSettings('eoapi-feature-push-eolink.eolink.remoteServer'); + if (module && module[action] && typeof module[action] === 'function') { + this.storage.run('projectExport', [], async (result: StorageHandleResult) => { + if (result.status === StorageHandleStatus.success) { + result.data.version = packageJson.version; + try { + const output = await module[action](result.data, { + url, + projectId, + secretKey, + }); + console.log(output); + } catch (e) { + console.log(e); + } + } + }); + } } } diff --git a/src/workbench/browser/src/app/shared/components/toolbar/select-theme/select-theme.component.html b/src/workbench/browser/src/app/shared/components/toolbar/select-theme/select-theme.component.html index 861458525..8b6c3448f 100644 --- a/src/workbench/browser/src/app/shared/components/toolbar/select-theme/select-theme.component.html +++ b/src/workbench/browser/src/app/shared/components/toolbar/select-theme/select-theme.component.html @@ -1,4 +1,4 @@ - - - -
-
{{ group.title }}
-
-
-
- -
- -
-
-
- - + diff --git a/src/workbench/browser/src/app/shared/shared.module.ts b/src/workbench/browser/src/app/shared/shared.module.ts index 910970b26..68d597679 100644 --- a/src/workbench/browser/src/app/shared/shared.module.ts +++ b/src/workbench/browser/src/app/shared/shared.module.ts @@ -24,7 +24,7 @@ import { PageBlankComponent } from './components/page-blank/page-blank.component import { PageFeaturePreviewComponent } from './components/page-feature-preview/page-feature-preview.component'; import { RouterModule } from '@angular/router'; -const COMPONENTS = [ToolbarComponent, SelectThemeComponent, SidebarComponent, NavbarComponent,PageNotFoundComponent]; +const COMPONENTS = [ToolbarComponent, SelectThemeComponent, SidebarComponent, NavbarComponent, PageNotFoundComponent]; @NgModule({ imports: [ CommonModule, @@ -38,7 +38,7 @@ const COMPONENTS = [ToolbarComponent, SelectThemeComponent, SidebarComponent, Na NzToolTipModule, NzResultModule, NzDropDownModule, - NzSpinModule + NzSpinModule, ], declarations: [WebviewDirective, ...COMPONENTS,ApiParamsNumPipe, PageBlankComponent, PageFeaturePreviewComponent], providers: [ModalService], diff --git a/src/workbench/browser/src/assets/theme/antd.less b/src/workbench/browser/src/assets/theme/antd.less index 44865e890..e55e18df1 100644 --- a/src/workbench/browser/src/assets/theme/antd.less +++ b/src/workbench/browser/src/assets/theme/antd.less @@ -5,10 +5,10 @@ // Override less variables to here // View all variables: https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/components/style/themes/default.less @theme-color: #00785a; -@border-radius-base:3px; +@border-radius-base: 3px; @primary-color: @theme-color; @success-color: @theme-color; -@link-color:rgba(0, 0, 0, 0.8); +@link-color:rgba (0, 0, 0, 0.8); @processing-color: @theme-color; @tree-title-height: 30px; body { @@ -68,13 +68,16 @@ body { p { margin-bottom: 0; } -.ant-btn.ant-dropdown-trigger{ +.ant-btn.ant-dropdown-trigger { width: 20px; } -.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected{ +.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected { background-color: @theme-color; color: #fff; } -.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn{ +.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn { text-shadow: none; -} \ No newline at end of file +} +.ant-tree-switcher { + width: 20px; +} diff --git a/src/workbench/browser/src/main.ts b/src/workbench/browser/src/main.ts index d3ad50118..f65f6c820 100644 --- a/src/workbench/browser/src/main.ts +++ b/src/workbench/browser/src/main.ts @@ -9,6 +9,5 @@ if (APP_CONFIG.production) { } platformBrowserDynamic() - .bootstrapModule(AppModule, { - }) - .catch(err => console.error(err)); + .bootstrapModule(AppModule, {}) + .catch((err) => console.error(err)); diff --git a/src/workbench/browser/src/styles.scss b/src/workbench/browser/src/styles.scss index bc8079c77..8eea89b9b 100644 --- a/src/workbench/browser/src/styles.scss +++ b/src/workbench/browser/src/styles.scss @@ -8,8 +8,8 @@ body { } :root { --NAVBAR_HEIGHT: 50px; - --FOOTER_HEIGHT: 0px; - // --FOOTER_HEIGHT: 30px; + // --FOOTER_HEIGHT: 0px; + --FOOTER_HEIGHT: 30px; } .api_test_history_list { .method_label { diff --git a/tsconfig.json b/tsconfig.json index 785060093..2ad2f39f2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,6 @@ "lib": ["es2017", "es2016", "es2015", "dom"], "baseUrl": "./", "paths": { - "@utils/*": ["src/core/api-manager/browser/src/app/utils/*"] } }, "include": ["**/**.ts"],