diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5006926b7..34f66cb96 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -77,7 +77,7 @@ jobs: # apply provisioning profile # mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles # cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles - echo "${{ secrets.NOTARIZE_JS }}" > build/notarize.js + echo "${{ secrets.NOTARIZE_JS }}" > scripts/notarize.js yarn release:m1 yarn release diff --git a/.gitignore b/.gitignore index ea7afdabf..d0295ae5d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,12 +13,12 @@ out/ !src/workbench/node/electron/**/*.js !src/workbench/node/request/**/*.js !src/workbench/node/server/**/*.js +!src/workbench/browser/src/libs/ !/api/*.js -!/build/*.js +!/scripts/*.js !*.config.js !upload.js -scripts/notarize.js # dependencies node_modules # package-lock.json diff --git a/electron-builder.json b/electron-builder.json index 763cf2013..43f16fe38 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -1,5 +1,5 @@ { - "appId": ".eolinker.com", + "appId": ".eoapi.io", "asar": true, "directories": { "output": "release/" @@ -28,8 +28,17 @@ "nsis": { "oneClick": false, "allowElevation": true, - "allowToChangeInstallationDirectory": true + "allowToChangeInstallationDirectory": true, + // for win - 将协议写入主机的脚本 + "include": "scripts/urlProtoco.nsh" }, + "protocols": [ + // for macOS - 用于在主机注册指定协议 + { + "name": "eoapi", + "schemes": ["eoapi"] + } + ], "win": { "icon": "src/app/common/images/256x256.png", "target": [ @@ -46,14 +55,14 @@ "icon": "src/app/common/images/512x512.png", "hardenedRuntime": true, "gatekeeperAssess": false, - "entitlements": "build/entitlements.mac.plist", - "entitlementsInherit": "build/entitlements.mac.plist", + "entitlements": "scripts/entitlements.mac.plist", + "entitlementsInherit": "scripts/entitlements.mac.plist", "target": ["dmg", "zip"] }, "dmg": { "sign": false }, - "afterSign": "build/notarize.js", + "afterSign": "scripts/notarize.js", "linux": { "icon": "src/app/common/images/", "target": ["AppImage"] diff --git a/package.json b/package.json index 650bb4b7c..004e6d185 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "eoapi", "souceLocale": "zh-Hans", - "version": "1.6.0", + "version": "1.6.2", "main": "out/app/electron-main/main.js", "description": "A lightweight, extensible API tool", "homepage": "https://github.com/eolinker/eoapi.git", @@ -23,6 +23,7 @@ "electron:static": "npm run electron:tsc && electron .", "electron:dev": "npm run electron:tsc && electron . --development", "build": "npx patch-package && npm-run-all -s build:workbench clear:electron:tsc electron:tsc && electron-builder build", + "build:local": "npm-run-all -s build:workbench clear:electron:tsc electron:tsc && electron-builder build", "build:static": "npm run clear:electron:tsc&&npm run electron:tsc && electron-builder build", "release": "npm-run-all -s build:workbench electron:tsc && electron-builder --publish=always", "release:m1": "npm-run-all -s build:workbench electron:tsc && electron-builder -m=dmg --arm64 -p onTagOrDraft", diff --git a/build/afterBuild.js b/scripts/afterBuild.js similarity index 100% rename from build/afterBuild.js rename to scripts/afterBuild.js diff --git a/build/entitlements.mac.plist b/scripts/entitlements.mac.plist similarity index 100% rename from build/entitlements.mac.plist rename to scripts/entitlements.mac.plist diff --git a/build/notarize.js b/scripts/notarize.js similarity index 100% rename from build/notarize.js rename to scripts/notarize.js diff --git a/scripts/urlProtoco.nsh b/scripts/urlProtoco.nsh new file mode 100644 index 000000000..c94b4b350 --- /dev/null +++ b/scripts/urlProtoco.nsh @@ -0,0 +1,9 @@ +!macro customInstall + DetailPrint "Register eoapi URI Handler" + DeleteRegKey HKCR "eoapi" + WriteRegStr HKCR "eoapi" "" "URL:eoapi" + WriteRegStr HKCR "eoapi" "URL Protocol" "" + WriteRegStr HKCR "eoapi\shell" "" "" + WriteRegStr HKCR "eoapi\shell\Open" "" "" + WriteRegStr HKCR "eoapi\shell\Open\command" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME} %1" +!macroend diff --git a/src/app/electron-main/appView.ts b/src/app/electron-main/appView.ts index 41307db78..e40f193d0 100644 --- a/src/app/electron-main/appView.ts +++ b/src/app/electron-main/appView.ts @@ -18,7 +18,7 @@ export class AppViews { if (module && module.moduleType === ModuleType.app) { if (module.isApp && this.mainModuleID !== module.moduleID) { this.mainModuleID = module.moduleID; - this.sidePosition = module.sidePosition; + // this.sidePosition = module.sidePosition; } this.createAppView(module); diff --git a/src/app/electron-main/main.ts b/src/app/electron-main/main.ts index d9ef0e259..c3c066f4e 100644 --- a/src/app/electron-main/main.ts +++ b/src/app/electron-main/main.ts @@ -19,6 +19,21 @@ export const subView = { appView: null, mainView: null, }; + +// 获取单实例锁 +const gotTheLock = app.requestSingleInstanceLock(); +if (!gotTheLock) { + // 如果获取失败,说明已经有实例在运行了,直接退出 + app.quit(); +} +const PROTOCOL = 'eoapi'; +// app.setAsDefaultProtocolClient(PROTOCOL); // 注册协议 +if (app.isPackaged) { + app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, ['--']); +} else { + app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, [path.resolve(process.argv[1]), '--']); +} + const eoUpdater = new EoUpdater(); const mockServer = new MockServer(); const moduleManager: ModuleManagerInterface = new ModuleManager(); @@ -92,6 +107,7 @@ class EoBrowserWindow { contextIsolation: false, // false if you want to run e2e test with Spectron }, }); + proxyOpenExternal(this.win); this.loadURL(); this.startMock(); diff --git a/src/platform/node/extension-manager/lib/loader.ts b/src/platform/node/extension-manager/lib/loader.ts index 0296a4cb6..aecda76bc 100644 --- a/src/platform/node/extension-manager/lib/loader.ts +++ b/src/platform/node/extension-manager/lib/loader.ts @@ -40,8 +40,7 @@ export class ModuleLoader implements ModuleLoaderInterface { */ loadModule(module: ModuleInfo): void { if ((this.runtime === ModuleRuntime.main && ![ModuleType.system, ModuleType.app].indexOf(module.moduleType)) - || (this.runtime === ModuleRuntime.render && ![ModuleType.feature].indexOf(module.moduleType)) - || (this.runtime === ModuleRuntime.web && !module.web)) { + || (this.runtime === ModuleRuntime.render && ![ModuleType.feature].indexOf(module.moduleType))) { console.log(`The [${module.moduleType}] module [${module.name}] can not run in runtime [${this.runtime}].`); return; } diff --git a/src/platform/node/extension-manager/lib/manager.ts b/src/platform/node/extension-manager/lib/manager.ts index 4464c6206..1eb8f43d1 100644 --- a/src/platform/node/extension-manager/lib/manager.ts +++ b/src/platform/node/extension-manager/lib/manager.ts @@ -211,7 +211,7 @@ export class ModuleManager implements ModuleManagerInterface { if (!this.features.has(key)) { this.features.set(key, new Map()); } - this.features.get(key).set(moduleInfo.moduleID, value); + this.features.get(key).set(moduleInfo.moduleID, { name: moduleInfo.name, ...value }); }); } } diff --git a/src/platform/node/extension-manager/types/manager.ts b/src/platform/node/extension-manager/types/manager.ts index 57c35b82a..a689549e4 100644 --- a/src/platform/node/extension-manager/types/manager.ts +++ b/src/platform/node/extension-manager/types/manager.ts @@ -36,6 +36,7 @@ export interface ModuleInfo { // extension name moduleName: string; // extension type + //!TODO what usage moduleType: ModuleType; // extension logo logo: string; @@ -48,19 +49,17 @@ export interface ModuleInfo { // inject script before start app preload?: string; // 判断是不是顶层App + //!TODO use feature contribution to control page isApp?: boolean; - // web运行支持 - web?: boolean; + // 模块对应上层模块ID + //!TODO what usage? belongs?: Array; // 下层关联模块ID集合 + //!TODO what usage? sideItems?: Array; - // 下层功能模块ID集合, 待移除 - featureItems?: Array; // 模块路径 baseDir?: string; - // 边栏显示 - sidePosition?: SidePosition; // 配置项 configuration?: ModuleConfiguration; /** 贡献点 */ diff --git a/src/workbench/browser/.gitignore b/src/workbench/browser/.gitignore index f96895499..8db20701a 100644 --- a/src/workbench/browser/.gitignore +++ b/src/workbench/browser/.gitignore @@ -7,7 +7,7 @@ dist/ /app-builds /release src/**/*.js -!build/*.js +!scripts/*.js !src/karma.conf.js !src/ng1/**/*.js *.js.map diff --git a/src/workbench/browser/src/app/app.module.ts b/src/workbench/browser/src/app/app.module.ts index 76d470489..6ea5cd478 100644 --- a/src/workbench/browser/src/app/app.module.ts +++ b/src/workbench/browser/src/app/app.module.ts @@ -76,7 +76,7 @@ registerLocaleData(zh); } }, deps: [LOCALE_ID], - } + }, ], bootstrap: [AppComponent], }) diff --git a/src/workbench/browser/src/app/pages/api/overview/api-overview.component.html b/src/workbench/browser/src/app/pages/api/overview/api-overview.component.html index 249f0ec6d..a9d6326b0 100644 --- a/src/workbench/browser/src/app/pages/api/overview/api-overview.component.html +++ b/src/workbench/browser/src/app/pages/api/overview/api-overview.component.html @@ -1,13 +1,13 @@

