mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-10-14 09:22:10 +08:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
abab44ad24 | ||
|
849b561933 | ||
|
1031595a97 | ||
|
f5cb19dfa4 | ||
|
e400175ffe |
@ -55,7 +55,7 @@
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"element-plus": "^2.9.11",
|
||||
"enquirer": "^2.4.1",
|
||||
"eslint": "^9.34.0",
|
||||
"eslint": "^9.35.0",
|
||||
"execa": "^4.1.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"husky": "^9.1.7",
|
||||
@ -76,7 +76,7 @@
|
||||
"vitepress": "^1.6.4",
|
||||
"vitest": "^3.2.4",
|
||||
"vue": "catalog:",
|
||||
"vue-tsc": "^3.0.6"
|
||||
"vue-tsc": "^3.0.7"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
|
@ -167,8 +167,13 @@ class App extends EventEmitter {
|
||||
this.setPage(pageId);
|
||||
|
||||
if (this.dataSourceManager) {
|
||||
const dataSourceList = Array.from(this.dataSourceManager.dataSourceMap.values());
|
||||
this.eventHelper?.bindDataSourceEvents(dataSourceList);
|
||||
if (this.dataSourceManager.isAllDataSourceRegistered()) {
|
||||
this.eventHelper?.bindDataSourceEvents();
|
||||
} else {
|
||||
this.dataSourceManager.once('registered-all', () => {
|
||||
this.eventHelper?.bindDataSourceEvents();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,15 +264,15 @@ class App extends EventEmitter {
|
||||
* @param eventConfig 代码动作的配置
|
||||
* @returns void
|
||||
*/
|
||||
public async runCode(codeId: Id, params: Record<string, any>, args: any[], flowState?: FlowState) {
|
||||
public async runCode(codeId: Id, params: Record<string, any>, args: any[], flowState?: FlowState, node?: Node) {
|
||||
if (!codeId || isEmpty(this.codeDsl)) return;
|
||||
const content = this.codeDsl?.[codeId]?.content;
|
||||
if (typeof content === 'function') {
|
||||
try {
|
||||
await content({ app: this, params, eventParams: args, flowState });
|
||||
await content({ app: this, params, eventParams: args, flowState, node });
|
||||
} catch (e: any) {
|
||||
if (this.errorHandler) {
|
||||
this.errorHandler(e, undefined, { type: 'run-code', codeId, params, eventParams: args, flowState });
|
||||
this.errorHandler(e, undefined, { type: 'run-code', codeId, params, eventParams: args, flowState, node });
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
@ -281,6 +286,7 @@ class App extends EventEmitter {
|
||||
params: Record<string, any>,
|
||||
args: any[],
|
||||
flowState?: FlowState,
|
||||
node?: Node,
|
||||
) {
|
||||
if (!dsId || !methodName) return;
|
||||
|
||||
@ -293,13 +299,13 @@ class App extends EventEmitter {
|
||||
|
||||
const method = methods.find((item) => item.name === methodName);
|
||||
if (method && typeof method.content === 'function') {
|
||||
await method.content({ app: this, params, dataSource, eventParams: args, flowState });
|
||||
await method.content({ app: this, params, dataSource, eventParams: args, flowState, node });
|
||||
} else if (typeof dataSource[methodName] === 'function') {
|
||||
await dataSource[methodName]();
|
||||
}
|
||||
} catch (e: any) {
|
||||
if (this.errorHandler) {
|
||||
this.errorHandler(e, dataSource, { type: 'data-source-method', params, eventParams: args, flowState });
|
||||
this.errorHandler(e, dataSource, { type: 'data-source-method', params, eventParams: args, flowState, node });
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
@ -113,21 +113,23 @@ export default class EventHelper extends EventEmitter {
|
||||
}
|
||||
|
||||
public removeNodeEvents() {
|
||||
Array.from(this.nodeEventList.keys()).forEach((handler) => {
|
||||
for (const handler of Array.from(this.nodeEventList.keys())) {
|
||||
const name = this.nodeEventList.get(handler);
|
||||
name && this.off(name, handler);
|
||||
});
|
||||
}
|
||||
|
||||
this.nodeEventList.clear();
|
||||
}
|
||||
|
||||
public bindDataSourceEvents(dataSourceList: DataSource[]) {
|
||||
public bindDataSourceEvents() {
|
||||
const dataSourceList = Array.from(this.app.dataSourceManager?.dataSourceMap.values() || []);
|
||||
|
||||
this.removeDataSourceEvents(dataSourceList);
|
||||
|
||||
dataSourceList.forEach((dataSource) => {
|
||||
for (const dataSource of dataSourceList) {
|
||||
const dataSourceEvent = this.dataSourceEventList.get(dataSource.id) ?? new Map<string, (args: any) => void>();
|
||||
|
||||
(dataSource.schema.events || []).forEach((event) => {
|
||||
for (const event of dataSource.schema.events || []) {
|
||||
const [prefix, ...path] = event.name?.split('.') || [];
|
||||
if (!prefix) return;
|
||||
const handler = (...args: any[]) => {
|
||||
@ -141,9 +143,9 @@ export default class EventHelper extends EventEmitter {
|
||||
// 数据源自定义事件
|
||||
dataSource.on(prefix, handler);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.dataSourceEventList.set(dataSource.id, dataSourceEvent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public removeDataSourceEvents(dataSourceList: DataSource[]) {
|
||||
@ -152,20 +154,20 @@ export default class EventHelper extends EventEmitter {
|
||||
}
|
||||
|
||||
// 先清掉之前注册的事件,重新注册
|
||||
dataSourceList.forEach((dataSource) => {
|
||||
for (const dataSource of dataSourceList) {
|
||||
const dataSourceEvent = this.dataSourceEventList.get(dataSource.id)!;
|
||||
|
||||
if (!dataSourceEvent) return;
|
||||
|
||||
Array.from(dataSourceEvent.keys()).forEach((eventName) => {
|
||||
for (const eventName of Array.from(dataSourceEvent.keys())) {
|
||||
const [prefix, ...path] = eventName.split('.');
|
||||
if (prefix === DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX) {
|
||||
dataSource.offDataChange(path.join('.'), dataSourceEvent.get(eventName)!);
|
||||
} else {
|
||||
dataSource.off(prefix, dataSourceEvent.get(eventName)!);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.dataSourceEventList.clear();
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
import { DataSource } from '@tmagic/data-source';
|
||||
import type { EventConfig, MNode } from '@tmagic/schema';
|
||||
import { HookCodeType, HookType, NODE_DISABLE_CODE_BLOCK_KEY } from '@tmagic/schema';
|
||||
|
||||
@ -141,23 +140,10 @@ class Node extends EventEmitter {
|
||||
for (const item of hookData.hookData) {
|
||||
const { codeType = HookCodeType.CODE, codeId, params: itemParams = {} } = item;
|
||||
|
||||
let functionContent: ((...args: any[]) => any) | string | undefined;
|
||||
const functionParams: { app: TMagicApp; node: Node; params: Record<string, any>; dataSource?: DataSource } = {
|
||||
app: this.app,
|
||||
node: this,
|
||||
params: params || itemParams,
|
||||
};
|
||||
|
||||
if (codeType === HookCodeType.CODE && typeof codeId === 'string' && this.app.codeDsl?.[codeId]) {
|
||||
functionContent = this.app.codeDsl[codeId].content;
|
||||
if (codeType === HookCodeType.CODE && typeof codeId === 'string') {
|
||||
await this.app.runCode(codeId, params || itemParams, [], undefined, this);
|
||||
} else if (codeType === HookCodeType.DATA_SOURCE_METHOD && Array.isArray(codeId) && codeId.length > 1) {
|
||||
const dataSource = this.app.dataSourceManager?.get(codeId[0]);
|
||||
functionContent = dataSource?.methods.find((method) => method.name === codeId[1])?.content;
|
||||
functionParams.dataSource = dataSource;
|
||||
}
|
||||
|
||||
if (functionContent && typeof functionContent === 'function') {
|
||||
await functionContent(functionParams);
|
||||
await this.app.runDataSourceMethod(codeId[0], codeId[1], params || itemParams, [], undefined, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,9 @@ export class DeepObservedData extends ObservedData {
|
||||
update = (data: any, path?: string) => {
|
||||
this.state?.update(path ?? '', data);
|
||||
};
|
||||
on = (path: string, callback: (newVal: any) => void) => {
|
||||
on = (path: string, callback: (newVal: any) => void, options?: { immediate?: boolean }) => {
|
||||
// subscribe 会立即执行一次,ignoreFirstCall 会忽略第一次执行
|
||||
const unsubscribe = this.state!.subscribe(path, ignoreFirstCall(callback));
|
||||
const unsubscribe = this.state!.subscribe(path, options?.immediate ? callback : ignoreFirstCall(callback));
|
||||
|
||||
// 把取消监听的函数保存下来,供 off 时调用
|
||||
const pathSubscribers = this.subscribers.get(path) ?? new Map<Function, () => void>();
|
||||
|
@ -1,7 +1,7 @@
|
||||
export abstract class ObservedData {
|
||||
abstract update(data: any, path?: string): void;
|
||||
|
||||
abstract on(path: string, callback: (newVal: any) => void): void;
|
||||
abstract on(path: string, callback: (newVal: any) => void, options?: { immediate?: boolean }): void;
|
||||
|
||||
abstract off(path: string, callback: (newVal: any) => void): void;
|
||||
|
||||
|
@ -32,7 +32,10 @@ export class SimpleObservedData extends ObservedData {
|
||||
this.event.emit('', changeEvent);
|
||||
}
|
||||
|
||||
on(path: string, callback: (newVal: any) => void): void {
|
||||
on(path: string, callback: (newVal: any) => void, options?: { immediate?: boolean }): void {
|
||||
if (options?.immediate) {
|
||||
callback(this.getData(path));
|
||||
}
|
||||
this.event.on(path, callback);
|
||||
}
|
||||
|
||||
|
@ -11,19 +11,21 @@
|
||||
:width="160"
|
||||
:destroy-on-close="true"
|
||||
>
|
||||
<div>
|
||||
<slot name="page-list-popover" :list="list">
|
||||
<ToolButton
|
||||
v-for="(item, index) in list"
|
||||
:data="{
|
||||
type: 'button',
|
||||
text: item.devconfig?.tabName || item.name || item.id,
|
||||
className: item.id === page?.id ? 'active' : '',
|
||||
handler: () => switchPage(item.id),
|
||||
}"
|
||||
:key="index"
|
||||
></ToolButton>
|
||||
</slot>
|
||||
<div class="page-bar-popover-wrapper">
|
||||
<div class="page-bar-popover-inner">
|
||||
<slot name="page-list-popover" :list="list">
|
||||
<ToolButton
|
||||
v-for="(item, index) in list"
|
||||
:data="{
|
||||
type: 'button',
|
||||
text: item.devconfig?.tabName || item.name || item.id,
|
||||
className: item.id === page?.id ? 'active' : '',
|
||||
handler: () => switchPage(item.id),
|
||||
}"
|
||||
:key="index"
|
||||
></ToolButton>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
<template #reference>
|
||||
<TMagicIcon class="m-editor-page-list-menu-icon">
|
||||
|
@ -92,6 +92,11 @@
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.page-bar-popover-wrapper {
|
||||
max-height: calc(100vh - $page-bar-height - 20px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease 0s;
|
||||
|
515
pnpm-lock.yaml
generated
515
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -7,8 +7,8 @@ packages:
|
||||
- 'eslint-config'
|
||||
|
||||
catalog:
|
||||
vue: ^3.5.20
|
||||
vue: ^3.5.21
|
||||
'@vue/compiler-sfc': ^3.5.20
|
||||
vite: ^7.1.3
|
||||
vite: ^7.1.5
|
||||
typescript: "^5.9.2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user