@nocobase/client-v2 2.2.0-beta.5 → 2.2.0-beta.6

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.
Files changed (109) hide show
  1. package/es/RouteRepository.d.ts +21 -6
  2. package/es/components/form/JsonTextArea.d.ts +2 -1
  3. package/es/components/form/VariableJsonTextArea.d.ts +19 -0
  4. package/es/components/form/index.d.ts +1 -0
  5. package/es/components/index.d.ts +1 -0
  6. package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +2 -0
  7. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.d.ts +2 -1
  8. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +2 -0
  9. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +3 -2
  10. package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +4 -0
  11. package/es/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.d.ts +6 -0
  12. package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
  13. package/es/flow/models/base/GridModel.d.ts +1 -1
  14. package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +5 -0
  15. package/es/flow/models/blocks/form/FormBlockModel.d.ts +4 -0
  16. package/es/flow/models/blocks/form/value-runtime/rules.d.ts +21 -0
  17. package/es/flow/models/blocks/form/value-runtime/runtime.d.ts +21 -0
  18. package/es/flow/models/blocks/form/value-runtime/types.d.ts +2 -2
  19. package/es/flow-compat/FieldValidation.d.ts +2 -1
  20. package/es/index.d.ts +2 -1
  21. package/es/index.mjs +143 -117
  22. package/lib/index.js +148 -122
  23. package/package.json +7 -7
  24. package/src/RouteRepository.ts +126 -24
  25. package/src/__tests__/RouteRepository.test.ts +216 -0
  26. package/src/__tests__/exports.test.ts +16 -0
  27. package/src/__tests__/settings-center.test.tsx +33 -0
  28. package/src/components/form/JsonTextArea.tsx +21 -11
  29. package/src/components/form/VariableJsonTextArea.tsx +175 -0
  30. package/src/components/form/__tests__/JsonTextArea.test.tsx +43 -0
  31. package/src/components/form/__tests__/VariableJsonTextArea.test.tsx +86 -0
  32. package/src/components/form/index.tsx +1 -0
  33. package/src/components/index.ts +1 -0
  34. package/src/flow/__tests__/FlowRoute.test.tsx +443 -5
  35. package/src/flow/actions/__tests__/fieldLinkageRules.scopeDepth.test.ts +150 -1
  36. package/src/flow/actions/__tests__/linkageAssignField.legacy.test.ts +135 -0
  37. package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +19 -5
  38. package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +92 -0
  39. package/src/flow/actions/customVariable.tsx +1 -2
  40. package/src/flow/actions/linkageRules.tsx +122 -34
  41. package/src/flow/actions/runjs.tsx +2 -14
  42. package/src/flow/actions/validation.tsx +62 -30
  43. package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +33 -10
  44. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +310 -0
  45. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +44 -8
  46. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.ts +5 -3
  47. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +61 -9
  48. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +71 -8
  49. package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +1 -1
  50. package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +21 -8
  51. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +188 -0
  52. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +99 -0
  53. package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +166 -2
  54. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +20 -0
  55. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +33 -5
  56. package/src/flow/components/DefaultValue.tsx +1 -2
  57. package/src/flow/components/FieldAssignRulesEditor.tsx +62 -12
  58. package/src/flow/components/FlowRoute.tsx +56 -11
  59. package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +81 -4
  60. package/src/flow/components/code-editor/__tests__/useCodeRunner.test.tsx +2 -17
  61. package/src/flow/components/code-editor/hooks/useCodeRunner.ts +2 -14
  62. package/src/flow/components/code-editor/runjsDiagnostics.ts +8 -45
  63. package/src/flow/models/actions/JSActionModel.tsx +2 -7
  64. package/src/flow/models/actions/JSCollectionActionModel.tsx +2 -7
  65. package/src/flow/models/actions/JSItemActionModel.tsx +2 -7
  66. package/src/flow/models/actions/JSRecordActionModel.tsx +2 -7
  67. package/src/flow/models/base/ActionModel.tsx +12 -1
  68. package/src/flow/models/base/GridModel.tsx +38 -7
  69. package/src/flow/models/base/PageModel/PageModel.tsx +4 -1
  70. package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +28 -4
  71. package/src/flow/models/base/__tests__/ActionModel.test.ts +83 -0
  72. package/src/flow/models/base/__tests__/GridModel.dragSnapshotContainer.test.ts +239 -1
  73. package/src/flow/models/base/__tests__/transformRowsToSingleColumn.test.ts +48 -0
  74. package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +31 -3
  75. package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +2 -7
  76. package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +77 -0
  77. package/src/flow/models/blocks/form/EditFormModel.tsx +1 -0
  78. package/src/flow/models/blocks/form/FormBlockModel.tsx +7 -0
  79. package/src/flow/models/blocks/form/JSFormActionModel.tsx +2 -7
  80. package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +17 -0
  81. package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +880 -102
  82. package/src/flow/models/blocks/form/value-runtime/rules.ts +445 -13
  83. package/src/flow/models/blocks/form/value-runtime/runtime.ts +257 -13
  84. package/src/flow/models/blocks/form/value-runtime/types.ts +2 -2
  85. package/src/flow/models/blocks/js-block/JSBlock.tsx +2 -7
  86. package/src/flow/models/blocks/table/JSColumnModel.tsx +1 -9
  87. package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +1 -1
  88. package/src/flow/models/blocks/table/TableBlockModel.tsx +13 -3
  89. package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +54 -0
  90. package/src/flow/models/blocks/table/__tests__/TableBlockModel.mobileSettingsButtons.test.tsx +78 -0
  91. package/src/flow/models/fields/AssociationFieldModel/AssociationFieldModel.tsx +1 -1
  92. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +29 -6
  93. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +13 -1
  94. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableFieldModel.reset.test.ts +180 -0
  95. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -4
  96. package/src/flow/models/fields/AssociationFieldModel/__tests__/AssociationFieldModel.updateAssociation.test.ts +72 -0
  97. package/src/flow/models/fields/InputFieldModel.tsx +14 -22
  98. package/src/flow/models/fields/JSEditableFieldModel.tsx +2 -11
  99. package/src/flow/models/fields/JSFieldModel.tsx +2 -7
  100. package/src/flow/models/fields/JSItemModel.tsx +2 -14
  101. package/src/flow/models/fields/__tests__/InputFieldModel.test.tsx +17 -0
  102. package/src/flow/models/topbar/TopbarActionModel.tsx +93 -10
  103. package/src/flow-compat/FieldValidation.tsx +122 -60
  104. package/src/flow-compat/Popover.tsx +43 -4
  105. package/src/flow-compat/__tests__/Popover.test.tsx +34 -0
  106. package/src/index.ts +8 -1
  107. package/src/layout-manager/__tests__/LayoutRoute.test.tsx +41 -1
  108. package/src/settings-center/AdminSettingsLayout.tsx +3 -0
  109. package/src/settings-center/plugin-manager/index.tsx +3 -0