Index

-
+
- + - +
diff --git a/src/workbench/browser/src/app/pages/api/overview/api-overview.component.ts b/src/workbench/browser/src/app/pages/api/overview/api-overview.component.ts index 1771e0177..ab08284cc 100644 --- a/src/workbench/browser/src/app/pages/api/overview/api-overview.component.ts +++ b/src/workbench/browser/src/app/pages/api/overview/api-overview.component.ts @@ -43,6 +43,12 @@ export class ApiOverviewComponent implements OnDestroy { }, ]; + handleClickCard = (event, item) => { + if (event.target?.classList?.contains?.('ant-card-actions') || event.target?.closest('.ant-card-actions')) { + this.clickCard(item); + } + }; + clickCard({ title, desc, type }) { this.modal = this.modalService.create({ nzTitle: desc, diff --git a/src/workbench/browser/src/app/pages/extension/detail/components/extensions.component.ts b/src/workbench/browser/src/app/pages/extension/detail/components/extensions.component.ts new file mode 100644 index 000000000..560dc736b --- /dev/null +++ b/src/workbench/browser/src/app/pages/extension/detail/components/extensions.component.ts @@ -0,0 +1,127 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { LanguageService } from 'eo/workbench/browser/src/app/core/services/language/language.service'; +import { SettingService } from 'eo/workbench/browser/src/app/core/services/settings/settings.service'; +import { NzMessageService } from 'ng-zorro-antd/message'; + +@Component({ + selector: 'eo-extension-setting', + template: ` +
+ +
+ +
+ + + + {{ properties[field]?.label }} + + + +
+ {{ properties[field]?.description }} +
+ + + + + + + + + + + + + + + {{ properties[field]?.description }} + + +
+
+ `, +}) +export class ExtensionSettingComponent implements OnInit { + @Input() configuration = {} as any; + localSettings = {} as Record; + validateForm!: FormGroup; + objectKeys = Object.keys; + get properties() { + return this.configuration?.properties || {}; + } + + constructor( + public languageService: LanguageService, + private fb: FormBuilder, + private settingService: SettingService, + private message: NzMessageService + ) {} + + ngOnInit(): void { + this.init(); + } + + private init() { + this.localSettings = this.settingService.getSettings(); + const controls = {}; + + this.setSettingsModel(this.configuration.properties, controls); + + this.validateForm = this.fb.group(controls); + } + + /** + * set data + * + * @param properties + */ + private setSettingsModel(properties, controls) { + // Flat configuration object + Object.keys(properties).forEach((fieldKey) => { + const props = properties[fieldKey]; + this.localSettings[fieldKey] ??= props.default; + // Extensible to add more default checks + if (props.required) { + controls[fieldKey] = [null, [Validators.required]]; + } else { + controls[fieldKey] = [null]; + } + }); + } + + handleSave = () => { + this.settingService.saveSetting(this.localSettings); + window.eo?.saveSettings?.({ ...this.localSettings }); + this.message.create('success', `Save Success`); + }; +} diff --git a/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.html b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.html index 481b84644..7577f3311 100644 --- a/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.html +++ b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.html @@ -1,79 +1,95 @@ -
-
- -
-
-
-
- -
-
- {{ extensionDetail?.moduleName }} -

{{ extensionDetail?.description }}

+
+
+
+
+ + Back + + +
+
-
+ {{ extensionDetail.moduleName }} + + + +
-
-
-

Intro

- -
+ +
+
+

{{ extensionDetail.description }}

+
+ +
+ + + + + + + + +
- +
-
-
-
-

Install

-
- - - -
-
- - - -
- -
- - - - -
- The extensions can only be installed on the client at present. Please download the client first~ -
-
- -

Support

+ + - {{ extensionDetail?.author }} - {{ extensionDetail?.version }} + {{ extensionDetail.author }} + {{ extensionDetail.version }} + + + {{ extensionDetail.repository.url.replace('git+', '') }} + + + + {{ extensionDetail.homepage }} + + + {{extensionDetail.bugs.url }} + -
-
+ + + + + + + + + +
+ + + + Don't have Eoapi? + + Download + . + + + + + diff --git a/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.scss b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.scss index 3afa25b61..53f496228 100644 --- a/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.scss +++ b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.scss @@ -1,11 +1,27 @@ +:host { + overflow: initial; +} +.ant-divider-vertical { + margin: 0 16px; +} ::ng-deep { eo-extension-detail { + .settings .ant-tabs-content-holder { + padding-top: 0; + } .ant-tabs-content-holder { - padding-top: 20px; + padding-top: 15px; + padding-bottom: 8px; + margin-bottom: 24px; + overflow: auto; } .ant-skeleton-element .ant-skeleton-button { width: 100%; } + .ant-tabs-tab { + color: #333; + padding: 10px 0; + } } .md-preview { img { @@ -13,10 +29,6 @@ } } .extension-detail { - .markdown-desc { - overflow: auto; - } - .ant-descriptions-row > td { padding-bottom: 8px; } @@ -26,3 +38,7 @@ } } } + +a { + color: var(--BLUE_NORMAL); +} diff --git a/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.ts b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.ts index 2c5bbdebc..3beb4624f 100644 --- a/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.ts +++ b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.component.ts @@ -14,9 +14,15 @@ import { LanguageService } from 'eo/workbench/browser/src/app/core/services/lang export class ExtensionDetailComponent implements OnInit { isOperating = false; introLoading = false; + changelogLoading = false; + isVisible = false; + isEnable = false; isNotLoaded = true; extensionDetail: EoExtensionInfo; resourceInfo = ResourceInfo; + nzSelectedIndex = 0; + + changeLog = ''; get isElectron() { return this.electronService.isElectron; } @@ -30,18 +36,82 @@ export class ExtensionDetailComponent implements OnInit { this.getDetail(); this.getInstaller(); } + + ngOnInit(): void {} + + handleInstall() { + if (this.electronService.isElectron) { + this.manageExtension(this.extensionDetail?.installed ? 'uninstall' : 'install', this.extensionDetail?.name); + } else { + const PROTOCOL = 'eoapi://'; + (window as any).protocolCheck( + PROTOCOL, + () => { + // alert("检测到您电脑Eoapi Client本地客户端未安装 请下载"); + this.isVisible = true; + }, + () => { + window.location.href = PROTOCOL; + } + ); + } + } + async getDetail() { this.extensionDetail = await this.extensionService.getDetail( this.route.snapshot.queryParams.id, this.route.snapshot.queryParams.name ); + + this.isEnable = this.extensionService.isEnable(this.extensionDetail.name); + if (!this.extensionDetail?.installed) { await this.fetchReadme(this.language.systemLanguage); } this.isNotLoaded = false; this.extensionDetail.introduction ||= $localize`This plugin has no documentation yet.`; + + if (this.extensionDetail?.features?.configuration) { + this.nzSelectedIndex = ~~this.route.snapshot.queryParams.tab; + } } + async fetchChangelog(locale = '') { + //Default locale en-US + if (locale === 'en-US') locale = ''; + const timer = setTimeout(() => (this.changelogLoading = true), 200); + try { + const response = await fetch( + `https://unpkg.com/${this.extensionDetail.name}@${this.extensionDetail.version}/changeLog.${ + locale ? locale + '.' : '' + }md` + ); + if (response.status === 200) { + this.changeLog = await response.text(); + } else if (!locale && response.status === 404) { + const result = await fetch(`https://registry.npmjs.org/${this.extensionDetail.name}`, { + headers: { + // if fullmeta + // accept: ' application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*', + }, + }); + const data = await result.json(); + this.changeLog = Object.entries(data.versions).reduceRight((log, [key, value]) => { + return ` +${log} +## [${key}](${value.dist.tarball}) - ${new Date(data.time[key]).toLocaleString()} + `; + }, ''); + } else if (locale) { + //If locale README not find,fetch default locale(en-US) + this.fetchChangelog(); + } + } catch (error) { + } finally { + clearTimeout(timer); + this.changelogLoading = false; + } + } async fetchReadme(locale = '') { //Default locale en-US if (locale === 'en-US') locale = ''; @@ -64,6 +134,12 @@ export class ExtensionDetailComponent implements OnInit { } } + handleTabChange = (e) => { + if (e.tab?.nzTitle === 'ChangeLog') { + this.fetchChangelog(); + } + }; + private findLinkInSingleAssets(assets, item) { let result = ''; const assetIndex = assets.findIndex( @@ -91,7 +167,7 @@ export class ExtensionDetailComponent implements OnInit { getInstaller() { fetch('https://api.github.com/repos/eolinker/eoapi/releases') .then((response) => response.json()) - .then((data) => { + .then((data = []) => { [...this.resourceInfo] .sort((a1, a2) => a2.suffix.length - a1.suffix.length) .forEach((item) => { @@ -114,11 +190,13 @@ export class ExtensionDetailComponent implements OnInit { switch (operate) { case 'install': { this.extensionDetail.installed = this.extensionService.install(id); + this.handleEnableExtension(true); this.getDetail(); break; } case 'uninstall': { this.extensionDetail.installed = !this.extensionService.uninstall(id); + this.handleEnableExtension(false); this.fetchReadme(this.language.systemLanguage); break; } @@ -126,7 +204,6 @@ export class ExtensionDetailComponent implements OnInit { this.isOperating = false; }, 100); } - ngOnInit(): void {} backToList() { this.router.navigate(['/home/extension/list'], { @@ -135,4 +212,17 @@ export class ExtensionDetailComponent implements OnInit { }, }); } + + handleOk(): void { + console.log('Button ok clicked!'); + this.isVisible = false; + } + + handleEnableExtension(isEnable) { + if (isEnable) { + this.extensionService.enableExtension(this.extensionDetail.name); + } else { + this.extensionService.disableExtension(this.extensionDetail.name); + } + } } diff --git a/src/workbench/browser/src/app/pages/extension/detail/extension-detail.module.ts b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.module.ts new file mode 100644 index 000000000..7539eb64a --- /dev/null +++ b/src/workbench/browser/src/app/pages/extension/detail/extension-detail.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { ExtensionSettingComponent } from './components/extensions.component'; +import { ExtensionDetailComponent } from './extension-detail.component'; +import { SharedModule } from 'eo/workbench/browser/src/app/shared/shared.module'; + +@NgModule({ + imports: [SharedModule, FormsModule, CommonModule], + declarations: [ExtensionSettingComponent, ExtensionDetailComponent], +}) +export class ExtensionDetailModule {} diff --git a/src/workbench/browser/src/app/pages/extension/extension.component.html b/src/workbench/browser/src/app/pages/extension/extension.component.html index a0f97c4f5..f3df717d9 100644 --- a/src/workbench/browser/src/app/pages/extension/extension.component.html +++ b/src/workbench/browser/src/app/pages/extension/extension.component.html @@ -1,4 +1,4 @@ -
+
- - {{ node.origin.method }} - {{ node.title }}
diff --git a/src/workbench/browser/src/app/pages/extension/extension.component.scss b/src/workbench/browser/src/app/pages/extension/extension.component.scss index b243e295b..f65fbefd0 100644 --- a/src/workbench/browser/src/app/pages/extension/extension.component.scss +++ b/src/workbench/browser/src/app/pages/extension/extension.component.scss @@ -1,12 +1,14 @@ -::ng-deep .main { +::ng-deep .eo-extension-main { height: 100%; width: 100%; display: flex; - + .ant-btn-link { + padding: 0; + } .input { height: 30px; border-color: transparent; - background-color: rgba(0,0,0,0.05); + background-color: rgba(0, 0, 0, 0.05); &:hover { border-color: #158565; } @@ -14,27 +16,27 @@ .tree_node { font-size: 12px; } - .ant-tree .ant-tree-treenode { - padding: 0; - margin: 2px 0; - border-radius: 3px; - transition: all 0.3s, border 0s, line-height 0s, box-shadow 0s; - &:hover { - background-color: #f5f5f5; - } - } - .ant-tree-treenode-selected { - background-color: var(--NAVBAR_BTN_BG); - } - .ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected { - background-color: transparent; - transition: none; + .ant-tree .ant-tree-treenode { + padding: 0; + margin: 2px 0; + border-radius: 3px; + transition: all 0.3s, border 0s, line-height 0s, box-shadow 0s; + &:hover { + background-color: #f5f5f5; } - .ant-tree .ant-tree-node-content-wrapper{ + } + .ant-tree-treenode-selected { + background-color: var(--NAVBAR_BTN_BG); + } + .ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected { + background-color: transparent; + transition: none; + } + .ant-tree .ant-tree-node-content-wrapper { border-radius: 0; &.ant-tree-node-selected { - opacity: .8; - } + opacity: 0.8; + } } .ant-tree-switcher { diff --git a/src/workbench/browser/src/app/pages/extension/extension.component.ts b/src/workbench/browser/src/app/pages/extension/extension.component.ts index 5308c97ca..919d23293 100644 --- a/src/workbench/browser/src/app/pages/extension/extension.component.ts +++ b/src/workbench/browser/src/app/pages/extension/extension.component.ts @@ -22,6 +22,11 @@ export class ExtensionComponent implements OnInit { title: $localize`Official`, isLeaf: true, }, + { + key: 'installed', + title: $localize`Installed`, + isLeaf: true, + } ]; fixedTreeNode: GroupTreeItem[] | NzTreeNode[] = [ { diff --git a/src/workbench/browser/src/app/pages/extension/extension.model.ts b/src/workbench/browser/src/app/pages/extension/extension.model.ts index c3a7b698a..e9a8cfb8f 100644 --- a/src/workbench/browser/src/app/pages/extension/extension.model.ts +++ b/src/workbench/browser/src/app/pages/extension/extension.model.ts @@ -6,9 +6,11 @@ export enum ExtensionGroupType { installed = 'installed', } -export interface EoExtensionInfo extends ModuleInfo{ - installed?:boolean; - bugs:{ - url:string +export interface EoExtensionInfo extends ModuleInfo { + installed?: boolean; + changeLog?: string; + bugs: { + url: string; }; + [key: string]: any; } diff --git a/src/workbench/browser/src/app/pages/extension/extension.module.ts b/src/workbench/browser/src/app/pages/extension/extension.module.ts index 2597db78d..36df86bc9 100644 --- a/src/workbench/browser/src/app/pages/extension/extension.module.ts +++ b/src/workbench/browser/src/app/pages/extension/extension.module.ts @@ -5,7 +5,7 @@ import { FormsModule } from '@angular/forms'; import { ExtensionRoutingModule } from './extension-routing.module'; import { ExtensionComponent } from './extension.component'; import { ExtensionListComponent } from './list/extension-list.component'; -import { ExtensionDetailComponent } from './detail/extension-detail.component'; +import { ExtensionDetailModule } from './detail/extension-detail.module'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzInputModule } from 'ng-zorro-antd/input'; @@ -15,14 +15,18 @@ import { NzTagModule } from 'ng-zorro-antd/tag'; import { NzDividerModule } from 'ng-zorro-antd/divider'; import { NzTreeModule } from 'ng-zorro-antd/tree'; import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; +import { NzSwitchModule } from 'ng-zorro-antd/switch'; import { NzSkeletonModule } from 'ng-zorro-antd/skeleton'; import { SharedModule } from 'eo/workbench/browser/src/app/shared/shared.module'; - +import { NzCardModule } from 'ng-zorro-antd/card'; +import { NzAvatarModule } from 'ng-zorro-antd/avatar'; +import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; @NgModule({ imports: [ SharedModule, FormsModule, NzTabsModule, + NzToolTipModule, NzTagModule, NzDescriptionsModule, NzInputModule, @@ -31,9 +35,13 @@ import { SharedModule } from 'eo/workbench/browser/src/app/shared/shared.module' CommonModule, NzDividerModule, NzTreeModule, + NzSwitchModule, NzDropDownModule, - NzSkeletonModule + NzSkeletonModule, + NzCardModule, + NzAvatarModule, + ExtensionDetailModule, ], - declarations: [ExtensionComponent, ExtensionListComponent, ExtensionDetailComponent], + declarations: [ExtensionComponent, ExtensionListComponent], }) export class ExtensionModule {} diff --git a/src/workbench/browser/src/app/pages/extension/extension.service.ts b/src/workbench/browser/src/app/pages/extension/extension.service.ts index 59441487e..742ef4914 100644 --- a/src/workbench/browser/src/app/pages/extension/extension.service.ts +++ b/src/workbench/browser/src/app/pages/extension/extension.service.ts @@ -6,12 +6,14 @@ import { ModuleInfo } from 'eo/platform/node/extension-manager/types/index'; import { TranslateService } from 'eo/platform/common/i18n'; import { LanguageService } from 'eo/workbench/browser/src/app/core/services/language/language.service'; import { APP_CONFIG } from 'eo/workbench/browser/src/environments/environment'; +import { DISABLE_EXTENSION_NAMES } from 'eo/workbench/browser/src/app/shared/constant/storageKeys'; @Injectable({ providedIn: 'root', }) export class ExtensionService { ignoreList = ['default']; + disabledExtensionNames: string[] = this.getExtensionNames(); extensionIDs: Array = []; HOST = ''; localExtensions: Map; @@ -28,6 +30,10 @@ export class ExtensionService { // Local extension exception for ignore list return Array.from(this.localExtensions.values()).filter((it) => this.extensionIDs.includes(it.moduleID)); } + isInstalled(name) { + const installList = this.getInstalledList(); + return installList.includes(name); + } private translateModule(module: ModuleInfo) { const lang = this.language.systemLanguage; const locale = module.i18n?.find((val) => val.locale === lang)?.package; @@ -86,6 +92,33 @@ export class ExtensionService { console.error(data); return false; } + + isEnable(name: string) { + return !this.disabledExtensionNames.includes(name); + } + + enableExtension(names: string | string[]) { + const enableNames = Array().concat(names) as string[]; + this.setExtension(this.disabledExtensionNames.filter((n) => !enableNames.includes(n))); + } + + disableExtension(names: string | string[]) { + this.setExtension([...new Set(this.disabledExtensionNames.concat(names))]); + } + + setExtension(arr: string[]) { + localStorage.setItem(DISABLE_EXTENSION_NAMES, JSON.stringify(arr)); + this.disabledExtensionNames = arr; + } + + getExtensionNames() { + try { + return (this.disabledExtensionNames = JSON.parse(localStorage.getItem(DISABLE_EXTENSION_NAMES) || '[]')); + } catch (error) { + return []; + } + } + private async requestDetail(id) { return await lastValueFrom(this.http.get(`${this.HOST}/detail/${id}?locale=${this.language.systemLanguage}`)).catch( (err) => [0, err] diff --git a/src/workbench/browser/src/app/pages/extension/list/extension-list.component.html b/src/workbench/browser/src/app/pages/extension/list/extension-list.component.html index b6e1d44c0..f41143b84 100644 --- a/src/workbench/browser/src/app/pages/extension/list/extension-list.component.html +++ b/src/workbench/browser/src/app/pages/extension/list/extension-list.component.html @@ -1,24 +1,41 @@
-
-
-
-
+ class="bd_all w-full min-h-[140px] p-5 flex flex-col flex-wrap plugin-block hover:border-green-700 hover:shadow-lg transition-shadow duration-300" + *ngFor="let it of renderList" (click)="clickExtension($event,it)"> + +
+
+
+
+
+
+ {{ it.moduleName }} + {{ it.author }} + {{it.description}} -
- {{ it.moduleName }} - {{ it.author }} - {{ it.description }} -
-
- Installed +
+
+ + Setting + + + Details +
+
+
+
+ +
+
+ Installed +
-
+
diff --git a/src/workbench/browser/src/app/pages/extension/list/extension-list.component.scss b/src/workbench/browser/src/app/pages/extension/list/extension-list.component.scss index 6d29e8594..7d8a7149b 100644 --- a/src/workbench/browser/src/app/pages/extension/list/extension-list.component.scss +++ b/src/workbench/browser/src/app/pages/extension/list/extension-list.component.scss @@ -3,7 +3,7 @@ display: -webkit-box; text-overflow: ellipsis; -webkit-box-orient: vertical; - -webkit-line-clamp: 3; + -webkit-line-clamp: 1; } .plugin-block { @@ -14,21 +14,12 @@ .list-block { height: calc(100% - 65px); overflow: auto; - >div{ + > div { border-radius: 3px; } } -.warn-color { - color: var(--MAIN_THEME_COLOR); -} @media (max-width: 1279.9px) { .grid-cols-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); } } -.w-60{ - width: 15rem; -} -.h-76{ - height: 17rem; -} \ No newline at end of file diff --git a/src/workbench/browser/src/app/pages/extension/list/extension-list.component.ts b/src/workbench/browser/src/app/pages/extension/list/extension-list.component.ts index efcff1c36..03e43371a 100644 --- a/src/workbench/browser/src/app/pages/extension/list/extension-list.component.ts +++ b/src/workbench/browser/src/app/pages/extension/list/extension-list.component.ts @@ -25,6 +25,7 @@ export class ExtensionListComponent implements OnInit { type: ExtensionGroupType = ExtensionGroupType.all; keyword = ''; renderList = []; + loading = false; seachChanged$: Subject = new Subject(); private destroy$: Subject = new Subject(); @@ -45,31 +46,53 @@ export class ExtensionListComponent implements OnInit { this.watchSearchKeywordChange(); } async searchPlugin(keyword = '') { - if (this.type === 'installed') { - const installedList = new ExtensionList(this.extensionService.getInstalledList()); - return installedList.search(keyword); + const timer = setTimeout(() => (this.loading = true), 80); + const timeStart = Date.now(); + try { + if (this.type === 'installed') { + const installedList = new ExtensionList(this.extensionService.getInstalledList()); + return installedList.search(keyword).map((n) => { + n.isEnable = this.extensionService.isEnable(n.name); + return n; + }); + } + const res: any = await this.extensionService.requestList(); + if (this.type === 'official') { + return new ExtensionList(res.data.filter((it) => it.author === 'Eoapi')).search(keyword); + } + return new ExtensionList(res.data).search(keyword); + } catch (error) { + } finally { + clearTimeout(timer); + const timeout = Date.now() - timeStart > 300 ? 0 : 300; + setTimeout(() => (this.loading = false), timeout); } - const res: any = await this.extensionService.requestList(); - if (this.type === 'official') { - return new ExtensionList(res.data.filter((it) => it.author === 'Eoapi')).search(keyword); - } - return new ExtensionList(res.data).search(keyword); } onSeachChange(keyword) { this.seachChanged$.next(keyword); } - clickExtension(item) { + clickExtension(event, item) { + console.log('event?.target?.dataset', event?.target); this.router .navigate(['home/extension/detail'], { queryParams: { type: this.route.snapshot.queryParams.type, id: item.moduleID, name: item.name, - jump: 'setting', + tab: event?.target?.dataset?.id === 'details' ? 1 : 0, }, }) .finally(); } + + handleEnableExtension(isEnable, item) { + if (isEnable) { + this.extensionService.enableExtension(item.name); + } else { + this.extensionService.disableExtension(item.name); + } + } + private watchSearchConditionChange() { this.route.queryParamMap.subscribe(async (params) => { this.type = this.route.snapshot.queryParams.type; diff --git a/src/workbench/browser/src/app/shared/components/export-api/export-api.component.ts b/src/workbench/browser/src/app/shared/components/export-api/export-api.component.ts index 6cc9ac8ce..1d2eca8b8 100644 --- a/src/workbench/browser/src/app/shared/components/export-api/export-api.component.ts +++ b/src/workbench/browser/src/app/shared/components/export-api/export-api.component.ts @@ -4,6 +4,7 @@ import { StorageRes, StorageResStatus } from '../../services/storage/index.model import packageJson from '../../../../../../../../package.json'; import { FeatureType } from '../../types'; import { ModuleInfo } from 'eo/platform/node/extension-manager'; +import { ExtensionService } from 'eo/workbench/browser/src/app/pages/extension/extension.service'; @Component({ selector: 'eo-export-api', @@ -13,13 +14,15 @@ export class ExportApiComponent implements OnInit { currentExtension = 'eoapi'; supportList: Array = []; featureMap = window.eo.getFeature('apimanage.export'); - constructor(private storage: StorageService) {} + constructor(private storage: StorageService, public extensionService: ExtensionService) {} ngOnInit(): void { this.featureMap?.forEach((data: FeatureType, key: string) => { - this.supportList.push({ - key, - ...data, - }); + if (this.extensionService.isEnable(data.name)) { + this.supportList.push({ + key, + ...data, + }); + } }); { const { key } = this.supportList.at(0); diff --git a/src/workbench/browser/src/app/shared/components/import-api/import-api.component.ts b/src/workbench/browser/src/app/shared/components/import-api/import-api.component.ts index 1674aa4ad..bb566926c 100644 --- a/src/workbench/browser/src/app/shared/components/import-api/import-api.component.ts +++ b/src/workbench/browser/src/app/shared/components/import-api/import-api.component.ts @@ -4,6 +4,7 @@ import { EoMessageService } from 'eo/workbench/browser/src/app/eoui/message/eo-m import { MessageService } from 'eo/workbench/browser/src/app/shared/services/message/message.service'; import { StorageService } from 'eo/workbench/browser/src/app/shared/services/storage'; import { StorageRes, StorageResStatus } from 'eo/workbench/browser/src/app/shared/services/storage/index.model'; +import { ExtensionService } from 'eo/workbench/browser/src/app/pages/extension/extension.service'; // const optionList = [ // { @@ -53,14 +54,17 @@ export class ImportApiComponent implements OnInit { constructor( private messageService: MessageService, private storage: StorageService, - private eoMessage: EoMessageService + private eoMessage: EoMessageService, + public extensionService: ExtensionService ) {} ngOnInit(): void { this.featureMap?.forEach((data: FeatureType, key: string) => { - this.supportList.push({ - key, - ...data, - }); + if (this.extensionService.isEnable(data.name)) { + this.supportList.push({ + key, + ...data, + }); + } }); { const { key } = this.supportList.at(0); 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 89f8999ae..32fedcd32 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,21 +1,13 @@ - +
- + {{ node.name }} @@ -24,11 +16,8 @@ - + {{ node.name }} @@ -42,16 +31,16 @@ - - + > --> + - +
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 f0ff9ba8d..4721d5051 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 @@ -5,7 +5,6 @@ import { FlatTreeControl } from '@angular/cdk/tree'; import { NzTreeFlatDataSource, NzTreeFlattener } from 'ng-zorro-antd/tree-view'; import { Message, MessageService } from '../../../shared/services/message'; import { Subject, takeUntil } from 'rxjs'; -import { NzMessageService } from 'ng-zorro-antd/message'; import { RemoteService } from 'eo/workbench/browser/src/app/shared/services/remote/remote.service'; import { SettingService } from 'eo/workbench/browser/src/app/core/services/settings/settings.service'; import { debounce } from 'eo/workbench/browser/src/app/utils'; @@ -105,10 +104,10 @@ export class SettingComponent implements OnInit { name: $localize`:@@Language:Language`, moduleID: 'eoapi-language', }, - { - name: $localize`Extensions`, - moduleID: 'eoapi-extensions', - }, + // { + // name: $localize`Extensions`, + // moduleID: 'eoapi-extensions', + // }, { name: $localize`About`, moduleID: 'eoapi-about', @@ -130,7 +129,6 @@ export class SettingComponent implements OnInit { private destroy$: Subject = new Subject(); constructor( private messageService: MessageService, - private message: NzMessageService, private remoteService: RemoteService, private settingService: SettingService ) {} @@ -231,9 +229,9 @@ export class SettingComponent implements OnInit { }, []); // All settings const treeData = JSON.parse(JSON.stringify(this.treeNodes)); - const extensions = treeData.find((n) => n.moduleID === 'eoapi-extensions'); - extensions.children = generateTreeData(this.extensitonConfigurations); - extensions.configuration = this.extensitonConfigurations; + // const extensions = treeData.find((n) => n.moduleID === 'eoapi-extensions'); + // extensions.children = generateTreeData(this.extensitonConfigurations); + // extensions.configuration = this.extensitonConfigurations; this.dataSource.setData(treeData); this.treeControl.expandAll(); diff --git a/src/workbench/browser/src/app/shared/components/shadow/eo-shadow-dom.component.scss b/src/workbench/browser/src/app/shared/components/shadow/eo-shadow-dom.component.scss new file mode 100644 index 000000000..fd4eec811 --- /dev/null +++ b/src/workbench/browser/src/app/shared/components/shadow/eo-shadow-dom.component.scss @@ -0,0 +1,40 @@ +:host { + .markdown-body { + font-size: 14px; + > :first-child { + margin-top: 12px !important; + } + img { + max-width: 600px; + } + h1 { + font-size: 16px; + } + h2 { + font-size: 16px; + } + h3 { + font-size: 16px; + } + h4, + h5, + h6, + h7 { + font-size: 14px; + } + h1, + h2, + h3, + h4, + h5, + h6, + h7 { + color: black; + font-weight: 600; + } + } + img { + margin: 0 auto; + display: block; + } +} diff --git a/src/workbench/browser/src/app/shared/components/shadow/shadow-dom-encapsulation.component.ts b/src/workbench/browser/src/app/shared/components/shadow/shadow-dom-encapsulation.component.ts index b615de310..94e145c50 100644 --- a/src/workbench/browser/src/app/shared/components/shadow/shadow-dom-encapsulation.component.ts +++ b/src/workbench/browser/src/app/shared/components/shadow/shadow-dom-encapsulation.component.ts @@ -8,15 +8,9 @@ import MarkdownIt from 'markdown-it/dist/markdown-it'; rel="stylesheet" href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/github-markdown-css/5.1.0/github-markdown.min.css" /> - -
-
-
+
`, + styleUrls: ['./eo-shadow-dom.component.scss'], encapsulation: ViewEncapsulation.ShadowDom, }) export class ShadowDomEncapsulationComponent implements OnInit { 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 4f0d1dc55..0b6101b41 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 @@ -3,6 +3,7 @@ import { StorageRes, StorageResStatus } from '../../services/storage/index.model import { StorageService } from '../../services/storage'; import packageJson from '../../../../../../../../package.json'; import { FeatureType } from '../../types'; +import { ExtensionService } from 'eo/workbench/browser/src/app/pages/extension/extension.service'; @Component({ selector: 'eo-sync-api', @@ -12,14 +13,16 @@ export class SyncApiComponent implements OnInit { currentExtension = ''; supportList: any[] = []; featureMap = window.eo.getFeature('apimanage.sync'); - constructor(private storage: StorageService) {} + constructor(private storage: StorageService, public extensionService: ExtensionService) {} ngOnInit(): void { this.featureMap?.forEach((data: FeatureType, key: string) => { - this.supportList.push({ - key, - ...data, - }); + if (this.extensionService.isEnable(data.name)) { + this.supportList.push({ + key, + ...data, + }); + } }); { const { key } = this.supportList.at(0); diff --git a/src/workbench/browser/src/app/shared/constant/storageKeys.ts b/src/workbench/browser/src/app/shared/constant/storageKeys.ts new file mode 100644 index 000000000..fb39a9863 --- /dev/null +++ b/src/workbench/browser/src/app/shared/constant/storageKeys.ts @@ -0,0 +1,2 @@ +/** disable extensions */ +export const DISABLE_EXTENSION_NAMES = 'DISABLE_EXTENSION_NAMES'; diff --git a/src/workbench/browser/src/app/shared/directives/index.ts b/src/workbench/browser/src/app/shared/directives/index.ts index 84937176f..978b43166 100644 --- a/src/workbench/browser/src/app/shared/directives/index.ts +++ b/src/workbench/browser/src/app/shared/directives/index.ts @@ -1 +1 @@ -export * from './webview/webview.directive'; +export * from './stop-propagation/stop-propagation.directive'; diff --git a/src/workbench/browser/src/app/shared/directives/stop-propagation/stop-propagation.directive.ts b/src/workbench/browser/src/app/shared/directives/stop-propagation/stop-propagation.directive.ts new file mode 100644 index 000000000..e8c9ccd26 --- /dev/null +++ b/src/workbench/browser/src/app/shared/directives/stop-propagation/stop-propagation.directive.ts @@ -0,0 +1,15 @@ +import { Directive, HostListener } from '@angular/core'; + +@Directive({ + selector: '[click-stop-propagation]', +}) +export class ClickStopPropagationDirective { + @HostListener('click', ['$event']) + public onClick(event: any): void { + event.stopPropagation(); + } + @HostListener('mousedown', ['$event']) + public onMousedown(event: any): void { + event.stopPropagation(); + } +} diff --git a/src/workbench/browser/src/app/shared/directives/webview/webview.directive.spec.ts b/src/workbench/browser/src/app/shared/directives/webview/webview.directive.spec.ts deleted file mode 100644 index d157f015b..000000000 --- a/src/workbench/browser/src/app/shared/directives/webview/webview.directive.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { WebviewDirective } from './webview.directive'; - -describe('WebviewDirective', () => { - it('should create an instance', () => { - const directive = new WebviewDirective(); - expect(directive).toBeTruthy(); - }); -}); diff --git a/src/workbench/browser/src/app/shared/directives/webview/webview.directive.ts b/src/workbench/browser/src/app/shared/directives/webview/webview.directive.ts deleted file mode 100644 index 239fed4a3..000000000 --- a/src/workbench/browser/src/app/shared/directives/webview/webview.directive.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Directive } from '@angular/core'; - -@Directive({ - selector: 'webview' -}) -export class WebviewDirective { - constructor() { } -} diff --git a/src/workbench/browser/src/app/shared/shared.module.ts b/src/workbench/browser/src/app/shared/shared.module.ts index 71491a3a9..b257094ab 100644 --- a/src/workbench/browser/src/app/shared/shared.module.ts +++ b/src/workbench/browser/src/app/shared/shared.module.ts @@ -1,11 +1,19 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { PageNotFoundComponent, ToolbarComponent, SidebarComponent } from './components'; -import { WebviewDirective } from './directives'; +import { ClickStopPropagationDirective } from './directives'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { NzDrawerModule } from 'ng-zorro-antd/drawer'; +import { NzFormModule } from 'ng-zorro-antd/form'; +import { NzInputModule } from 'ng-zorro-antd/input'; +import { NzInputNumberModule } from 'ng-zorro-antd/input-number'; import { NzRadioModule } from 'ng-zorro-antd/radio'; +import { NzCheckboxModule } from 'ng-zorro-antd/checkbox'; +import { NzAvatarModule } from 'ng-zorro-antd/avatar'; +import { NzSwitchModule } from 'ng-zorro-antd/switch'; +import { NzTabsModule } from 'ng-zorro-antd/tabs'; +import { NzSkeletonModule } from 'ng-zorro-antd/skeleton'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; import { NzResultModule } from 'ng-zorro-antd/result'; @@ -16,6 +24,9 @@ import { NzCardModule } from 'ng-zorro-antd/card'; import { NzPopoverModule } from 'ng-zorro-antd/popover'; import { NzCodeEditorModule } from 'ng-zorro-antd/code-editor'; import { NzResizableModule } from 'ng-zorro-antd/resizable'; +import { NzDividerModule } from 'ng-zorro-antd/divider'; +import { NzModalModule } from 'ng-zorro-antd/modal'; +import { NzTypographyModule } from 'ng-zorro-antd/typography'; import { NzNotificationModule } from 'ng-zorro-antd/notification'; import { NzMessageModule } from 'ng-zorro-antd/message'; @@ -53,6 +64,7 @@ const SHARED_MODULE = [ FormsModule, RouterModule, ReactiveFormsModule, + NzFormModule, NzDrawerModule, NzRadioModule, NzButtonModule, @@ -65,19 +77,28 @@ const SHARED_MODULE = [ NzEmptyModule, NzMessageModule, NzDescriptionsModule, - EoIconparkIconModule, + NzInputModule, + NzCheckboxModule, EouiModule, NzTreeModule, + NzAvatarModule, + NzTabsModule, + NzSkeletonModule, NzPopoverModule, NzCodeEditorModule, NzResizableModule, EoIconparkIconModule, + NzInputNumberModule, + NzSwitchModule, + NzDividerModule, + NzModalModule, + NzTypographyModule, ] as const; @NgModule({ imports: [...SHARED_MODULE], - declarations: [WebviewDirective, ...COMPONENTS, ApiParamsNumPipe, PageBlankComponent, EnvListComponent], + declarations: [...COMPONENTS, ClickStopPropagationDirective, ApiParamsNumPipe, PageBlankComponent, EnvListComponent], providers: [ModalService], - exports: [...SHARED_MODULE, ...COMPONENTS, WebviewDirective, ApiParamsNumPipe], + exports: [...SHARED_MODULE, ...COMPONENTS, ClickStopPropagationDirective, ApiParamsNumPipe], }) export class SharedModule {} diff --git a/src/workbench/browser/src/app/shared/types.ts b/src/workbench/browser/src/app/shared/types.ts index 264779fa8..6fd99cd3e 100644 --- a/src/workbench/browser/src/app/shared/types.ts +++ b/src/workbench/browser/src/app/shared/types.ts @@ -1,6 +1,7 @@ export type FeatureType = { icon: string; label: string; + name: string; description: string; key?: string; properties?: object; diff --git a/src/workbench/browser/src/assets/theme/antd.less b/src/workbench/browser/src/assets/theme/antd.less index 26eb0a663..a31505493 100644 --- a/src/workbench/browser/src/assets/theme/antd.less +++ b/src/workbench/browser/src/assets/theme/antd.less @@ -10,12 +10,16 @@ @primary-color: @theme-color; @primary-color-hover: @theme-color; @success-color: @theme-color; -@link-color:#333; +@link-color: #333; @processing-color: @theme-color; @tree-title-height: 30px; body { line-height: initial; } +.ant-btn-link, +.ant-btn-link:hover { + color: var(--BLUE_DEEPER); +} // .ant-message-notice-content { // background-color: @theme-color; // color: #fff; @@ -71,9 +75,6 @@ body { p { margin-bottom: 0; } -.ant-btn { - border-radius: 3px !important; -} .ant-dropdown { background-color: white; } diff --git a/src/workbench/browser/src/index.html b/src/workbench/browser/src/index.html index d6130a42d..a4633934f 100644 --- a/src/workbench/browser/src/index.html +++ b/src/workbench/browser/src/index.html @@ -1,60 +1,63 @@ - - - Eoapi - Easy & Open Source API Ecosystem - - - - - - - - - -
- -
- - - - - - -
+ + + Eoapi - Easy & Open Source API Ecosystem + + + + + + + + + + + +
+ +
+ + + + + +
- -
- - + .loading_container img { + width: 200px; + } +