@nocobase/client-v2 2.2.0-alpha.6 → 2.2.0-alpha.8

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 (49) hide show
  1. package/es/BaseApplication.d.ts +1 -0
  2. package/es/collection-field-interface/CollectionFieldInterface.d.ts +1 -0
  3. package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +1 -0
  4. package/es/flow/components/FieldAssignExactDatePicker.d.ts +1 -0
  5. package/es/flow/components/FieldAssignValueInput.d.ts +7 -0
  6. package/es/flow/components/RunJSValueEditor.d.ts +1 -0
  7. package/es/flow/components/filter/FilterGroup.d.ts +1 -0
  8. package/es/flow/components/filter/VariableFilterItem.d.ts +1 -0
  9. package/es/flow/models/blocks/form/QuickEditFormModel.d.ts +17 -2
  10. package/es/index.mjs +89 -89
  11. package/lib/index.js +97 -97
  12. package/package.json +8 -7
  13. package/src/BaseApplication.tsx +11 -6
  14. package/src/__tests__/app.test.tsx +55 -0
  15. package/src/collection-field-interface/CollectionFieldInterface.ts +1 -0
  16. package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +1 -0
  17. package/src/components/form/ScanInput/__tests__/useCodeScanner.test.tsx +145 -2
  18. package/src/components/form/ScanInput/useCodeScanner.ts +154 -2
  19. package/src/components/form/TypedVariableInput.tsx +12 -8
  20. package/src/components/form/__tests__/TypedVariableInput.test.tsx +44 -3
  21. package/src/flow/FlowPage.tsx +9 -1
  22. package/src/flow/__tests__/FlowPage.test.tsx +50 -3
  23. package/src/flow/__tests__/FlowRoute.test.tsx +2 -2
  24. package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +7 -3
  25. package/src/flow/actions/linkageRulesRefresh.tsx +2 -6
  26. package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +0 -1
  27. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +253 -6
  28. package/src/flow/components/FieldAssignExactDatePicker.tsx +25 -11
  29. package/src/flow/components/FieldAssignValueInput.tsx +81 -15
  30. package/src/flow/components/FlowRoute.tsx +7 -3
  31. package/src/flow/components/RunJSValueEditor.tsx +9 -1
  32. package/src/flow/components/__tests__/FieldAssignValueInput.context.test.tsx +216 -0
  33. package/src/flow/components/filter/FilterGroup.tsx +33 -5
  34. package/src/flow/components/filter/VariableFilterItem.tsx +139 -6
  35. package/src/flow/components/filter/__tests__/FilterGroup.test.tsx +45 -0
  36. package/src/flow/components/filter/__tests__/VariableFilterItem.leftMetaTree.test.tsx +9 -0
  37. package/src/flow/components/filter/__tests__/VariableFilterItem.test.tsx +21 -0
  38. package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +1 -0
  39. package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +27 -12
  40. package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +36 -0
  41. package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +34 -0
  42. package/src/flow/models/blocks/form/QuickEditFormModel.tsx +189 -36
  43. package/src/flow/models/blocks/form/__tests__/QuickEditFormModel.quickEdit.test.ts +350 -2
  44. package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +2 -1
  45. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +1 -0
  46. package/src/flow/models/fields/VariableFieldFormModel.tsx +3 -3
  47. package/src/flow/models/fields/__tests__/VariableFieldFormModel.test.tsx +51 -0
  48. package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +20 -10
  49. package/src/flow/models/fields/mobile-components/MobileSelect.tsx +24 -12
@@ -0,0 +1,51 @@
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 { FlowEngine, FlowEngineProvider } from '@nocobase/flow-engine';
11
+ import { render, screen, waitFor } from '@testing-library/react';
12
+ import React from 'react';
13
+ import { describe, expect, it } from 'vitest';
14
+ import { InputFieldModel } from '../InputFieldModel';
15
+ import { VariableFieldFormModel } from '../VariableFieldFormModel';
16
+
17
+ describe('VariableFieldFormModel', () => {
18
+ it('uses DOM-safe name and id for temporary controls created from reserved form property names', async () => {
19
+ const engine = new FlowEngine();
20
+ engine.registerModels({ InputFieldModel, VariableFieldFormModel });
21
+ const model = engine.createModel<VariableFieldFormModel>({
22
+ use: 'VariableFieldFormModel',
23
+ subModels: {
24
+ fields: [
25
+ {
26
+ use: 'InputFieldModel',
27
+ stepParams: {
28
+ fieldSettings: {
29
+ init: {
30
+ fieldPath: 'nodeName',
31
+ },
32
+ },
33
+ },
34
+ },
35
+ ],
36
+ },
37
+ });
38
+ const field = model.subModels.fields[0];
39
+
40
+ render(<FlowEngineProvider engine={engine}>{model.render()}</FlowEngineProvider>);
41
+
42
+ const input = await screen.findByRole('textbox');
43
+ await waitFor(() => {
44
+ expect(field.props.name).toEqual(['__nb_variable_field_nodeName']);
45
+ });
46
+ expect(input).toHaveAttribute('name', '__nb_variable_field_nodeName');
47
+ expect(input).toHaveAttribute('id', '__nb_variable_field_nodeName');
48
+ expect(field.props.id).toEqual(['__nb_variable_field_nodeName']);
49
+ expect(field.getStepParams('fieldSettings', 'init')).toEqual({ fieldPath: 'nodeName' });
50
+ });
51
+ });
@@ -23,6 +23,20 @@ import {
23
23
  } from '../AssociationFieldModel/recordSelectShared';
