@nocobase/client-v2 2.1.0-beta.34 → 2.1.0-beta.35
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.
- package/es/BaseApplication.d.ts +6 -0
- package/es/PluginManager.d.ts +2 -0
- package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +9 -1
- package/es/index.mjs +77 -77
- package/es/json-logic/globalOperators.d.ts +11 -0
- package/es/utils/globalDeps.d.ts +7 -0
- package/lib/index.js +91 -91
- package/package.json +7 -6
- package/src/BaseApplication.tsx +8 -0
- package/src/PluginManager.ts +2 -0
- package/src/__tests__/app.test.tsx +8 -0
- package/src/__tests__/remotePlugins.test.ts +148 -0
- package/src/css-variable/CSSVariableProvider.tsx +1 -1
- package/src/flow/actions/filterFormDefaultValues.tsx +1 -2
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +329 -5
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +337 -0
- package/src/json-logic/globalOperators.js +731 -0
- package/src/utils/globalDeps.ts +45 -29
- package/src/utils/remotePlugins.ts +107 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/client-v2",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.35",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.mjs",
|
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
"@formily/antd-v5": "1.2.3",
|
|
27
27
|
"@formily/react": "^2.2.27",
|
|
28
28
|
"@formily/shared": "^2.2.27",
|
|
29
|
-
"@nocobase/evaluators": "2.1.0-beta.
|
|
30
|
-
"@nocobase/flow-engine": "2.1.0-beta.
|
|
31
|
-
"@nocobase/sdk": "2.1.0-beta.
|
|
32
|
-
"@nocobase/shared": "2.1.0-beta.
|
|
29
|
+
"@nocobase/evaluators": "2.1.0-beta.35",
|
|
30
|
+
"@nocobase/flow-engine": "2.1.0-beta.35",
|
|
31
|
+
"@nocobase/sdk": "2.1.0-beta.35",
|
|
32
|
+
"@nocobase/shared": "2.1.0-beta.35",
|
|
33
|
+
"@nocobase/utils": "2.1.0-beta.35",
|
|
33
34
|
"ahooks": "^3.7.2",
|
|
34
35
|
"antd": "5.24.2",
|
|
35
36
|
"antd-style": "3.7.1",
|
|
@@ -43,5 +44,5 @@
|
|
|
43
44
|
"react-i18next": "^11.15.1",
|
|
44
45
|
"react-router-dom": "^6.30.1"
|
|
45
46
|
},
|
|
46
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "74310d8b9e9581fcde14b5a93d12b41ddb5bb325"
|
|
47
48
|
}
|
package/src/BaseApplication.tsx
CHANGED
|
@@ -40,6 +40,7 @@ import type {
|
|
|
40
40
|
RouterOptions,
|
|
41
41
|
} from './RouterManager';
|
|
42
42
|
import { WebSocketClient, type WebSocketClientOptions } from './WebSocketClient';
|
|
43
|
+
import { getOperators } from './json-logic/globalOperators';
|
|
43
44
|
import { compose, normalizeContainer } from './utils';
|
|
44
45
|
import { defineGlobalDeps } from './utils/globalDeps';
|
|
45
46
|
import { getRequireJs } from './utils/requirejs';
|
|
@@ -57,6 +58,11 @@ type AuthTokenPayload = {
|
|
|
57
58
|
token: string;
|
|
58
59
|
authenticator: string | null;
|
|
59
60
|
};
|
|
61
|
+
export type JsonLogic = {
|
|
62
|
+
apply: (logic: any, data?: any) => any;
|
|
63
|
+
addOperation: (name: string, fn?: any) => void;
|
|
64
|
+
rmOperation: (name: string) => void;
|
|
65
|
+
};
|
|
60
66
|
|
|
61
67
|
const LEADING_SLASHES_REGEXP = /^\/+/;
|
|
62
68
|
const TRAILING_SLASHES_REGEXP = /\/+$/;
|
|
@@ -123,6 +129,7 @@ export abstract class BaseApplication<
|
|
|
123
129
|
public favicon!: string;
|
|
124
130
|
public flowEngine: FlowEngine;
|
|
125
131
|
public dataSourceManager: any;
|
|
132
|
+
public jsonLogic!: JsonLogic;
|
|
126
133
|
public context: FlowEngineContext & {
|
|
127
134
|
routeRepository: RouteRepository;
|
|
128
135
|
appInfo: Promise<Record<string, any>>;
|
|
@@ -220,6 +227,7 @@ export abstract class BaseApplication<
|
|
|
220
227
|
|
|
221
228
|
protected afterManagersInitialized() {
|
|
222
229
|
this.aiManager = new AIManager(this);
|
|
230
|
+
this.jsonLogic = getOperators();
|
|
223
231
|
}
|
|
224
232
|
|
|
225
233
|
protected configureContext() {
|
package/src/PluginManager.ts
CHANGED
|
@@ -48,6 +48,14 @@ describe('app', () => {
|
|
|
48
48
|
expect(app.getHref('/test')).toBe('/test');
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
it('should initialize shared jsonLogic operators', () => {
|
|
52
|
+
const app = new Application({ router });
|
|
53
|
+
|
|
54
|
+
expect(app.jsonLogic.apply({ $eq: [1, '1'] })).toBe(true);
|
|
55
|
+
app.jsonLogic.addOperation('$testAlwaysTrue', () => true);
|
|
56
|
+
expect(app.jsonLogic.apply({ $testAlwaysTrue: [] })).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
51
59
|
it('should apply the provided favicon immediately', () => {
|
|
52
60
|
const app = new Application({ router });
|
|
53
61
|
|
|
@@ -14,8 +14,11 @@ import { configRequirejs, defineDevPlugins, getPlugins } from '../utils/remotePl
|
|
|
14
14
|
describe('client-v2 remotePlugins', () => {
|
|
15
15
|
afterEach(() => {
|
|
16
16
|
window.define = undefined;
|
|
17
|
+
window.__nocobase_app_dev_plugins__ = undefined;
|
|
17
18
|
});
|
|
18
19
|
|
|
20
|
+
const createModuleUrl = (code: string) => `data:text/javascript;charset=utf-8,${encodeURIComponent(code)}`;
|
|
21
|
+
|
|
19
22
|
it('should define dev plugins with /client-v2 module ids', () => {
|
|
20
23
|
class DemoPlugin extends Plugin {}
|
|
21
24
|
|
|
@@ -58,6 +61,151 @@ describe('client-v2 remotePlugins', () => {
|
|
|
58
61
|
expect(mockDefine).not.toHaveBeenCalledWith('@nocobase/demo/client', expect.any(Function));
|
|
59
62
|
});
|
|
60
63
|
|
|
64
|
+
it('should request remote plugins when devDynamicImport only resolves some plugins', async () => {
|
|
65
|
+
class DemoPlugin extends Plugin {}
|
|
66
|
+
|
|
67
|
+
const remoteFn = vi.fn();
|
|
68
|
+
const requirejs: any = {
|
|
69
|
+
requirejs: (pluginData, resolve) => {
|
|
70
|
+
remoteFn();
|
|
71
|
+
resolve({ default: DemoPlugin });
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
requirejs.requirejs.config = vi.fn();
|
|
75
|
+
|
|
76
|
+
const mockDefine: any = vi.fn();
|
|
77
|
+
window.define = mockDefine;
|
|
78
|
+
|
|
79
|
+
const plugins = await getPlugins({
|
|
80
|
+
requirejs,
|
|
81
|
+
pluginData: [
|
|
82
|
+
{
|
|
83
|
+
name: '@nocobase/demo',
|
|
84
|
+
packageName: '@nocobase/demo',
|
|
85
|
+
url: 'https://demo.com/dist/client-v2/index.js',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: '@nocobase/remote',
|
|
89
|
+
packageName: '@nocobase/remote',
|
|
90
|
+
url: 'https://remote.com/dist/client-v2/index.js',
|
|
91
|
+
},
|
|
92
|
+
] as any,
|
|
93
|
+
devDynamicImport: ((packageName) => {
|
|
94
|
+
if (packageName === '@nocobase/demo') {
|
|
95
|
+
return Promise.resolve({ default: DemoPlugin });
|
|
96
|
+
}
|
|
97
|
+
return Promise.resolve(null);
|
|
98
|
+
}) as any,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(plugins).toEqual([
|
|
102
|
+
['@nocobase/demo', DemoPlugin],
|
|
103
|
+
['@nocobase/remote', DemoPlugin],
|
|
104
|
+
]);
|
|
105
|
+
expect(remoteFn).toHaveBeenCalledTimes(1);
|
|
106
|
+
expect(mockDefine).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(requirejs.requirejs.config).toHaveBeenCalledWith({
|
|
108
|
+
waitSeconds: 120,
|
|
109
|
+
paths: {
|
|
110
|
+
'@nocobase/remote/client-v2': 'https://remote.com/dist/client-v2/index.js',
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should register ESM dev plugins before importing dependent plugins', async () => {
|
|
116
|
+
const requirejs: any = {
|
|
117
|
+
requirejs: vi.fn(),
|
|
118
|
+
};
|
|
119
|
+
requirejs.requirejs.config = vi.fn();
|
|
120
|
+
|
|
121
|
+
const mockDefine: any = vi.fn();
|
|
122
|
+
window.define = mockDefine;
|
|
123
|
+
|
|
124
|
+
const plugins = await getPlugins({
|
|
125
|
+
requirejs,
|
|
126
|
+
pluginData: [
|
|
127
|
+
{
|
|
128
|
+
name: '@nocobase/dependent',
|
|
129
|
+
packageName: '@nocobase/dependent',
|
|
130
|
+
url: createModuleUrl(`
|
|
131
|
+
const dependency = window.__nocobase_app_dev_plugins__ && window.__nocobase_app_dev_plugins__['@nocobase/dependency/client-v2'];
|
|
132
|
+
export default class DependentPlugin extends dependency.default {
|
|
133
|
+
static SharedBase = dependency.SharedBase;
|
|
134
|
+
}
|
|
135
|
+
`),
|
|
136
|
+
devMode: 'esm',
|
|
137
|
+
appDevDependencies: ['@nocobase/dependency'],
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: '@nocobase/dependency',
|
|
141
|
+
packageName: '@nocobase/dependency',
|
|
142
|
+
url: createModuleUrl('export class SharedBase {}; export default class DependencyPlugin {}'),
|
|
143
|
+
devMode: 'esm',
|
|
144
|
+
},
|
|
145
|
+
] as any,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const dependencyModule = window.__nocobase_app_dev_plugins__['@nocobase/dependency/client-v2'] as {
|
|
149
|
+
default?: unknown;
|
|
150
|
+
SharedBase?: unknown;
|
|
151
|
+
};
|
|
152
|
+
const dependentPlugin = plugins[1][1] as (typeof plugins)[number][1] & { SharedBase?: unknown };
|
|
153
|
+
|
|
154
|
+
expect(plugins.map(([name]) => name)).toEqual(['@nocobase/dependency', '@nocobase/dependent']);
|
|
155
|
+
expect(dependencyModule.SharedBase).toBeDefined();
|
|
156
|
+
expect(plugins[0][1]).toBe(dependencyModule.default);
|
|
157
|
+
expect(dependentPlugin.SharedBase).toBe(dependencyModule.SharedBase);
|
|
158
|
+
expect(mockDefine).toHaveBeenCalledWith('@nocobase/dependency/client-v2', expect.any(Function));
|
|
159
|
+
expect(requirejs.requirejs.config).not.toHaveBeenCalled();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should load RequireJS dependencies before ESM dev plugins', async () => {
|
|
163
|
+
class DependencyPlugin extends Plugin {}
|
|
164
|
+
const SharedBase = { source: 'remote' };
|
|
165
|
+
const dependencyModule = {
|
|
166
|
+
SharedBase,
|
|
167
|
+
default: DependencyPlugin,
|
|
168
|
+
};
|
|
169
|
+
const requirejs: any = {
|
|
170
|
+
requirejs: vi.fn((packageNames, resolve) => {
|
|
171
|
+
expect(packageNames).toEqual(['@nocobase/remote-dependency/client-v2']);
|
|
172
|
+
resolve(dependencyModule);
|
|
173
|
+
}),
|
|
174
|
+
};
|
|
175
|
+
requirejs.requirejs.config = vi.fn();
|
|
176
|
+
|
|
177
|
+
window.define = vi.fn();
|
|
178
|
+
|
|
179
|
+
const plugins = await getPlugins({
|
|
180
|
+
requirejs,
|
|
181
|
+
pluginData: [
|
|
182
|
+
{
|
|
183
|
+
name: '@nocobase/dependent',
|
|
184
|
+
packageName: '@nocobase/dependent',
|
|
185
|
+
url: createModuleUrl(`
|
|
186
|
+
const dependency = window.__nocobase_app_dev_plugins__ && window.__nocobase_app_dev_plugins__['@nocobase/remote-dependency/client-v2'];
|
|
187
|
+
export default class DependentPlugin extends dependency.default {
|
|
188
|
+
static SharedBase = dependency.SharedBase;
|
|
189
|
+
}
|
|
190
|
+
`),
|
|
191
|
+
devMode: 'esm',
|
|
192
|
+
appDevDependencies: ['@nocobase/remote-dependency'],
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: '@nocobase/remote-dependency',
|
|
196
|
+
packageName: '@nocobase/remote-dependency',
|
|
197
|
+
url: 'https://dependency.com',
|
|
198
|
+
},
|
|
199
|
+
] as any,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const dependentPlugin = plugins[1][1] as (typeof plugins)[number][1] & { SharedBase?: unknown };
|
|
203
|
+
|
|
204
|
+
expect(plugins.map(([name]) => name)).toEqual(['@nocobase/remote-dependency', '@nocobase/dependent']);
|
|
205
|
+
expect(window.__nocobase_app_dev_plugins__['@nocobase/remote-dependency/client-v2']).toBe(dependencyModule);
|
|
206
|
+
expect(dependentPlugin.SharedBase).toBe(SharedBase);
|
|
207
|
+
});
|
|
208
|
+
|
|
61
209
|
it('should configure remote plugin paths with /client-v2 module ids', () => {
|
|
62
210
|
const requirejs: any = {
|
|
63
211
|
requirejs: {
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import { TinyColor } from '@ctrl/tinycolor';
|
|
11
11
|
import { useEffect } from 'react';
|
|
12
|
-
import { CustomToken, defaultTheme } from '@nocobase/client-v2';
|
|
13
12
|
import { theme } from 'antd';
|
|
13
|
+
import { type CustomToken, defaultTheme } from '../theme';
|
|
14
14
|
|
|
15
15
|
interface Result extends ReturnType<typeof theme.useToken> {
|
|
16
16
|
token: CustomToken;
|
|
@@ -122,12 +122,11 @@ const FilterFormDefaultValuesUI = observer(
|
|
|
122
122
|
rootCollection={getCollectionFromModel(ctx.model)}
|
|
123
123
|
value={value}
|
|
124
124
|
onChange={handleChange}
|
|
125
|
-
fixedMode="default"
|
|
126
|
-
showCondition={false}
|
|
127
125
|
showValueEditorWhenNoField
|
|
128
126
|
getValueInputProps={getValueInputProps}
|
|
129
127
|
isTitleFieldCandidate={isTitleFieldCandidate}
|
|
130
128
|
onSyncAssociationTitleField={onSyncAssociationTitleField}
|
|
129
|
+
enableDateVariableAsConstant
|
|
131
130
|
/>
|
|
132
131
|
);
|
|
133
132
|
},
|