@@ -8,15 +8,54 @@
8
8
  */
9
9
 
10
10
  import { Popover as AntdPopover, type PopoverProps } from 'antd';
11
- import React, { useCallback, useRef } from 'react';
11
+ import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
12
12
  import { getZIndex, useZIndexContext, zIndexContext } from './zIndexContext';
13
13
 
14
14
  export const ICON_POPUP_Z_INDEX = 2000;
15
15
 
16
+ function parseZIndex(value?: string | null) {
17
+ if (!value || value === 'auto') {
18
+ return;
19
+ }
20
+
21
+ const zIndex = Number(value);
22
+ return Number.isFinite(zIndex) ? zIndex : undefined;
23
+ }
24
+
25
+ function getElementZIndex(element: HTMLElement) {
26
+ return parseZIndex(window.getComputedStyle(element).zIndex) ?? parseZIndex(element.style.zIndex);
27
+ }
28
+
29
+ function getContainingPopupZIndex(element: HTMLElement | null) {
30
+ if (!element || typeof window === 'undefined') {
31
+ return 0;
32
+ }
33
+
34
+ let current: HTMLElement | null = element;
35
+ let maxZIndex = 0;
36
+
37
+ while (current && current !== document.documentElement) {
38
+ const zIndex = getElementZIndex(current);
39
+ if (typeof zIndex === 'number' && zIndex > maxZIndex) {
40
+ maxZIndex = zIndex;
41
+ }
42
+ current = current.parentElement;
43
+ }
44
+
45
+ return maxZIndex;
46
+ }
47
+
16
48
  export const StablePopover = (props: PopoverProps) => {
17
49
  const parentZIndex = useZIndexContext();
18
- const zIndex = getZIndex('drawer', parentZIndex, 1);
19
- const target = useRef(null);
50
+ const [containingPopupZIndex, setContainingPopupZIndex] = useState(parentZIndex);
51
+ const target = useRef<EventTarget | null>(null);
52
+ const triggerRef = useRef<HTMLDivElement | null>(null);
53
+ const zIndex = getZIndex('drawer', Math.max(parentZIndex, containingPopupZIndex), 1);
54
+
55
+ useLayoutEffect(() => {
56
+ const nextZIndex = Math.max(parentZIndex, getContainingPopupZIndex(triggerRef.current));
57
+ setContainingPopupZIndex((previousZIndex) => (previousZIndex === nextZIndex ? previousZIndex : nextZIndex));
58
+ }, [parentZIndex]);
20
59
 
21
60
  const avoidClose = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
22
61
  target.current = e.target;
@@ -36,7 +75,7 @@ export const StablePopover = (props: PopoverProps) => {
36
75
  );
37
76
 
38
77
  return (
39
- <div className="popover-with-stop-propagation" onClick={avoidClose}>
78
+ <div ref={triggerRef} className="popover-with-stop-propagation" onClick={avoidClose}>
40
79
  <zIndexContext.Provider value={zIndex}>
41
80
  <AntdPopover {...props} zIndex={zIndex} onOpenChange={onOpenChange} />
42
81
  </zIndexContext.Provider>
@@ -0,0 +1,34 @@
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
+ import { render, screen, waitFor } from '@testing-library/react';
11
+ import React from 'react';
12
+ import { describe, expect, it } from 'vitest';
13
+ import { StablePopover } from '../Popover';
14
+
15
+ describe('StablePopover', () => {
16
+ it('renders above the containing popup layer', async () => {
17
+ render(
18
+ <div style={{ position: 'relative', zIndex: 5000 }}>
19
+ <StablePopover open content={<div>Icon picker popup</div>}>
20
+ <button type="button">Select icon</button>
21
+ </StablePopover>
22
+ </div>,
23
+ );
24
+
25
+ expect(screen.getByText('Icon picker popup')).toBeInTheDocument();
26
+
27
+ await waitFor(() => {
28
+ const popover = document.querySelector<HTMLElement>('.ant-popover');
29
+
30
+ expect(popover).toBeInTheDocument();
31
+ expect(Number(popover?.style.zIndex)).toBeGreaterThan(5000);
32
+ });
33
+ });
34
+ });
package/src/index.ts CHANGED
@@ -39,5 +39,12 @@ export * from './collection-manager/interfaces';
39
39
  export * from './collection-manager/template-fields';
40
40
  export * from './data-source';
41
41
  export * from './flow';
42
- export { DEFAULT_DATA_SOURCE_KEY, isTitleField, isTitleFieldInterface } from './flow-compat';
42
+ export {
43
+ DEFAULT_DATA_SOURCE_KEY,
44
+ IconPicker,
45
+ isTitleField,
46
+ isTitleFieldInterface,
47
+ NocoBaseDesktopRouteType,
48
+ } from './flow-compat';
49
+ export type { NocoBaseDesktopRoute } from './flow-compat';
43
50
  export { default as AntdAppProvider } from './theme/AntdAppProvider';
@@ -11,7 +11,7 @@ import { FlowEngine, FlowEngineProvider, observer } from '@nocobase/flow-engine'
11
11
  import { render, screen, waitFor } from '@testing-library/react';
12
12
  import React from 'react';
13
13
  import { createMemoryRouter, Outlet, RouterProvider, useOutlet } from 'react-router-dom';
14
- import { describe, expect, it } from 'vitest';
14
+ import { describe, expect, it, vi } from 'vitest';
15
15
  import { BaseLayoutModel } from '../../flow/admin-shell/BaseLayoutModel';
16
16
  import { LayoutContentRoute } from '../LayoutContentRoute';
17
17
  import { LayoutRoute } from '../LayoutRoute';
@@ -106,6 +106,46 @@ describe('LayoutRoute', () => {
106
106
  });
107
107
  });
