@nocobase/client-v2 2.1.0-beta.36 → 2.1.0-beta.38

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 (154) hide show
  1. package/es/Application.d.ts +1 -0
  2. package/es/BaseApplication.d.ts +4 -0
  3. package/es/RouterManager.d.ts +1 -0
  4. package/es/components/KeepAlive.d.ts +22 -0
  5. package/es/components/RouterBridge.d.ts +9 -0
  6. package/es/components/form/DialogFormLayout.d.ts +5 -29
  7. package/es/components/form/filter/CollectionFilter.d.ts +41 -0
  8. package/es/components/form/filter/CollectionFilterItem.d.ts +41 -0
  9. package/es/components/form/filter/DateFilterDynamicComponent.d.ts +57 -0
  10. package/es/components/form/filter/FilterValueInput.d.ts +29 -0
  11. package/es/components/form/filter/index.d.ts +11 -0
  12. package/es/components/form/filter/useFilterActionProps.d.ts +96 -0
  13. package/es/components/form/index.d.ts +1 -0
  14. package/es/data-source/ExtendCollectionsProvider.d.ts +50 -0
  15. package/es/data-source/index.d.ts +9 -0
  16. package/es/flow/FlowPage.d.ts +2 -1
  17. package/es/flow/admin-shell/AdminLayoutRouteCoordinator.d.ts +8 -40
  18. package/es/flow/admin-shell/BaseLayoutModel.d.ts +89 -0
  19. package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +74 -0
  20. package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +12 -0
  21. package/es/flow/admin-shell/admin-layout/AdminLayoutModel.d.ts +7 -92
  22. package/es/flow/admin-shell/admin-layout/index.d.ts +2 -0
  23. package/es/flow/admin-shell/useAdminLayoutRoutePage.d.ts +2 -2
  24. package/es/flow/admin-shell/useLayoutRoutePage.d.ts +23 -0
  25. package/es/flow/components/FlowRoute.d.ts +10 -1
  26. package/es/flow/components/filter/index.d.ts +2 -0
  27. package/es/flow/components/filter/useFilterOptions.d.ts +54 -0
  28. package/es/flow/index.d.ts +4 -0
  29. package/es/flow/models/base/PageModel/PageModel.d.ts +3 -1
  30. package/es/flow/models/blocks/form/FormActionGroupModel.d.ts +1 -0
  31. package/es/flow/models/blocks/table/TableBlockModel.d.ts +10 -0
  32. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.d.ts +1 -1
  33. package/es/flow-compat/passwordUtils.d.ts +1 -1
  34. package/es/index.d.ts +2 -0
  35. package/es/index.mjs +491 -439
  36. package/es/layout-manager/LayoutContentRoute.d.ts +14 -0
  37. package/es/layout-manager/LayoutManager.d.ts +22 -0
  38. package/es/layout-manager/LayoutRoute.d.ts +14 -0
  39. package/es/layout-manager/index.d.ts +13 -0
  40. package/es/layout-manager/types.d.ts +20 -0
  41. package/es/layout-manager/utils.d.ts +14 -0
  42. package/es/nocobase-buildin-plugin/index.d.ts +3 -10
  43. package/es/settings-center/index.d.ts +1 -1
  44. package/es/settings-center/plugin-manager/BulkEnableButton.d.ts +15 -0
  45. package/es/settings-center/plugin-manager/PluginCard.d.ts +15 -0
  46. package/es/settings-center/plugin-manager/PluginDetail.d.ts +16 -0
  47. package/es/settings-center/{PluginManagerPage.d.ts → plugin-manager/index.d.ts} +1 -7
  48. package/es/settings-center/plugin-manager/types.d.ts +34 -0
  49. package/lib/index.js +491 -439
  50. package/package.json +8 -7
  51. package/src/Application.tsx +27 -12
  52. package/src/BaseApplication.tsx +19 -0
  53. package/src/PluginSettingsManager.ts +1 -1
  54. package/src/RouterManager.tsx +17 -1
  55. package/src/__tests__/PluginSettingsManager.test.ts +41 -2
  56. package/src/__tests__/app.test.tsx +17 -1
  57. package/src/__tests__/globalDeps.test.ts +1 -0
  58. package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +45 -2
  59. package/src/__tests__/plugin-manager.test.tsx +177 -0
  60. package/src/__tests__/settings-center.test.tsx +24 -2
  61. package/src/components/KeepAlive.tsx +131 -0
  62. package/src/components/README.md +89 -6
  63. package/src/components/README.zh-CN.md +89 -7
  64. package/src/components/RouterBridge.tsx +28 -4
  65. package/src/components/__tests__/KeepAlive.test.tsx +63 -0
  66. package/src/components/__tests__/RouterBridge.test.tsx +27 -0
  67. package/src/components/form/DialogFormLayout.tsx +5 -29
  68. package/src/components/form/filter/CollectionFilter.tsx +101 -0
  69. package/src/components/form/filter/CollectionFilterItem.tsx +176 -0
  70. package/src/components/form/filter/DateFilterDynamicComponent.tsx +283 -0
  71. package/src/components/form/filter/FilterValueInput.tsx +198 -0
  72. package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +205 -0
  73. package/src/components/form/filter/__tests__/DateFilterDynamicComponent.test.tsx +148 -0
  74. package/src/components/form/filter/__tests__/FilterValueInput.test.tsx +243 -0
  75. package/src/components/form/filter/__tests__/compileFilterGroup.test.ts +146 -0
  76. package/src/components/form/filter/index.ts +13 -0
  77. package/src/components/form/filter/useFilterActionProps.ts +200 -0
  78. package/src/components/form/index.tsx +1 -0
  79. package/src/data-source/ExtendCollectionsProvider.tsx +144 -0
  80. package/src/data-source/__tests__/ExtendCollectionsProvider.test.tsx +264 -0
  81. package/src/data-source/index.ts +10 -0
  82. package/src/flow/FlowPage.tsx +35 -7
  83. package/src/flow/__tests__/FlowPage.test.tsx +79 -0
  84. package/src/flow/__tests__/FlowRoute.test.tsx +529 -2
  85. package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +191 -0
  86. package/src/flow/actions/__tests__/openView.subModelKey.test.tsx +33 -0
  87. package/src/flow/actions/aclCheck.tsx +4 -0
  88. package/src/flow/actions/aclCheckRefresh.tsx +4 -0
  89. package/src/flow/actions/dateTimeFormat.tsx +12 -8
  90. package/src/flow/actions/linkageRules.tsx +122 -0
  91. package/src/flow/actions/openView.tsx +28 -4
  92. package/src/flow/admin-shell/AdminLayoutRouteCoordinator.ts +11 -329
  93. package/src/flow/admin-shell/BaseLayoutModel.tsx +455 -0
  94. package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +502 -0
  95. package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +547 -3
  96. package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +4 -4
  97. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +160 -0
  98. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +0 -12
  99. package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +28 -201
  100. package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +11 -2
  101. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +1 -26
  102. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +149 -27
  103. package/src/flow/admin-shell/admin-layout/index.ts +2 -0
  104. package/src/flow/admin-shell/useAdminLayoutRoutePage.ts +10 -26
  105. package/src/flow/admin-shell/useLayoutRoutePage.ts +61 -0
  106. package/src/flow/components/AdminLayout.tsx +4 -154
  107. package/src/flow/components/FlowRoute.tsx +105 -15
  108. package/src/flow/components/filter/index.ts +3 -0
  109. package/src/flow/components/filter/useFilterOptions.ts +80 -0
  110. package/src/flow/index.ts +4 -0
  111. package/src/flow/models/base/ActionModel.tsx +8 -1
  112. package/src/flow/models/base/PageModel/PageModel.tsx +51 -18
  113. package/src/flow/models/base/PageModel/RootPageModel.tsx +6 -13
  114. package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +102 -1
  115. package/src/flow/models/base/RouteModel.tsx +1 -1
  116. package/src/flow/models/blocks/form/FormActionGroupModel.tsx +14 -0
  117. package/src/flow/models/blocks/form/FormItemModel.tsx +8 -1
  118. package/src/flow/models/blocks/form/__tests__/FormActionGroupModel.test.ts +46 -0
  119. package/src/flow/models/blocks/form/submitValues.ts +4 -1
  120. package/src/flow/models/blocks/table/TableBlockModel.tsx +118 -16
  121. package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +114 -0
  122. package/src/flow/models/fields/AssociationFieldModel/SubFormFieldModel.tsx +7 -1
  123. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +1 -1
  124. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -5
  125. package/src/flow/models/fields/ClickableFieldModel.tsx +9 -1
  126. package/src/flow/models/fields/DisplayTimeFieldModel.tsx +1 -1
  127. package/src/flow/models/fields/TimeFieldModel.tsx +1 -1
  128. package/src/flow/models/fields/__tests__/TimeFieldModel.test.tsx +61 -0
  129. package/src/flow/models/fields/mobile-components/MobileDatePicker.tsx +19 -3
  130. package/src/flow/models/fields/mobile-components/__tests__/MobileDatePicker.test.tsx +94 -0
  131. package/src/flow/models/topbar/TopbarActionModel.tsx +1 -1
  132. package/src/flow/utils/__tests__/dateTimeFormat.test.ts +91 -0
  133. package/src/index.ts +2 -0
  134. package/src/layout-manager/LayoutContentRoute.tsx +90 -0
  135. package/src/layout-manager/LayoutManager.tsx +185 -0
  136. package/src/layout-manager/LayoutRoute.tsx +138 -0
  137. package/src/layout-manager/__tests__/LayoutManager.test.tsx +335 -0
  138. package/src/layout-manager/__tests__/LayoutRoute.test.tsx +473 -0
  139. package/src/layout-manager/index.ts +14 -0
  140. package/src/layout-manager/types.ts +22 -0
  141. package/src/layout-manager/utils.ts +37 -0
  142. package/src/nocobase-buildin-plugin/index.tsx +69 -67
  143. package/src/nocobase-buildin-plugin/plugins/LocalePlugin.ts +1 -0
  144. package/src/settings-center/index.ts +1 -1
  145. package/src/settings-center/plugin-manager/BulkEnableButton.tsx +111 -0
  146. package/src/settings-center/plugin-manager/PluginCard.tsx +270 -0
  147. package/src/settings-center/plugin-manager/PluginDetail.tsx +195 -0
  148. package/src/settings-center/plugin-manager/index.tsx +254 -0
  149. package/src/settings-center/plugin-manager/types.ts +35 -0
  150. package/src/settings-center/utils.tsx +8 -1
  151. package/src/theme/__tests__/globalStyles.test.ts +24 -0
  152. package/src/theme/globalStyles.ts +10 -0
  153. package/src/utils/globalDeps.ts +2 -0
  154. package/src/settings-center/PluginManagerPage.tsx +0 -162
