layer.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. /* eslint-disable react/no-deprecated */
  6. import React from 'react';
  7. import { inject } from 'inversify';
  8. import { domUtils } from '@flowgram.ai/utils';
  9. import { nanoid } from '@flowgram.ai/free-layout-core';
  10. import { Layer } from '@flowgram.ai/core';
  11. import type {
  12. CallNodePanelParams,
  13. NodePanelLayerOptions,
  14. NodePanelRenderProps,
  15. NodePanelResult,
  16. } from './type';
  17. import { WorkflowNodePanelService } from './service';
  18. export class WorkflowNodePanelLayer extends Layer<NodePanelLayerOptions> {
  19. public static type = 'WorkflowNodePanelLayer';
  20. @inject(WorkflowNodePanelService) private service: WorkflowNodePanelService;
  21. public node: HTMLDivElement;
  22. private renderList: Map<string, NodePanelRenderProps>;
  23. constructor() {
  24. super();
  25. this.node = domUtils.createDivWithClass('gedit-playground-layer gedit-node-panel-layer');
  26. this.node.style.zIndex = '9999';
  27. this.renderList = new Map();
  28. }
  29. public onReady(): void {
  30. this.service.setCallNodePanel(this.call.bind(this));
  31. }
  32. public onZoom(zoom: number): void {
  33. this.node.style.transform = `scale(${zoom})`;
  34. }
  35. public render(): JSX.Element {
  36. const NodePanelRender = this.options.renderer;
  37. return (
  38. <>
  39. {Array.from(this.renderList.keys()).map((taskId) => {
  40. const renderProps = this.renderList.get(taskId)!;
  41. return <NodePanelRender key={taskId} {...renderProps} />;
  42. })}
  43. </>
  44. );
  45. }
  46. private async call(params: CallNodePanelParams): Promise<void> {
  47. const taskId = nanoid();
  48. const { onSelect, onClose, enableMultiAdd = false, panelProps = {} } = params;
  49. return new Promise((resolve) => {
  50. const unmount = () => {
  51. // 清理挂载的组件
  52. this.renderList.delete(taskId);
  53. this.render();
  54. resolve();
  55. };
  56. const handleClose = () => {
  57. unmount();
  58. onClose();
  59. };
  60. const handleSelect = (params?: NodePanelResult) => {
  61. onSelect(params);
  62. if (!enableMultiAdd) {
  63. unmount();
  64. }
  65. };
  66. const renderProps: NodePanelRenderProps = {
  67. ...params,
  68. panelProps,
  69. onSelect: handleSelect,
  70. onClose: handleClose,
  71. };
  72. this.renderList.set(taskId, renderProps);
  73. this.render();
  74. });
  75. }
  76. }