24
24
  import _ from 'lodash';
25
25
 
26
+ const mobileSelectSafeAreaPaddingBottom = 'calc(12px + env(safe-area-inset-bottom, 0px))';
27
+
28
+ const mobileSelectConfirmFooterStyle: CSSProperties = {
29
+ paddingBottom: mobileSelectSafeAreaPaddingBottom,
30
+ };
31
+
32
+ function getMobileSelectListStyle(hasConfirmFooter: boolean): CSSProperties {
33
+ return {
34
+ maxHeight: '60vh',
35
+ overflowY: 'auto',
36
+ paddingBottom: hasConfirmFooter ? undefined : mobileSelectSafeAreaPaddingBottom,
37
+ };
38
+ }
39
+
26
40
  const labelClassName = css`
27
41
  div {
28
42
  white-space: nowrap !important;
@@ -280,13 +294,7 @@ export function MobileLazySelect(props: Readonly<LazySelectProps>) {
280
294
  showCancelButton
281
295
  />
282
296
  </div>
283
- <div
284
- style={{
285
- maxHeight: '60vh',
286
- overflowY: 'auto',
287
- }}
288
- onScroll={handleScroll}
289
- >
297
+ <div style={getMobileSelectListStyle(isMultiple)} onScroll={handleScroll}>
290
298
  <CheckList multiple={isMultiple} value={selectedValueIds} onChange={handleListChange}>
291
299
  {realOptions.map((item) => {
292
300
  const optionValue = item?.[valueKey];
@@ -311,9 +319,11 @@ export function MobileLazySelect(props: Readonly<LazySelectProps>) {
311
319
  )}
312
320
  </div>
313
321
  {isMultiple && (
314
- <Button block color="primary" onClick={handleConfirm} style={{ marginTop: '16px' }}>
315
- {t('Confirm')}
316
- </Button>
322
+ <div style={mobileSelectConfirmFooterStyle}>
323
+ <Button block color="primary" onClick={handleConfirm} style={{ marginTop: '16px' }}>
324
+ {t('Confirm')}
325
+ </Button>
326
+ </div>
317
327
  )}
318
328
  </Popup>
319
329
  </>
@@ -12,8 +12,23 @@ import { Select } from 'antd';
12
12
  import { Button, CheckList, Popup, SearchBar } from 'antd-mobile';
13
13
  import React, { useEffect, useMemo, useState } from 'react';
14
14
 
15
+ const mobileSelectSafeAreaPaddingBottom = 'calc(12px + env(safe-area-inset-bottom, 0px))';
16
+
17
+ const mobileSelectConfirmFooterStyle: React.CSSProperties = {
18
+ paddingBottom: mobileSelectSafeAreaPaddingBottom,
19
+ };
20
+
21
+ function getMobileSelectListStyle(hasConfirmFooter: boolean): React.CSSProperties {
22
+ return {
23
+ maxHeight: '60vh',
24
+ overflowY: 'auto',
25
+ paddingBottom: hasConfirmFooter ? undefined : mobileSelectSafeAreaPaddingBottom,
26
+ };
27
+ }
28
+
15
29
  export function MobileSelect(props) {
16
30
  const { value, displayValue, onChange, onChangeComplete, disabled, options = [], mode } = props;
31
+ const isMultiple = ['multiple', 'tags'].includes(mode);
17
32
  const ctx = useFlowModelContext();
18
33
  const t = ctx.t;
19
34
  const [visible, setVisible] = useState(false);
@@ -64,17 +79,12 @@ export function MobileSelect(props) {
64
79
  <div style={{ margin: '10px' }}>
65
80
  <SearchBar placeholder={t('search')} value={searchText} onChange={(v) => setSearchText(v)} showCancelButton />
66
81
  </div>
67
- <div
68
- style={{
69
- maxHeight: '60vh',
70
- overflowY: 'auto',
71
- }}
72
- >
82
+ <div style={getMobileSelectListStyle(isMultiple)}>
73
83
  <CheckList
74
- multiple={['multiple', 'tags'].includes(mode)}
84
+ multiple={isMultiple}
75
85
  value={Array.isArray(selected) ? selected : [selected]}
76
86
  onChange={(val) => {
77
- if (['multiple', 'tags'].includes(mode)) {
87
+ if (isMultiple) {
78
88
  setSelected(val);
79
89
  } else {
80
90
  setSelected(val[0]);
@@ -91,10 +101,12 @@ export function MobileSelect(props) {
91
101
  ))}
92
102
  </CheckList>
93
103
  </div>
94
- {['multiple', 'tags'].includes(mode) && (
95
- <Button block color="primary" onClick={handleConfirm} style={{ marginTop: '16px' }}>
96
- {t('Confirm')}
97
- </Button>
104
+ {isMultiple && (
105
+ <div style={mobileSelectConfirmFooterStyle}>
106
+ <Button block color="primary" onClick={handleConfirm} style={{ marginTop: '16px' }}>
107
+ {t('Confirm')}
108
+ </Button>
109
+ </div>
98
110
  )}
99
111
  </Popup>
100
112
  </>