@@ -28,6 +28,7 @@ export interface ApplicationOptions extends BaseApplicationOptions<PluginType> {
28
28
  }
29
29
  export declare class Application extends BaseApplication<ApplicationOptions, PluginManager, RouterManager, APIClient, PluginSettingsManager> {
30
30
  dataSourceManager: any;
31
+ hasLoadError: boolean;
31
32
  protected createApiClient(options: ApplicationOptions): APIClient;
32
33
  protected configureRuntimeAdapters(): void;
33
34
  protected createI18n(options: ApplicationOptions): i18next;
@@ -12,6 +12,7 @@ import type { i18n as i18next } from 'i18next';
12
12
  import React, { ReactElement, ReactNode } from 'react';
13
13
  import { AIManager } from './ai';
14
14
  import { SystemSettingsSource } from './flow/system-settings';
15
+ import { LayoutManager } from './layout-manager/LayoutManager';
15
16
  import type { PluginClass, PluginManager, PluginType } from './PluginManager';
16
17
  import { RouteRepository } from './RouteRepository';
17
18
  import type { ComponentTypeAndString, RenderableComponentType, RouterComponentType, RouterManager, RouterOptions } from './RouterManager';
@@ -71,6 +72,7 @@ export declare abstract class BaseApplication<TOptions extends BaseApplicationOp
71
72
  components: Record<string, AnyComponent>;
72
73
  pluginManager: TPluginManager;
73
74
  pluginSettingsManager: TPluginSettingsManager;
75
+ layoutManager: LayoutManager<this>;
74
76
  aiManager: AIManager;
75
77
  devDynamicImport?: DevDynamicImport;
76
78
  requirejs: RequireJS;
@@ -106,6 +108,7 @@ export declare abstract class BaseApplication<TOptions extends BaseApplicationOp
106
108
  get pm(): TPluginManager;
107
109
  get disableAcl(): boolean;
108
110
  get isWsAuthorized(): boolean;
111
+ setDocumentLanguage(language?: string | null): void;
109
112
  constructor(options?: TOptions);
110
113
  /**
111
114
  * 注册共享 observable 状态。
@@ -160,6 +163,7 @@ export declare abstract class BaseApplication<TOptions extends BaseApplicationOp
160
163
  protected abstract createRouterManager(options: TOptions): TRouterManager;
161
164
  protected abstract createPluginManager(options: TOptions): TPluginManager;
162
165
  protected abstract createPluginSettingsManager(options: TOptions): TPluginSettingsManager;
166
+ protected createLayoutManager(_options: TOptions): LayoutManager<this>;
163
167
  protected createWebSocketClient(options: TOptions): WebSocketClient;
164
168
  protected getDefaultComponents(): Record<string, AnyComponent>;
165
169
  abstract load(): Promise<void>;
@@ -34,6 +34,7 @@ export interface RouteType extends Omit<RouteObject, 'children' | 'Component'> {
34
34
  Component?: ComponentTypeAndString;
35
35
  componentLoader?: ComponentLoader;
36
36
  skipAuthCheck?: boolean;
37
+ authCheck?: boolean;
37
38
  }
38
39
  export type RenderComponentType = (Component: ComponentTypeAndString, props?: any) => React.ReactNode;
39
40
  export type RouterComponentType = React.FC<{
@@ -0,0 +1,22 @@
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 React, { FC } from 'react';
10
+ export declare const KeepAliveProvider: FC<{
11
+ active: boolean;
12
+ parentActive: boolean;
13
+ }>;
14
+ export declare const useKeepAlive: () => {
15
+ active: boolean;
16
+ };
17
+ interface KeepAliveProps {
18
+ uid: string;
19
+ children: (uid: string) => React.ReactNode;
20
+ }
21
+ export declare const KeepAlive: FC<KeepAliveProps>;
22
+ export {};
@@ -7,7 +7,16 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { Application } from '../Application';
10
+ type LayoutMatchLike = {
11
+ id: string;
12
+ pathname: string;
13
+ };
14
+ type LayoutDefinitionLike = {
15
+ routeName: string;
16
+ };
17
+ export declare function findDeepestLayoutMatch(layouts?: LayoutDefinitionLike[], matches?: LayoutMatchLike[]): LayoutMatchLike;
10
18
  export declare function useRouterSync(app: Application): void;
11
19
  export declare function RouterBridge({ app }: {
12
20
  app: any;
13
21
  }): any;
22
+ export {};
@@ -12,17 +12,9 @@ export interface DialogFormLayoutProps {
12
12
  title: React.ReactNode;
13
13
  /** Form body — typically a `<Form>` wrapping `<Form.Item>` fields. */
14
14
  children: React.ReactNode;
15
- /**
16
- * Called before the dialog is closed by the Cancel button or the
17
- * top-right close (X) icon. Use for "discard changes" confirmations.
18
- */
15
+ /** Called before the dialog is closed by the Cancel button or the top-right close (X) icon. Use for "discard changes" confirmations. */
19
16
  onCancel?: () => void | Promise<void>;
20
- /**
21
- * Called when the Submit button is clicked. Caller owns validation
22
- * + the actual API call; the dialog is closed automatically when
23
- * `onSubmit` resolves. Throw from `onSubmit` to keep the dialog open
24
- * (e.g. on a validation error).
25
- */
17
+ /** Called when the Submit button is clicked. Caller owns validation + the actual API call; the dialog is closed automatically when `onSubmit` resolves. Throw from `onSubmit` to keep the dialog open (e.g. on a validation error). */
26
18
  onSubmit?: () => void | Promise<void>;
27
19
  /** Drives the Submit button's loading state. */
28
20
  submitting?: boolean;
@@ -30,29 +22,13 @@ export interface DialogFormLayoutProps {
30
22
  submitText?: React.ReactNode;
31
23
  /** Override the Cancel button label. Defaults to "Cancel". */
32
24
  cancelText?: React.ReactNode;
33
- /**
34
- * Full override of the footer content. When provided, the default
35
- * Cancel + Submit buttons are replaced. Useful for forms that need
36
- * extra actions (e.g. Preview, Save draft).
37
- */
25
+ /** Full override of the footer content. When provided, the default Cancel + Submit buttons are replaced. Useful for forms that need extra actions (e.g. Preview, Save draft). */
38
26
  footer?: React.ReactNode;
39
27
  }
40
28
  /**
41
- * Standard layout for dialog-hosted forms — the dialog counterpart of
42
- * `DrawerFormLayout`. Title sits left-aligned in the dialog's native
43
- * header (no inline close icon — the dialog provides its own X in the
44
- * top-right when opened with `viewer.dialog({ closable: true, ... })`),
45
- * the form body fills the middle, and a Cancel + Submit footer sits
46
- * at the bottom.
29
+ * Standard layout for dialog-hosted forms — the dialog counterpart of `DrawerFormLayout`. Title sits left-aligned in the dialog's native header, the form body fills the middle, and a Cancel + Submit footer sits at the bottom. Neither this layout nor `DrawerFormLayout` renders a close icon — both rely on the caller passing `closable: true` at the `viewer.dialog` / `viewer.drawer` call site to surface antd Modal's native top-right X (Dialog) or antd Drawer's native left-side X (Drawer).
47
30
  *
48
- * Why not just reuse `DrawerFormLayout`? `DrawerFormLayout` injects a
49
- * `<CloseOutlined>` button next to the title — that's the drawer
50
- * visual contract (close lives near the title in a side panel). In a
51
- * centered dialog the native top-right close button is the expected
52
- * affordance, so a separate layout keeps the visual contract clean.
53
- *
54
- * Callers own the `<Form>` instance, validation, and the actual API
55
- * call. This component only handles the chrome and close behaviour.
31
+ * Callers own the `<Form>` instance, validation, and the actual API call. This component only handles the chrome and close behaviour.
56
32
  *
57
33
  * Example:
58
34
  *
@@ -0,0 +1,41 @@
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 type { Collection } from '@nocobase/flow-engine';
10
+ import { type ButtonProps, type PopoverProps } from 'antd';
11
+ import React, { FC } from 'react';
12
+ import { CompiledFilter } from './useFilterActionProps';
13
+ export interface CollectionFilterProps {
14
+ /** Collection whose fields drive the filter row's field picker. */
15
+ collection: Collection | undefined;
16
+ /** Called on Submit or Reset with the compiled NocoBase filter param (`undefined` when cleared). */
17
+ onChange: (filter: CompiledFilter) => void;
18
+ /** Translator. Defaults to identity. */
19
+ t?: (key: string, options?: Record<string, any>) => string;
20
+ /** Whitelist of root-level field names to expose. */
21
+ filterableFieldNames?: string[];
22
+ /** Bypass the `filterableFieldNames` whitelist. */
23
+ noIgnore?: boolean;
24
+ /** Override the trigger button's label. Defaults to `t('Filter')`, or the v1-style `t('{{count}} filter items', { count })` when conditions are present. */
25
+ buttonText?: React.ReactNode;
26
+ /** Swap the default `t('Filter')` label for v1's `t('{{count}} filter items', { count })` when conditions are present. Defaults to `true`. */
27
+ showCount?: boolean;
28
+ /** Pass-through props for the antd `<Popover>`. */
29
+ popoverProps?: Omit<PopoverProps, 'open' | 'onOpenChange' | 'content' | 'children'>;
30
+ /** Pass-through props for the trigger `<Button>`. */
31
+ buttonProps?: Omit<ButtonProps, 'icon' | 'type' | 'children' | 'onClick'>;
32
+ /** Min-width applied to the popover body. Defaults to `520`. */
33
+ popoverMinWidth?: number;
34
+ }
35
+ /**
36
+ * Filter button bound to a collection. Renders an antd `<Popover>` over a `<Button>`; the popover hosts a multi-condition filter form (field picker, operator, value). Submit dismisses the popover and emits the compiled filter via `onChange`; Reset keeps the popover open and emits `undefined`.
37
+ *
38
+ * Pair with `<ExtendCollectionsProvider>` when the target collection is client-only (e.g. a `schema-only` server collection that isn't auto-published to the v2 data source).
39
+ */
40
+ export declare const CollectionFilter: FC<CollectionFilterProps>;
41
+ export default CollectionFilter;
@@ -0,0 +1,41 @@
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 { Collection } from '@nocobase/flow-engine';
10
+ import React, { FC } from 'react';
11
+ export interface CollectionFilterItemValue {
12
+ path: string;
13
+ operator: string;
14
+ /** Operator-dependent — string for default ops, descriptor for $date*, etc. */
15
+ value: any;
16
+ }
17
+ export interface CollectionFilterItemProps {
18
+ /** Reactive filter row managed by the parent `FilterContainer`. */
19
+ value: CollectionFilterItemValue;
20
+ /** Target collection whose fields populate the field selector. */
21
+ collection: Collection;
22
+ /** Whitelist of field names to expose; empty/undefined means all filterable fields. */
23
+ filterableFieldNames?: string[];
24
+ /** Bypass the `filterableFieldNames` whitelist (matches the legacy FilterItem `noIgnore`). */
25
+ noIgnore?: boolean;
26
+ /** Translator; defaults to identity so callers can omit it. */
27
+ t?: (key: string) => string;
28
+ }
29
+ /**
30
+ * Filter row bound directly to a `Collection`, with no `FlowModel` dependency. Use this from settings pages or other surfaces that need a filter UI but don't have (and shouldn't synthesise) a block model just to satisfy `FilterItem`. Pair with `FilterContainer` via either an inline wrapper or `createCollectionFilterItem(collection)`.
31
+ *
32
+ * The field selector is an antd `Cascader`, mirroring v1's `Filter.Action` so association fields (belongsTo / m2o / etc.) can be drilled into — picking `user.username` is a first-class action. The value renderer is delegated to `FilterValueInput`, which dispatches to interface-specific controls (the smart date picker for `$date*` operators, tag-mode Select for array/enum, etc.) the same way v1's `DynamicComponent` did.
33
+ */
34
+ export declare const CollectionFilterItem: FC<CollectionFilterItemProps>;
35
+ /**
36
+ * Convenience factory returning a `FilterContainer`-compatible `FilterItem` component bound to a specific collection. Avoids creating an inline closure on every parent render, which would otherwise reset any focused inner antd control.
37
+ */
38
+ export declare function createCollectionFilterItem(collection: Collection, bound?: Pick<CollectionFilterItemProps, 'filterableFieldNames' | 'noIgnore' | 't'>): React.FC<{
39
+ value: CollectionFilterItemValue;
40
+ }>;
41
+ export default CollectionFilterItem;
@@ -0,0 +1,57 @@
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 { type Dayjs } from 'dayjs';
10
+ import React from 'react';
11
+ /**
12
+ * Value shape used by NocoBase's `$date*` filter operators. Two flavours:
13
+ *
14
+ * - For "Exact day" mode: a **formatted string** at the granularity of the picker — `"2026-02-15"` (date), `"2026-02"` (month), `"2026"` (year), `"2026-Q1"` (quarter). For `$dateBetween` (`isRange`), a `[string, string]` tuple. Strings (not Dayjs) so the value serializes verbatim into the query string the same way v1 does (`filter=%7B%22$and%22:[%7B%22lockedTs%22:%7B%22$dateOn%22:%222026-02%22%7D%7D]%7D`).
15
+ * - For relative modes (Today / Past 3 days / This Week / …): a `{ type, number?, unit? }` descriptor that the server resolves to a concrete range at query time.
16
+ */
17
+ export type DateFilterValue = string | [string, string] | {
18
+ type: string;
19
+ number?: number;
20
+ unit?: 'day' | 'week' | 'month' | 'year';
21
+ } | null | undefined;
22
+ export interface DateFilterDynamicComponentProps {
23
+ value?: DateFilterValue;
24
+ onChange?: (value: DateFilterValue) => void;
25
+ /** `true` for `$dateBetween`; renders a `DatePicker.RangePicker`. */
26
+ isRange?: boolean;
27
+ /**
28
+ * Translator. Defaults to identity so callers can omit it when running outside a translation context (tests, storybook).
29
+ */
30
+ t?: (key: string) => string;
31
+ }
32
+ type PickerMode = 'date' | 'month' | 'quarter' | 'year';
33
+ /**
34
+ * The exact format strings NocoBase's `$date*` server operators expect per picker granularity. Mirrors v1's `getPickerFormat` output under `underFilter=true`, so the URL-encoded query stays identical.
35
+ *
36
+ * Exported for unit tests and for downstream callers that need to parse / format `$date*` values outside this component.
37
+ */
38
+ export declare const FORMAT_BY_PICKER: Record<PickerMode, string>;
39
+ /**
40
+ * Parse a granularity-formatted string back into a `Dayjs`. Returns `null` on missing or unparseable input so the DatePicker's controlled-value contract stays clean.
41
+ */
42
+ export declare const parseDateFilterValue: (value: string | undefined, picker: PickerMode) => Dayjs | null;
43
+ /**
44
+ * Format a `Dayjs` (typically from `DatePicker.onChange`) into the server-facing string at the active picker's granularity. Returns `undefined` for empty input so callers can drop the value entirely.
45
+ */
46
+ export declare const formatDateFilterValue: (value: Dayjs | null | undefined, picker: PickerMode) => string | undefined;
47
+ /**
48
+ * v2 port of v1's `DateFilterDynamicComponent` — a multi-mode value input for the `$date*` operator family. Three sub-controls glued in a `Space.Compact` row:
49
+ *
50
+ * 1. Mode select — `Exact day` / `Past` / `Next` / `Today` / `This Week` / … Picking a relative mode emits a `{ type, number?, unit? }` descriptor that the server resolves at query time; picking `Exact day` emits a raw `Dayjs` instead.
51
+ * 2. Picker granularity — only when mode is `Exact day`: `Date` / `Month` / `Quarter` / `Year`. Controls the antd `DatePicker`'s `picker` mode so admins can filter to e.g. "any day in 2026-03".
52
+ * 3. Date input — antd `DatePicker` for single dates, or `DatePicker.RangePicker` when `isRange` is true (used by `$dateBetween`).
53
+ *
54
+ * v1 wired its own `<DatePicker.FilterWithPicker>` for the third slot; v2 inlines the picker-granularity selector here so we don't have to fork antd's DatePicker. Drops v1's `@emotion/css` (uses antd token spacing) and the `useCompile` schema-template chain (call sites pass a plain `t` translator).
55
+ */
56
+ export declare const DateFilterDynamicComponent: React.FC<DateFilterDynamicComponentProps>;
57
+ export default DateFilterDynamicComponent;
@@ -0,0 +1,29 @@
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 React from 'react';
10
+ import type { FilterOperator, FilterOption } from '../../../flow/components/filter/useFilterOptions';
11
+ export interface FilterValueInputProps {
12
+ /** The currently selected leaf field option from the field picker. */
13
+ field?: FilterOption;
14
+ /** The currently selected operator (full object, not just `.value`). */
15
+ operator?: FilterOperator;
16
+ /** Current value. Shape depends on operator/field. */
17
+ value: any;
18
+ /** Notify the parent when the user edits the value. */
19
+ onChange: (value: any) => void;
20
+ /** Translator used by sub-renderers. */
21
+ t?: (key: string) => string;
22
+ /** Optional placeholder for the fallback `Input`. */
23
+ placeholder?: string;
24
+ }
25
+ /**
26
+ * Interface-aware value renderer for filter rows. Returns `null` for `noValue` operators (`$empty`, `$notEmpty`). Otherwise dispatches the effective `x-component` (operator schema > field uiSchema > Input) to a small registry of antd controls.
27
+ */
28
+ export declare const FilterValueInput: React.FC<FilterValueInputProps>;
29
+ export default FilterValueInput;
@@ -0,0 +1,11 @@
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
+ export { CollectionFilter } from './CollectionFilter';
10
+ export type { CollectionFilterProps } from './CollectionFilter';
11
+ export type { CompiledFilter } from './useFilterActionProps';
@@ -0,0 +1,96 @@
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 { Collection } from '@nocobase/flow-engine';
10
+ import { FilterOption, UseFilterOptionsArgs } from '../../../flow/components/filter/useFilterOptions';
11
+ import { CollectionFilterItemValue, createCollectionFilterItem } from './CollectionFilterItem';
12
+ /** A single condition row (`{ path, operator, value }`) or a nested group. */
13
+ export type FilterGroupItem = CollectionFilterItemValue | FilterGroupValue;
14
+ /**
15
+ * Reactive shape consumed by `FilterContainer` / `FilterGroup`. `logic` is the join (`$and` / `$or`) and `items` is a heterogeneous list of leaf conditions and nested groups.
16
+ */
17
+ export type FilterGroupValue = {
18
+ logic: '$and' | '$or';
19
+ items: FilterGroupItem[];
20
+ };
21
+ /** Compiled filter param accepted by NocoBase resource `list`. */
22
+ export type CompiledFilter = Record<string, unknown> | undefined;
23
+ interface FilterCtxModel {
24
+ translate: (key: string) => string;
25
+ dispatchEvent: (event: 'submit' | 'reset' | (string & {})) => void;
26
+ }
27
+ export interface FilterCtx {
28
+ model: FilterCtxModel;
29
+ }
30
+ /**
31
+ * Compile a reactive filter group into the `{ $and: [{ path: { op: val } }] }` envelope accepted by NocoBase's resource `list` filter param. Returns `undefined` when the group is empty so callers can drop the param.
32
+ *
33
+ * Mirrors v1's `removeNullCondition` + filter compile path, but works on the v2 `{ logic, items }` group structure rather than v1's Formily-bracketed `$and.0.path.$eq` shape:
34
+ *
35
+ * - Rows missing `path` or `operator` are dropped (still mid-edit).
36
+ * - Rows whose `value` is empty (`undefined`, `''`, `[]`, `{}`) are dropped — matches v1, which sends `filter={}` for a row with only a field/operator picked. Sending `{lockedTs:{}}` would 500.
37
+ * - Dotted association paths (`user.createdBy.password`) are expanded into nested objects — matches v1's payload shape, which the server resolves along the association chain rather than treating the dotted string as a single key.
38
+ * - Empty groups (after pruning) propagate as `undefined` so the outermost caller can drop the whole `filter` param.
39
+ */
40
+ export declare function compileFilterGroup(group: FilterGroupValue | undefined): CompiledFilter;
41
+ /** Which footer button triggered the apply — useful for closing a popover on Submit but keeping it open on Reset. */
42
+ export type FilterApplyAction = 'submit' | 'reset';
43
+ export interface UseFilterActionPropsArgs extends UseFilterOptionsArgs {
44
+ /** Collection whose fields populate the filter row's field picker. */
45
+ collection: Collection | undefined;
46
+ /**
47
+ * Called when the user submits or resets the filter popover. Receives the compiled filter param (`undefined` when cleared) and which footer button triggered the call. Typical implementation: `(filter, action) => { listRequest.run(filter); if (action === 'submit') closePopover(); }`.
48
+ */
49
+ onApply: (filter: CompiledFilter, action: FilterApplyAction) => void;
50
+ }
51
+ export interface UseFilterActionPropsResult {
52
+ /**
53
+ * Reactive filter group state. Pass directly to `<FilterContent value={...}>`. Stable across renders.
54
+ */
55
+ value: FilterGroupValue;
56
+ /** Field-option tree (for inspection or custom badges). */
57
+ options: FilterOption[];
58
+ /** Bound `FilterItem` component to plug into `<FilterContent FilterItem={...}>`. */
59
+ FilterItem: ReturnType<typeof createCollectionFilterItem> | undefined;
60
+ /**
61
+ * Ready-to-use `ctx` for `<FilterContent ctx={...}>`. Wires Submit / Reset buttons to `onSubmit` / `onReset` below.
62
+ */
63
+ ctx: FilterCtx;
64
+ /** Imperative trigger — submit current group as a compiled filter. */
65
+ onSubmit: () => void;
66
+ /** Imperative trigger — clear the group and emit an empty filter. */
67
+ onReset: () => void;
68
+ /**
69
+ * Count of top-level condition rows. Useful for showing a badge like `Filter (3)` on the trigger button — matches v1's `field.title = t('{{count}} filter items', { count })`.
70
+ */
71
+ conditionCount: number;
72
+ }
73
+ /**
74
+ * v2 equivalent of v1's `useFilterActionProps` for non-schema surfaces (settings pages, panels, side drawers). Bundles three things v1's hook returned implicitly through schema:
75
+ *
76
+ * - A reactive `{ logic, items }` group state that `<FilterContent>` reads.
77
+ * - A bound `FilterItem` component (driven by `createCollectionFilterItem`).
78
+ * - A `ctx` object that turns `<FilterContent>`'s `dispatchEvent('submit' | 'reset')` into a compiled filter param passed to `onApply`.
79
+ *
80
+ * Pair with antd `Popover` to recreate the legacy `Filter.Action` UX:
81
+ *
82
+ * ```tsx
83
+ * const { value, ctx, FilterItem, onSubmit, conditionCount } = useFilterActionProps({
84
+ * collection,
85
+ * onApply: (filter) => listRequest.run(filter),
86
+ * t,
87
+ * });
88
+ * return (
89
+ * <Popover content={<FilterContent value={value} ctx={ctx} FilterItem={FilterItem} />}>
90
+ * <Button>{t('Filter')}{conditionCount ? ` (${conditionCount})` : ''}</Button>
91
+ * </Popover>
92
+ * );
93
+ * ```
94
+ */
95
+ export declare function useFilterActionProps(args: UseFilterActionPropsArgs): UseFilterActionPropsResult;
96
+ export {};
@@ -7,6 +7,7 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  export * from './createFormRegistry';
10
+ export * from './filter';
10
11
  export * from './DialogFormLayout';
