From 39b051dda4510eb25a4a85835d1857af89d4f9d3 Mon Sep 17 00:00:00 2001 From: everright Date: Tue, 10 May 2022 00:59:20 +0800 Subject: [PATCH] feat: add settings of modules --- src/app/electron-main/main.ts | 18 +++- src/core/market/browser/package.json | 2 +- src/platform/electron-browser/preload.ts | 20 ++++ src/platform/node/configuration/index.ts | 1 + src/platform/node/configuration/lib/index.ts | 100 +++++++++++++++++ .../node/configuration/types/index.ts | 14 +++ .../node/extension-manager/lib/manager.ts | 2 +- src/workbench/browser/src/app/app.module.ts | 2 - .../src/app/pages/pages.component.html | 1 + .../browser/src/app/pages/pages.module.ts | 4 +- .../app/pages/setting/setting.component.html | 24 +++++ .../app/pages/setting/setting.component.scss | 16 +++ .../app/pages/setting/setting.component.ts | 101 ++++++++++++++++++ .../src/app/pages/setting/setting.module.ts | 33 ++++++ 14 files changed, 329 insertions(+), 9 deletions(-) create mode 100644 src/platform/node/configuration/index.ts create mode 100644 src/platform/node/configuration/lib/index.ts create mode 100644 src/platform/node/configuration/types/index.ts create mode 100644 src/workbench/browser/src/app/pages/setting/setting.component.html create mode 100644 src/workbench/browser/src/app/pages/setting/setting.component.scss create mode 100644 src/workbench/browser/src/app/pages/setting/setting.component.ts create mode 100644 src/workbench/browser/src/app/pages/setting/setting.module.ts diff --git a/src/app/electron-main/main.ts b/src/app/electron-main/main.ts index d8d2bccbb..1281019eb 100644 --- a/src/app/electron-main/main.ts +++ b/src/app/electron-main/main.ts @@ -1,24 +1,26 @@ import { app, BrowserWindow, ipcMain, screen } from 'electron'; import { EoUpdater } from './updater'; import * as path from 'path'; -import * as os from 'os'; +import * as os from 'os' import ModuleManager from '../../platform/node/extension-manager/lib/manager'; import { ModuleInfo, ModuleManagerInterface } from '../../platform/node/extension-manager'; import { StorageHandleStatus, StorageProcessType } from '../../platform/browser/IndexedDB'; import { AppViews } from './appView'; -import { CoreViews } from './coreView'; import { processEnv } from '../../platform/node/constant'; import { proxyOpenExternal } from '../../shared/common/browserView'; import { deleteFile, readJson } from '../../shared/node/file'; import { STORAGE_TEMP as storageTemp } from '../../shared/common/constant'; import { UnitWorkerModule } from '../../workbench/node/unitWorker'; +import Configuration from '../../platform/node/configuration/lib'; +import { ConfigurationInterface } from 'src/platform/node/configuration'; let win: BrowserWindow = null; export const subView = { appView: null, mainView: null, }; -const eoUpdater = new EoUpdater(); +const eoUpdater = new EoUpdater() const moduleManager: ModuleManagerInterface = ModuleManager(); +const configuration: ConfigurationInterface = Configuration(); // Remote const mainRemote = require('@electron/remote/main'); mainRemote.initialize(); @@ -215,6 +217,16 @@ try { returnValue = moduleManager.getFeatures(); } else if (arg.action === 'getFeature') { returnValue = moduleManager.getFeature(arg.data.featureKey); + } else if (arg.action === 'saveSettings') { + returnValue = configuration.saveSettings(arg.data.settings); + } else if (arg.action === 'saveModuleSettings') { + returnValue = configuration.saveModuleSettings(arg.data.moduleID, arg.data.settings); + } else if (arg.action === 'deleteModuleSettings') { + returnValue = configuration.deleteModuleSettings(arg.data.moduleID); + } else if (arg.action === 'getSettings') { + returnValue = configuration.getSettings(); + } else if (arg.action === 'getModuleSettings') { + returnValue = configuration.getModuleSettings(arg.data.moduleID); } else if (arg.action === 'getSidePosition') { returnValue = subView.appView?.sidePosition; } else if (arg.action === 'hook') { diff --git a/src/core/market/browser/package.json b/src/core/market/browser/package.json index a4874ae30..627e50389 100644 --- a/src/core/market/browser/package.json +++ b/src/core/market/browser/package.json @@ -26,7 +26,7 @@ "core.market.url": { "type": "string", "required": true, - "default": "", + "default": "http://127.0.0.1", "label": "服务器地址", "description": "插件安装来源的服务器地址" }, diff --git a/src/platform/electron-browser/preload.ts b/src/platform/electron-browser/preload.ts index b0587441b..a525bc020 100644 --- a/src/platform/electron-browser/preload.ts +++ b/src/platform/electron-browser/preload.ts @@ -139,3 +139,23 @@ window.eo.storageRemote = (args) => { shareObject.storageResult = null; return output; }; + +window.eo.saveSettings = (settings) => { + return ipcRenderer.sendSync('eo-sync', { action: 'saveSettings', data: { settings: settings } }); +}; + +window.eo.saveModuleSettings = (moduleID, settings) => { + return ipcRenderer.sendSync('eo-sync', { action: 'saveModuleSettings', data: { moduleID: moduleID, settings: settings } }); +}; + +window.eo.deleteModuleSettings = (moduleID) => { + return ipcRenderer.sendSync('eo-sync', { action: 'deleteModuleSettings', data: { moduleID: moduleID } }); +}; + +window.eo.getSettings = (settings) => { + return ipcRenderer.sendSync('eo-sync', { action: 'getSettings' }); +}; + +window.eo.getModuleSettings = (moduleID) => { + return ipcRenderer.sendSync('eo-sync', { action: 'getModuleSettings', data: { moduleID: moduleID } }); +}; diff --git a/src/platform/node/configuration/index.ts b/src/platform/node/configuration/index.ts new file mode 100644 index 000000000..fcdac2de7 --- /dev/null +++ b/src/platform/node/configuration/index.ts @@ -0,0 +1 @@ +export * from './types'; \ No newline at end of file diff --git a/src/platform/node/configuration/lib/index.ts b/src/platform/node/configuration/lib/index.ts new file mode 100644 index 000000000..c13da5a34 --- /dev/null +++ b/src/platform/node/configuration/lib/index.ts @@ -0,0 +1,100 @@ +import { DATA_DIR as dataDir } from '../../../../shared/common/constant'; +import { ConfigurationInterface, ConfigurationValueInterface } from '../types'; +import * as path from 'path'; +import { fileExists, readJson, writeJson } from '../../../../shared/node/file'; + +export class Configuration implements ConfigurationInterface { + + /** + * 配置文件地址 + */ + private readonly configPath: string; + + constructor() { + this.configPath = path.join(dataDir, 'config.json'); + this.checkConfig(); + } + + /** + * 检查配置文件,不存在创建 + */ + private checkConfig() { + if (!fileExists(this.configPath)) { + this.saveConfig({ settings: {} }); + } + } + + /** + * 读取配置文件 + */ + private loadConfig(): ConfigurationValueInterface { + const data = readJson(this.configPath) || { settings: {} }; + return data; + } + + /** + * 保存配置文件 + */ + private saveConfig(data: ConfigurationValueInterface): boolean { + return writeJson(this.configPath, data); + } + + /** + * 保存全局配置 + */ + saveSettings(settings: ConfigurationValueInterface): boolean { + let data = this.loadConfig(); + data.settings = settings; + return this.saveConfig(data); + } + + /** + * 保存模块配置 + * @param moduleID + * @param settings + */ + saveModuleSettings(moduleID: string, settings: ConfigurationValueInterface): boolean { + let data = this.loadConfig(); + if (!data.settings) { + data.settings = {}; + } + data.settings[moduleID] = settings; + return this.saveConfig(data); + } + + /** + * 删除模块配置 + * @param moduleID + * @returns + */ + deleteModuleSettings(moduleID: string): boolean { + let data = this.loadConfig(); + if (data.settings && data.settings[moduleID]) { + delete(data.settings[moduleID]); + return this.saveConfig(data); + } + return false; + } + + /** + * 获取全局配置 + * @returns + */ + getSettings(): ConfigurationValueInterface { + const data = this.loadConfig(); + return data.settings; + } + + /** + * 获取模块配置 + * @param moduleID + * @returns + */ + getModuleSettings(moduleID: string): ConfigurationValueInterface { + const settings = this.getSettings(); + return settings[moduleID] || {}; + } + +} + +export default () => new Configuration(); diff --git a/src/platform/node/configuration/types/index.ts b/src/platform/node/configuration/types/index.ts new file mode 100644 index 000000000..2b3f20379 --- /dev/null +++ b/src/platform/node/configuration/types/index.ts @@ -0,0 +1,14 @@ +/** + * 配置管理 + */ +export interface ConfigurationInterface { + saveSettings: (settings: ConfigurationValueInterface) => boolean; + saveModuleSettings: (moduleID: string, settings: ConfigurationValueInterface) => boolean; + deleteModuleSettings: (moduleID: string) => boolean; + getSettings: () => ConfigurationValueInterface; + getModuleSettings: (moduleID: string) => ConfigurationValueInterface; +} + +export interface ConfigurationValueInterface { + [propName: string]: any; +} diff --git a/src/platform/node/extension-manager/lib/manager.ts b/src/platform/node/extension-manager/lib/manager.ts index d2820dec3..ff7653e33 100644 --- a/src/platform/node/extension-manager/lib/manager.ts +++ b/src/platform/node/extension-manager/lib/manager.ts @@ -3,7 +3,7 @@ import { ModuleHandler } from './handler'; import { CoreHandler } from './core'; import { ModuleHandlerResult, ModuleInfo, ModuleManagerInfo, ModuleManagerInterface, ModuleType } from '../types'; import * as path from 'path'; -import { isNotEmpty } from '../../../..//shared/common/common'; +import { isNotEmpty } from '../../../../shared/common/common'; export class ModuleManager implements ModuleManagerInterface { /** diff --git a/src/workbench/browser/src/app/app.module.ts b/src/workbench/browser/src/app/app.module.ts index dafa45936..3baf10847 100644 --- a/src/workbench/browser/src/app/app.module.ts +++ b/src/workbench/browser/src/app/app.module.ts @@ -13,7 +13,6 @@ import { EnvState } from './shared/store/env.state'; // NG1 Upgrade import { UpgradeModule } from '@angular/upgrade/static'; -import { NzModalModule } from 'ng-zorro-antd/modal'; @NgModule({ declarations: [AppComponent], @@ -25,7 +24,6 @@ import { NzModalModule } from 'ng-zorro-antd/modal'; AppRoutingModule, HttpClientModule, UpgradeModule, - NzModalModule, NgxsModule.forRoot([EnvState]), ], providers: [ diff --git a/src/workbench/browser/src/app/pages/pages.component.html b/src/workbench/browser/src/app/pages/pages.component.html index 6e45ffde8..2ad87fcc6 100644 --- a/src/workbench/browser/src/app/pages/pages.component.html +++ b/src/workbench/browser/src/app/pages/pages.component.html @@ -1,5 +1,6 @@
+
diff --git a/src/workbench/browser/src/app/pages/pages.module.ts b/src/workbench/browser/src/app/pages/pages.module.ts index 9c18c5a91..22e8e1290 100644 --- a/src/workbench/browser/src/app/pages/pages.module.ts +++ b/src/workbench/browser/src/app/pages/pages.module.ts @@ -2,13 +2,13 @@ import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { PagesRoutingModule } from './pages-routing.module'; - +import { SettingModule } from './setting/setting.module' import { PagesComponent } from './pages.component'; import { SharedModule } from '../shared/shared.module'; @NgModule({ declarations: [PagesComponent], - imports: [PagesRoutingModule, FormsModule, SharedModule], + imports: [PagesRoutingModule, FormsModule, SharedModule, SettingModule], exports: [] }) export class PagesModule {} diff --git a/src/workbench/browser/src/app/pages/setting/setting.component.html b/src/workbench/browser/src/app/pages/setting/setting.component.html new file mode 100644 index 000000000..391dcd73a --- /dev/null +++ b/src/workbench/browser/src/app/pages/setting/setting.component.html @@ -0,0 +1,24 @@ + + + + + +
+
+ + + + {{ field.label }} + + + + + + +
+
+ +
diff --git a/src/workbench/browser/src/app/pages/setting/setting.component.scss b/src/workbench/browser/src/app/pages/setting/setting.component.scss new file mode 100644 index 000000000..8c1064c52 --- /dev/null +++ b/src/workbench/browser/src/app/pages/setting/setting.component.scss @@ -0,0 +1,16 @@ +.sidebar_setting { + font-size: 20px; + position: absolute; + padding: 15px; + bottom: 0; +} + +.flex { + display: flex; + width: 100%; + height: 60vh; +} + +.footer { + text-align: right; +} \ No newline at end of file diff --git a/src/workbench/browser/src/app/pages/setting/setting.component.ts b/src/workbench/browser/src/app/pages/setting/setting.component.ts new file mode 100644 index 000000000..1cb41d8fe --- /dev/null +++ b/src/workbench/browser/src/app/pages/setting/setting.component.ts @@ -0,0 +1,101 @@ +import { Component, OnInit } from '@angular/core'; +import { NzTabPosition } from 'ng-zorro-antd/tabs'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +@Component({ + selector: 'eo-setting', + templateUrl: './setting.component.html', + styleUrls: ['./setting.component.scss'], +}) +export class SettingComponent implements OnInit { + isVisible = false; + isModal = false; + position: NzTabPosition = 'left'; + modules = []; + settings = {}; + validateForm!: FormGroup; + constructor( + private fb: FormBuilder, + ) {} + + ngOnInit(): void { + this.init(); + } + + 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; + } + + 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; + } + // 加入根据返回显示提示消息 + const saved = window.eo.saveSettings(this.settings); + if (saved) { + this.handleCancel(); + } + } + + handleCancel(): void { + this.isModal = false; + } +} diff --git a/src/workbench/browser/src/app/pages/setting/setting.module.ts b/src/workbench/browser/src/app/pages/setting/setting.module.ts new file mode 100644 index 000000000..dddd17ee2 --- /dev/null +++ b/src/workbench/browser/src/app/pages/setting/setting.module.ts @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { SettingComponent } from './setting.component'; +import { NzModalModule } from 'ng-zorro-antd/modal'; +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 { NzFormModule } from 'ng-zorro-antd/form'; +import { NzSelectModule } from 'ng-zorro-antd/select'; +import { NzDividerModule } from 'ng-zorro-antd/divider'; +import { NzTabsModule } from 'ng-zorro-antd/tabs'; +import { ElectronService } from '../../core/services'; + +const ANTDMODULES = [ + NzModalModule, + NzButtonModule, + NzIconModule, + NzListModule, + NzInputModule, + NzFormModule, + NzSelectModule, + NzDividerModule, + NzTabsModule, +]; +@NgModule({ + declarations: [SettingComponent], + imports: [FormsModule, ReactiveFormsModule, CommonModule, ...ANTDMODULES], + exports: [SettingComponent], + providers: [ElectronService], +}) +export class SettingModule {}