108
108
 
109
+ it('does not activate desktop route loading for generic layouts', async () => {
110
+ const activateLayout = vi.fn(() => vi.fn());
111
+ const engine = new FlowEngine();
112
+ engine.registerModels({ TestLayoutModel });
113
+ engine.context.defineProperty('routeRepository', {
114
+ value: {
115
+ activateLayout,
116
+ },
117
+ });
118
+ engine.context.defineProperty('app', {
119
+ value: {
120
+ layoutManager: {
121
+ getLayout: () => layout,
122
+ },
123
+ },
124
+ });
125
+
126
+ const router = createMemoryRouter(
127
+ [
128
+ {
129
+ id: layout.routeName,
130
+ path: layout.routePath,
131
+ element: <LayoutRoute layoutRouteName="test" />,
132
+ },
133
+ ],
134
+ {
135
+ initialEntries: ['/test'],
136
+ },
137
+ );
138
+
139
+ render(
140
+ <FlowEngineProvider engine={engine}>
141
+ <RouterProvider router={router} />
142
+ </FlowEngineProvider>,
143
+ );
144
+
145
+ expect(await screen.findByTestId('layout-route')).toHaveTextContent('test');
146
+ expect(activateLayout).not.toHaveBeenCalled();
147
+ });
148
+
109
149
  it('syncs nested page route before the layout renders its outlet', async () => {
110
150
  const nestedLayout: LayoutDefinition = {
111
151
  ...layout,
@@ -209,6 +209,9 @@ export const InternalAdminSettingsLayout = () => {
209
209
  style={{
210
210
  background: token.colorBgContainer,
211
211
  borderInlineEnd: `${token.lineWidth}px solid ${token.colorBorderSecondary}`,
212
+ minHeight: 0,
213
+ overflowY: 'auto',
214
+ overflowX: 'hidden',
212
215
  }}
213
216
  >
214
217
  <Menu
@@ -86,6 +86,9 @@ export const PluginManagerPage: React.FC = () => {
86
86
  async () => {
87
87
  const response = await app.apiClient.request({
88
88
  url: 'pm:list',
89
+ params: {
90
+ v2: true,
91
+ },
89
92
  skipNotify: true,
90
93
  });
91
94
  return Array.isArray(response?.data?.data) ? response.data.data : [];