11
12
  export * from './DrawerFormLayout';
12
13
  export * from './EnvVariableInput';
@@ -0,0 +1,50 @@
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 type { CollectionOptions } from '@nocobase/flow-engine';
10
+ import { FC, ReactNode } from 'react';
11
+ export interface ExtendCollectionsProviderProps {
12
+ /** Data source key to extend. Defaults to `'main'`. */
13
+ dataSource?: string;
14
+ /** Collections to surface for the lifetime of this provider's subtree. */
15
+ collections: CollectionOptions[];
16
+ /**
17
+ * When `true`, re-sync the data source whenever the `collections` prop
18
+ * reference changes after mount: add entries newly present in the prop and
19
+ * remove entries no longer present (only those this provider registered).
20
+ * The diff runs in the same render as the prop change so children see the
21
+ * new state on their first render — at the cost of one observable mutation
22
+ * per change.
23
+ *
24
+ * Defaults to `false`. Most pages pass a stable (often module-level)
25
+ * `collections` list and don't need this; leaving it off avoids accidental
26
+ * re-registration when callers forget to memoize. Enable only when your
27
+ * collection list legitimately varies during the provider's lifetime.
28
+ */
29
+ syncOnChange?: boolean;
30
+ children?: ReactNode;
31
+ }
32
+ /**
33
+ * Mount-scoped collection injector. Adds the given `collections` to the target
34
+ * data source on first render — synchronously, so children can read
35
+ * `getCollection(name)` on their own first render — and removes them on
36
+ * unmount. Survives mid-session data-source reloads via the
37
+ * `dataSource:loaded` event by re-registering only the names this provider
38
+ * owns.
39
+ *
40
+ * Use this for client-only collections — e.g. a `schema-only` server
41
+ * collection that isn't auto-published to the v2 data source, or a pure
42
+ * UI-side mirror — so downstream components (like `<CollectionFilter>`) can
43
+ * resolve the collection by name.
44
+ *
45
+ * Default behavior is "static-at-mount": subsequent changes to the
46
+ * `collections` prop are ignored. Pass `syncOnChange` to opt into diffing on
47
+ * prop change.
48
+ */
49
+ export declare const ExtendCollectionsProvider: FC<ExtendCollectionsProviderProps>;
50
+ export default ExtendCollectionsProvider;
@@ -0,0 +1,9 @@
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
+ export * from './ExtendCollectionsProvider';
@@ -6,7 +6,7 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- import type { FlowModel } from '@nocobase/flow-engine';
9
+ import type { FlowModel, FlowModelRendererProps } from '@nocobase/flow-engine';
10
10
  import React from 'react';
