@nocobase/flow-engine 2.1.0-beta.32 → 2.1.0-beta.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,4 +39,15 @@ export declare const Droppable: FC<{
39
39
  model: FlowModel<any>;
40
40
  children: React.ReactNode;
41
41
  }>;
42
- export declare const DndProvider: FC<DndContextProps & PersistOptions>;
42
+ export interface DndProviderProps extends DndContextProps, PersistOptions {
43
+ /**
44
+ * Whether to render the built-in `DragOverlay` (the "Dragging" pill that
45
+ * follows the cursor). Defaults to `true` for backwards compatibility with
46
+ * existing flow-engine drag interactions. Set to `false` when the
47
+ * surrounding UI already gives clear visual feedback (e.g. a drag-sort
48
+ * table that highlights the drop position) and the floating pill would be
49
+ * redundant.
50
+ */
51
+ showDragOverlay?: boolean;
52
+ }
53
+ export declare const DndProvider: FC<DndProviderProps>;
@@ -274,6 +274,7 @@ const Droppable = /* @__PURE__ */ __name(({ model, children }) => {
274
274
  }, "Droppable");
275
275
  const DndProvider = /* @__PURE__ */ __name(({
276
276
  persist = true,
277
+ showDragOverlay = true,
277
278
  children,
278
279
  onDragStart,
279
280
  onDragEnd,
@@ -337,7 +338,7 @@ const DndProvider = /* @__PURE__ */ __name(({
337
338
  ...restProps
338
339
  },
339
340
  children,
340
- typeof document !== "undefined" ? (0, import_react_dom.createPortal)(
341
+ showDragOverlay && typeof document !== "undefined" ? (0, import_react_dom.createPortal)(
341
342
  /* @__PURE__ */ import_react.default.createElement(
342
343
  import_core.DragOverlay,
343
344
  {
@@ -253,6 +253,13 @@ const SearchInputWithAutoFocus = /* @__PURE__ */ __name((props) => {
253
253
  return /* @__PURE__ */ import_react.default.createElement(import_antd.Input, { ref: inputRef, ...rest });
254
254
  }, "SearchInputWithAutoFocus");
255
255
  const getKeyPath = /* @__PURE__ */ __name((path, key) => [...path, key].join("/"), "getKeyPath");
256
+ const normalizeOpenKeys = /* @__PURE__ */ __name((nextOpenKeys) => {
257
+ const latestKey = nextOpenKeys[nextOpenKeys.length - 1];
258
+ if (!latestKey) {
259
+ return [];
260
+ }
261
+ return nextOpenKeys.filter((key) => latestKey === key || latestKey.startsWith(`${key}/`));
262
+ }, "normalizeOpenKeys");
256
263
  const createSearchItem = /* @__PURE__ */ __name((item, searchKey, currentSearchValue, menuVisible, t, updateSearchValue) => ({
257
264
  key: `${searchKey}-search`,
258
265
  type: "group",
@@ -286,6 +293,10 @@ const createEmptyItem = /* @__PURE__ */ __name((itemKey, t) => ({
286
293
  label: /* @__PURE__ */ import_react.default.createElement("div", { style: { padding: "16px", textAlign: "center" } }, /* @__PURE__ */ import_react.default.createElement(import_antd.Empty, { image: import_antd.Empty.PRESENTED_IMAGE_SIMPLE, description: t("No data"), style: { margin: 0 } })),
287
294
  disabled: true
288
295
  }), "createEmptyItem");
296
+ const KEEP_OPEN_LABEL_STYLE = {
297
+ display: "block",
298
+ width: "100%"
299
+ };
289
300
  const DROPDOWN_PERSIST_TTL_MS = 350;
290
301
  const dropdownPersistRegistry = /* @__PURE__ */ new Map();
291
302
  const LazyDropdown = /* @__PURE__ */ __name(({ menu, ...props }) => {
@@ -307,6 +318,19 @@ const LazyDropdown = /* @__PURE__ */ __name(({ menu, ...props }) => {
307
318
  const { searchValues, isSearching, updateSearchValue } = useMenuSearch();
308
319
  const { requestKeepOpen, shouldPreventClose } = useKeepDropdownOpen();
309
320
  useSubmenuStyles(menuVisible, dropdownMaxHeight);
321
+ const handleMenuOpenChange = (0, import_react.useCallback)(
322
+ (nextOpenKeys) => {
323
+ var _a, _b;
324
+ if (!nextOpenKeys.length && shouldPreventClose()) {
325
+ (_a = dropdownMenuProps.onOpenChange) == null ? void 0 : _a.call(dropdownMenuProps, Array.from(openKeys));
326
+ return;
327
+ }
328
+ const normalized = normalizeOpenKeys(nextOpenKeys);
329
+ setOpenKeys(new Set(normalized));
330
+ (_b = dropdownMenuProps.onOpenChange) == null ? void 0 : _b.call(dropdownMenuProps, normalized);
331
+ },
332
+ [dropdownMenuProps, openKeys, shouldPreventClose]
333
+ );
310
334
  (0, import_react.useEffect)(() => {
311
335
  if (!persistKey) return;
312
336
  const until = dropdownPersistRegistry.get(persistKey) || 0;
@@ -326,6 +350,11 @@ const LazyDropdown = /* @__PURE__ */ __name(({ menu, ...props }) => {
326
350
  }
327
351
  };
328
352
  }, [persistKey, menuVisible]);
353
+ (0, import_react.useEffect)(() => {
354
+ if (!menuVisible) {
355
+ setOpenKeys(/* @__PURE__ */ new Set());
356
+ }
357
+ }, [menuVisible]);
329
358
  (0, import_react.useEffect)(() => {
330
359
  const loadRootItems = /* @__PURE__ */ __name(async () => {
331
360
  let resolvedItems;
@@ -419,51 +448,66 @@ const LazyDropdown = /* @__PURE__ */ __name(({ menu, ...props }) => {
419
448
  if (item.type === "divider") {
420
449
  return { type: "divider", key: keyPath };
421
450
  }
451
+ const label = typeof item.label === "string" ? t(item.label) : item.label;
422
452
  if (item.searchable && children) {
423
453
  return {
424
- key: item.key,
425
- label: typeof item.label === "string" ? t(item.label) : item.label,
454
+ key: keyPath,
455
+ label,
426
456
  onClick: /* @__PURE__ */ __name((info) => {
427
457
  }, "onClick"),
428
- onMouseEnter: /* @__PURE__ */ __name(() => {
429
- setOpenKeys((prev) => {
430
- if (prev.has(keyPath)) return prev;
431
- const next = new Set(prev);
432
- next.add(keyPath);
433
- return next;
434
- });
435
- }, "onMouseEnter"),
436
458
  children: buildSearchChildren(children, item, keyPath, path, menuVisible, resolveItems)
437
459
  };
438
460
  }
461
+ const itemShouldKeepOpen = !children && (item.keepDropdownOpen ?? keepDropdownOpen ?? false);
462
+ const handleLeafClick = /* @__PURE__ */ __name((info) => {
463
+ var _a;
464
+ if (children) {
465
+ return;
466
+ }
467
+ if (itemShouldKeepOpen) {
468
+ requestKeepOpen();
469
+ }
470
+ const extendedInfo = {
471
+ ...info,
472
+ key: (info == null ? void 0 : info.key) ?? keyPath,
473
+ keyPath: (info == null ? void 0 : info.keyPath) ?? [keyPath],
474
+ item: (info == null ? void 0 : info.item) || item,
475
+ originalItem: item,
476
+ keepDropdownOpen: itemShouldKeepOpen
477
+ };
478
+ (_a = menu.onClick) == null ? void 0 : _a.call(menu, extendedInfo);
479
+ }, "handleLeafClick");
439
480
  return {
440
481
  key: keyPath,
441
- label: typeof item.label === "string" ? t(item.label) : item.label,
482
+ label: itemShouldKeepOpen ? /* @__PURE__ */ import_react.default.createElement(
483
+ "div",
484
+ {
485
+ style: KEEP_OPEN_LABEL_STYLE,
486
+ onMouseDown: (event) => {
487
+ event.stopPropagation();
488
+ requestKeepOpen();
489
+ },
490
+ onClick: (event) => {
491
+ event.stopPropagation();
492
+ handleLeafClick({
493
+ key: keyPath,
494
+ keyPath: [keyPath],
495
+ item,
496
+ domEvent: event
497
+ });
498
+ }
499
+ },
500
+ label
501
+ ) : label,
442
502
  onClick: /* @__PURE__ */ __name((info) => {
443
- var _a;
444
- if (children) {
503
+ if (!itemShouldKeepOpen) handleLeafClick(info);
504
+ }, "onClick"),
505
+ onMouseDown: /* @__PURE__ */ __name(() => {
506
+ if (!itemShouldKeepOpen) {
445
507
  return;
446
508
  }
447
- const itemShouldKeepOpen = item.keepDropdownOpen ?? keepDropdownOpen ?? false;
448
- if (itemShouldKeepOpen) {
449
- requestKeepOpen();
450
- }
451
- const extendedInfo = {
452
- ...info,
453
- item: info.item || item,
454
- originalItem: item,
455
- keepDropdownOpen: itemShouldKeepOpen
456
- };
457
- (_a = menu.onClick) == null ? void 0 : _a.call(menu, extendedInfo);
458
- }, "onClick"),
459
- onMouseEnter: /* @__PURE__ */ __name(() => {
460
- setOpenKeys((prev) => {
461
- if (prev.has(keyPath)) return prev;
462
- const next = new Set(prev);
463
- next.add(keyPath);
464
- return next;
465
- });
466
- }, "onMouseEnter"),
509
+ requestKeepOpen();
510
+ }, "onMouseDown"),
467
511
  children: children && children.length > 0 ? resolveItems(children, [...path, item.key]) : children && children.length === 0 ? [createEmptyItem(keyPath, t)] : void 0
468
512
  };
469
513
  });
@@ -498,9 +542,11 @@ const LazyDropdown = /* @__PURE__ */ __name(({ menu, ...props }) => {
498
542
  placement: "bottomLeft",
499
543
  menu: {
500
544
  ...dropdownMenuProps,
545
+ openKeys: Array.from(openKeys),
501
546
  items,
502
547
  onClick: /* @__PURE__ */ __name(() => {
503
548
  }, "onClick"),
549
+ onOpenChange: handleMenuOpenChange,
504
550
  style: {
505
551
  maxHeight: dropdownMaxHeight,
506
552
  overflowY: "auto",
@@ -153,7 +153,7 @@ const _FlowExecutor = class _FlowExecutor {
153
153
  const stepDefaultParams = await (0, import_utils.resolveDefaultParams)(step.defaultParams, runtimeCtx);
154
154
  combinedParams = { ...stepDefaultParams };
155
155
  } else {
156
- flowContext.logger.error(
156
+ flowContext.logger.warn(
157
157
  `BaseModel.applyFlow: Step '${stepKey}' in flow '${flowKey}' has neither 'use' nor 'handler'. Skipping.`
158
158
  );
159
159
  continue;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { FlowDefinition } from '../FlowDefinition';
10
+ import { FlowDefinitionOptions } from '../types';
11
+ import { BaseFlowRegistry, IFlowRepository } from './BaseFlowRegistry';
12
+ export type FlowRegistryData = Record<string, Omit<FlowDefinitionOptions, 'key'> & {
13
+ key?: string;
14
+ }>;
15
+ export declare class DetachedFlowRegistry extends BaseFlowRegistry {
16
+ constructor(flows?: FlowRegistryData);
17
+ saveFlow(_flow: FlowDefinition): void;
18
+ destroyFlow(flowKey: string): void;
19
+ }
20
+ export declare function serializeFlowRegistry(registry: Pick<IFlowRepository, 'getFlows'>): FlowRegistryData;
21
+ export declare function replaceFlowRegistry(registry: Pick<IFlowRepository, 'getFlows' | 'removeFlow' | 'addFlows'>, flows: FlowRegistryData): void;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
17
+ var __export = (target, all) => {
18
+ for (var name in all)
19
+ __defProp(target, name, { get: all[name], enumerable: true });
20
+ };
21
+ var __copyProps = (to, from, except, desc) => {
22
+ if (from && typeof from === "object" || typeof from === "function") {
23
+ for (let key of __getOwnPropNames(from))
24
+ if (!__hasOwnProp.call(to, key) && key !== except)
25
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
26
+ }
27
+ return to;
28
+ };
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
30
+ // If the importer is in node compatibility mode or this is not an ESM
31
+ // file that has been converted to a CommonJS file using a Babel-
32
+ // compatible transform (i.e. "__esModule" has not been set), then set
33
+ // "default" to the CommonJS "module.exports" for node compatibility.
34
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
35
+ mod
36
+ ));
37
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
+ var DetachedFlowRegistry_exports = {};
39
+ __export(DetachedFlowRegistry_exports, {
40
+ DetachedFlowRegistry: () => DetachedFlowRegistry,
41
+ replaceFlowRegistry: () => replaceFlowRegistry,
42
+ serializeFlowRegistry: () => serializeFlowRegistry
43
+ });
44
+ module.exports = __toCommonJS(DetachedFlowRegistry_exports);
45
+ var import_lodash = __toESM(require("lodash"));
46
+ var import_BaseFlowRegistry = require("./BaseFlowRegistry");
47
+ const _DetachedFlowRegistry = class _DetachedFlowRegistry extends import_BaseFlowRegistry.BaseFlowRegistry {
48
+ constructor(flows = {}) {
49
+ super();
50
+ this.addFlows(import_lodash.default.cloneDeep(flows));
51
+ }
52
+ saveFlow(_flow) {
53
+ }
54
+ destroyFlow(flowKey) {
55
+ this.removeFlow(flowKey);
56
+ }
57
+ };
58
+ __name(_DetachedFlowRegistry, "DetachedFlowRegistry");
59
+ let DetachedFlowRegistry = _DetachedFlowRegistry;
60
+ function serializeFlowRegistry(registry) {
61
+ const flows = {};
62
+ for (const [key, flow] of registry.getFlows()) {
63
+ flows[key] = import_lodash.default.cloneDeep(flow.toData());
64
+ }
65
+ return flows;
66
+ }
67
+ __name(serializeFlowRegistry, "serializeFlowRegistry");
68
+ function replaceFlowRegistry(registry, flows) {
69
+ for (const key of Array.from(registry.getFlows().keys())) {
70
+ registry.removeFlow(key);
71
+ }
72
+ registry.addFlows(import_lodash.default.cloneDeep(flows));
73
+ }
74
+ __name(replaceFlowRegistry, "replaceFlowRegistry");
75
+ // Annotate the CommonJS export names for ESM import in node:
76
+ 0 && (module.exports = {
77
+ DetachedFlowRegistry,
78
+ replaceFlowRegistry,
79
+ serializeFlowRegistry
80
+ });
@@ -9,3 +9,4 @@
9
9
  export * from './BaseFlowRegistry';
10
10
  export * from './InstanceFlowRegistry';
11
11
  export * from './GlobalFlowRegistry';
12
+ export * from './DetachedFlowRegistry';
@@ -26,9 +26,11 @@ module.exports = __toCommonJS(flow_registry_exports);
26
26
  __reExport(flow_registry_exports, require("./BaseFlowRegistry"), module.exports);
27
27
  __reExport(flow_registry_exports, require("./InstanceFlowRegistry"), module.exports);
28
28
  __reExport(flow_registry_exports, require("./GlobalFlowRegistry"), module.exports);
29
+ __reExport(flow_registry_exports, require("./DetachedFlowRegistry"), module.exports);
29
30
  // Annotate the CommonJS export names for ESM import in node:
30
31
  0 && (module.exports = {
31
32
  ...require("./BaseFlowRegistry"),
32
33
  ...require("./InstanceFlowRegistry"),
33
- ...require("./GlobalFlowRegistry")
34
+ ...require("./GlobalFlowRegistry"),
35
+ ...require("./DetachedFlowRegistry")
34
36
  });
package/lib/index.d.ts CHANGED
@@ -34,5 +34,7 @@ export { getSnippetBody, listSnippetsForContext, registerRunJSSnippet } from './
34
34
  export * from './views';
35
35
  export { DATA_SOURCE_DIRTY_EVENT, ENGINE_SCOPE_KEY, getEmitterViewActivatedVersion, VIEW_ACTIVATED_EVENT, VIEW_ACTIVATED_VERSION, VIEW_ENGINE_SCOPE, } from './views/viewEvents';
36
36
  export * from './FlowDefinition';
37
+ export { DetachedFlowRegistry, replaceFlowRegistry, serializeFlowRegistry } from './flow-registry';
38
+ export type { FlowRegistryData } from './flow-registry';
37
39
  export { createViewScopedEngine } from './ViewScopedFlowEngine';
38
40
  export { createBlockScopedEngine } from './BlockScopedFlowEngine';
package/lib/index.js CHANGED
@@ -28,6 +28,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
28
28
  var src_exports = {};
29
29
  __export(src_exports, {
30
30
  DATA_SOURCE_DIRTY_EVENT: () => import_viewEvents.DATA_SOURCE_DIRTY_EVENT,
31
+ DetachedFlowRegistry: () => import_flow_registry.DetachedFlowRegistry,
31
32
  ENGINE_SCOPE_KEY: () => import_viewEvents.ENGINE_SCOPE_KEY,
32
33
  RunJSContextRegistry: () => import_registry.RunJSContextRegistry,
33
34
  VIEW_ACTIVATED_EVENT: () => import_viewEvents.VIEW_ACTIVATED_EVENT,
@@ -47,6 +48,8 @@ __export(src_exports, {
47
48
  registerRunJSContextContribution: () => import_contributions.registerRunJSContextContribution,
48
49
  registerRunJSLib: () => import_runjsLibs.registerRunJSLib,
49
50
  registerRunJSSnippet: () => import_snippets.registerRunJSSnippet,
51
+ replaceFlowRegistry: () => import_flow_registry.replaceFlowRegistry,
52
+ serializeFlowRegistry: () => import_flow_registry.serializeFlowRegistry,
50
53
  setupRunJSContexts: () => import_setup.setupRunJSContexts
51
54
  });
52
55
  module.exports = __toCommonJS(src_exports);
@@ -75,11 +78,13 @@ var import_snippets = require("./runjs-context/snippets");
75
78
  __reExport(src_exports, require("./views"), module.exports);
76
79
  var import_viewEvents = require("./views/viewEvents");
77
80
  __reExport(src_exports, require("./FlowDefinition"), module.exports);
81
+ var import_flow_registry = require("./flow-registry");
78
82
  var import_ViewScopedFlowEngine = require("./ViewScopedFlowEngine");
79
83
  var import_BlockScopedFlowEngine = require("./BlockScopedFlowEngine");
80
84
  // Annotate the CommonJS export names for ESM import in node:
81
85
  0 && (module.exports = {
82
86
  DATA_SOURCE_DIRTY_EVENT,
87
+ DetachedFlowRegistry,
83
88
  ENGINE_SCOPE_KEY,
84
89
  RunJSContextRegistry,
85
90
  VIEW_ACTIVATED_EVENT,
@@ -99,6 +104,8 @@ var import_BlockScopedFlowEngine = require("./BlockScopedFlowEngine");
99
104
  registerRunJSContextContribution,
100
105
  registerRunJSLib,
101
106
  registerRunJSSnippet,
107
+ replaceFlowRegistry,
108
+ serializeFlowRegistry,
102
109
  setupRunJSContexts,
103
110
  ...require("./types"),
104
111
  ...require("./utils"),
@@ -47,11 +47,21 @@ const _FlowViewer = class _FlowViewer {
47
47
  if (this.types[type]) {
48
48
  zIndex += 1;
49
49
  const onClose = others.onClose;
50
+ let zIndexReleased = false;
51
+ const releaseZIndex = /* @__PURE__ */ __name(() => {
52
+ if (!zIndexReleased) {
53
+ zIndexReleased = true;
54
+ zIndex -= 1;
55
+ }
56
+ }, "releaseZIndex");
50
57
  const _zIndex = others.zIndex;
51
58
  others.onClose = (...args) => {
52
59
  onClose == null ? void 0 : onClose(...args);
53
- zIndex -= 1;
60
+ releaseZIndex();
54
61
  };
62
+ if (type === "embed") {
63
+ others.onOpenCancelled = releaseZIndex;
64
+ }
55
65
  if (type !== "embed") {
56
66
  others.zIndex = _zIndex ?? this.getNextZIndex();
57
67
  }
@@ -55,8 +55,9 @@ const PageComponent = (0, import_react.forwardRef)((props, ref) => {
55
55
  hidden,
56
56
  title: _title,
57
57
  styles = {},
58
- zIndex = 4
58
+ zIndex = 4,
59
59
  // 这个默认值是为了防止表格的阴影显示到子页面上面
60
+ onClose
60
61
  } = mergedProps;
61
62
  const closedRef = (0, import_react.useRef)(false);
62
63
  const flowEngine = (0, import_provider.useFlowEngine)();
@@ -114,11 +115,12 @@ const PageComponent = (0, import_react.forwardRef)((props, ref) => {
114
115
  type: "text",
115
116
  size: "small",
116
117
  icon: /* @__PURE__ */ import_react.default.createElement(import_icons.CloseOutlined, null),
117
- onClick: () => {
118
- var _a;
118
+ onClick: async () => {
119
119
  if (!closedRef.current) {
120
- closedRef.current = true;
121
- (_a = props.onClose) == null ? void 0 : _a.call(props);
120
+ const closed = await (onClose == null ? void 0 : onClose());
121
+ if (closed !== false) {
122
+ closedRef.current = true;
123
+ }
122
124
  }
123
125
  },
124
126
  style: {
@@ -138,7 +140,7 @@ const PageComponent = (0, import_react.forwardRef)((props, ref) => {
138
140
  )),
139
141
  extra && /* @__PURE__ */ import_react.default.createElement("div", null, extra)
140
142
  );
141
- }, [header, _title, flowEngine.context.themeToken, styles.header, props.onClose]);
143
+ }, [header, _title, flowEngine.context.themeToken, styles.header, onClose]);
142
144
  const FooterComponent = (0, import_react.useMemo)(() => {
143
145
  if (!footer) return null;
144
146
  const token = flowEngine.context.themeToken;
@@ -12,27 +12,20 @@ export declare const GLOBAL_EMBED_CONTAINER_ID = "nocobase-embed-container";
12
12
  /** Dataset key used to signal embed replacement in progress (skip style reset on close) */
13
13
  export declare const EMBED_REPLACING_DATA_KEY = "nocobaseEmbedReplacing";
14
14
  export declare function usePage(): (React.JSX.Element | {
15
- open: (config: any, flowContext: any) => Promise<unknown> & {
15
+ open: (config: any, flowContext: any) => Promise<any> & {
16
16
  type: "embed";
17
17
  inputArgs: any;
18
18
  preventClose: boolean;
19
+ Header: any;
20
+ Footer: any;
19
21
  beforeClose: any;
22
+ close: (result?: any, force?: boolean) => Promise<any>;
20
23
  destroy: (result?: any) => void;
21
24
  update: (newConfig: any) => void;
22
- close: (result?: any, force?: boolean) => Promise<boolean>;
23
- Header: React.FC<{
24
- title?: React.ReactNode;
25
- extra?: React.ReactNode;
26
- }>;
27
- Footer: React.FC<{
28
- children?: React.ReactNode;
29
- }>;
30
25
  setFooter: (footer: React.ReactNode) => void;
31
26
  setHeader: (header: {
32
27
  title?: React.ReactNode;
33
28
  extra?: React.ReactNode;
34
29
  }) => void;
35
- navigation: any;
36
- readonly record: unknown;
37
30
  };
38
31
  })[];