11
11
  import FlowRoute from './components/FlowRoute';
12
12
  type FlowPageProps = {
@@ -14,6 +14,7 @@ type FlowPageProps = {
14
14
  parentId?: string;
15
15
  onModelLoaded?: (uid: string, model: FlowModel) => void;
16
16
  defaultTabTitle?: string;
17
+ showFlowSettings?: FlowModelRendererProps['showFlowSettings'];
17
18
  };
18
19
  export declare const FlowPage: React.MemoExoticComponent<(props: FlowPageProps & Record<string, unknown>) => React.JSX.Element>;
19
20
  export declare const RemoteFlowModelRenderer: (props: any) => React.JSX.Element;
@@ -6,46 +6,14 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- import { FlowEngine, FlowModel, type ViewParam } from '@nocobase/flow-engine';
10
- export interface RoutePageMeta {
11
- active: boolean;
12
- refreshDesktopRoutes?: () => Promise<unknown>;
13
- layoutContentElement?: HTMLElement | null;
14
- }
15
- interface RouteLike {
16
- params?: {
17
- name?: string;
18
- };
19
- pathname?: string;
20
- }
9
+ import type { FlowEngine } from '@nocobase/flow-engine';
10
+ import { BaseLayoutRouteCoordinator, type BaseLayoutRouteCoordinatorOptions } from './BaseLayoutRouteCoordinator';
21
11
  /**
22
- * 管理 admin 场景下每个 page 的 v2 视图栈编排。
23
- * 该协调器只负责状态机和开关视图,不直接绑定 React 生命周期。
12
+ * Admin Layout 路由协调器。
13
+ *
14
+ * 该类保留旧导出路径,内部复用通用 BaseLayoutRouteCoordinator。
24
15
  */
25
- export declare class AdminLayoutRouteCoordinator {
26
- private readonly flowEngine;
27
- private readonly runtimes;
28
- private layoutContentElement;
29
- private setRuntimeActive;
30
- private getCurrentRouteByPageUid;
31
- constructor(flowEngine: FlowEngine);
32
- setLayoutContentElement(element: HTMLElement | null): void;
33
- registerPage(pageUid: string, meta: RoutePageMeta): FlowModel<import("@nocobase/flow-engine").DefaultStructure>;
34
- syncPageMeta(pageUid: string, meta: Partial<RoutePageMeta>): void;
35
- unregisterPage(pageUid: string): void;
36
- syncRoute(routeLike: RouteLike): void;
37
- cleanupPage(pageUid: string): void;
38
- destroy(): void;
39
- private syncRuntimeWithPathname;
40
- private shouldStepNavigate;
41
- private stepNavigate;
42
- private handleOpenViews;
43
- private openViews;
44
- private ensureRouteModelContext;
45
- private getOrCreateRouteModel;
16
+ export declare class AdminLayoutRouteCoordinator extends BaseLayoutRouteCoordinator {
17
+ constructor(flowEngine: FlowEngine, options?: BaseLayoutRouteCoordinatorOptions);
46
18
  }
47
- /**
48
- * 将 pathname 解析结果和 pageUid 对齐,便于测试里复用。
49
- */
50
- export declare function toViewStack(pathname: string): ViewParam[];
51
- export {};
19
+ export { toViewStack, type BaseLayoutRouteCoordinatorOptions, type RoutePageMeta } from './BaseLayoutRouteCoordinator';