@nocobase/client-v2 2.1.12 → 2.1.14
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/index.mjs +96 -64
- package/lib/index.js +96 -64
- package/package.json +7 -7
- package/src/flow/actions/dateTimeFormat.tsx +2 -2
- package/src/flow/models/blocks/table/TableColumnModel.tsx +6 -2
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +51 -0
- package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +45 -13
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +42 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/client-v2",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.14",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.mjs",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"@formily/antd-v5": "1.2.3",
|
|
28
28
|
"@formily/react": "^2.2.27",
|
|
29
29
|
"@formily/shared": "^2.2.27",
|
|
30
|
-
"@nocobase/evaluators": "2.1.
|
|
31
|
-
"@nocobase/flow-engine": "2.1.
|
|
32
|
-
"@nocobase/sdk": "2.1.
|
|
33
|
-
"@nocobase/shared": "2.1.
|
|
34
|
-
"@nocobase/utils": "2.1.
|
|
30
|
+
"@nocobase/evaluators": "2.1.14",
|
|
31
|
+
"@nocobase/flow-engine": "2.1.14",
|
|
32
|
+
"@nocobase/sdk": "2.1.14",
|
|
33
|
+
"@nocobase/shared": "2.1.14",
|
|
34
|
+
"@nocobase/utils": "2.1.14",
|
|
35
35
|
"ahooks": "^3.7.2",
|
|
36
36
|
"antd": "5.24.2",
|
|
37
37
|
"antd-style": "3.7.1",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"react-i18next": "^11.15.1",
|
|
47
47
|
"react-router-dom": "^6.30.1"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "2a8c3e0e9362aeb49b39c1d02358639b29769f32"
|
|
50
50
|
}
|
|
@@ -28,11 +28,11 @@ const isTableColumnFieldSubModel = (model) => {
|
|
|
28
28
|
|
|
29
29
|
const syncTableColumnDateTimeFormatProps = (ctx, props) => {
|
|
30
30
|
const model = ctx.model;
|
|
31
|
-
if (!isTableColumnFieldSubModel(model)
|
|
31
|
+
if (!isTableColumnFieldSubModel(model)) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
model.parent
|
|
35
|
+
model.parent?.setProps?.(props);
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
export const dateTimeFormat = defineAction({
|
|
@@ -373,14 +373,18 @@ TableColumnModel.registerFlow({
|
|
|
373
373
|
currentProps: ctx.model.props,
|
|
374
374
|
})
|
|
375
375
|
: undefined;
|
|
376
|
+
const collectionFieldComponentProps = collectionField.getComponentProps();
|
|
376
377
|
const componentProps =
|
|
377
378
|
collectionField.isAssociationField() && titleField
|
|
378
379
|
? {
|
|
379
|
-
...
|
|
380
|
+
...collectionFieldComponentProps,
|
|
380
381
|
...targetCollectionField?.getComponentProps?.(),
|
|
381
382
|
...savedDateTimeDisplayProps,
|
|
382
383
|
}
|
|
383
|
-
:
|
|
384
|
+
: {
|
|
385
|
+
...collectionFieldComponentProps,
|
|
386
|
+
...savedDateTimeDisplayProps,
|
|
387
|
+
};
|
|
384
388
|
ctx.model.setProps('title', collectionField.title);
|
|
385
389
|
ctx.model.setProps('dataIndex', collectionField.name);
|
|
386
390
|
// for quick edit
|
|
@@ -327,6 +327,57 @@ describe('TableColumnModel sorter settings', () => {
|
|
|
327
327
|
);
|
|
328
328
|
});
|
|
329
329
|
|
|
330
|
+
it('keeps saved ordinary datetime format when table column initializes again', async () => {
|
|
331
|
+
const engine = new FlowEngine();
|
|
332
|
+
const model = new TableColumnModel({
|
|
333
|
+
uid: 'table-column-saved-datetime-format',
|
|
334
|
+
flowEngine: engine,
|
|
335
|
+
} as any);
|
|
336
|
+
const initStep = model.getFlow('tableColumnSettings')?.steps?.init as any;
|
|
337
|
+
const setProps = vi.fn();
|
|
338
|
+
|
|
339
|
+
await initStep.handler({
|
|
340
|
+
model: {
|
|
341
|
+
context: {
|
|
342
|
+
collectionField: {
|
|
343
|
+
title: 'Datetime',
|
|
344
|
+
name: 'datetime',
|
|
345
|
+
isAssociationField: () => false,
|
|
346
|
+
getComponentProps: () => ({
|
|
347
|
+
dateFormat: 'YYYY-MM-DD',
|
|
348
|
+
showTime: false,
|
|
349
|
+
}),
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
props: {},
|
|
353
|
+
subModels: {
|
|
354
|
+
field: {
|
|
355
|
+
getStepParams: (flowKey, stepKey) =>
|
|
356
|
+
flowKey === 'datetimeSettings' && stepKey === 'dateFormat'
|
|
357
|
+
? {
|
|
358
|
+
picker: 'date',
|
|
359
|
+
dateFormat: 'YYYY-MM-DD',
|
|
360
|
+
showTime: true,
|
|
361
|
+
timeFormat: 'HH:mm:ss',
|
|
362
|
+
}
|
|
363
|
+
: undefined,
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
applySubModelsBeforeRenderFlows: vi.fn(),
|
|
367
|
+
setProps,
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
expect(setProps).toHaveBeenCalledWith(
|
|
372
|
+
expect.objectContaining({
|
|
373
|
+
dateFormat: 'YYYY-MM-DD',
|
|
374
|
+
format: 'YYYY-MM-DD HH:mm:ss',
|
|
375
|
+
showTime: true,
|
|
376
|
+
timeFormat: 'HH:mm:ss',
|
|
377
|
+
}),
|
|
378
|
+
);
|
|
379
|
+
});
|
|
380
|
+
|
|
330
381
|
it('does not update field component setting when title field refresh fails', async () => {
|
|
331
382
|
const engine = new FlowEngine();
|
|
332
383
|
const model = new TableColumnModel({ uid: 'table-column-title-field-component-failed', flowEngine: engine } as any);
|
|
@@ -198,6 +198,48 @@ const useFieldPermissionMessage = (model, allowEdit) => {
|
|
|
198
198
|
return messageValue;
|
|
199
199
|
};
|
|
200
200
|
|
|
201
|
+
const recordSelectClassName = css`
|
|
202
|
+
min-width: 0;
|
|
203
|
+
|
|
204
|
+
.ant-select-selector {
|
|
205
|
+
min-width: 0;
|
|
206
|
+
overflow: hidden;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.ant-select-selection-search,
|
|
210
|
+
.ant-select-selection-item,
|
|
211
|
+
.ant-select-selection-placeholder,
|
|
212
|
+
.ant-select-selection-overflow,
|
|
213
|
+
.ant-select-selection-overflow-item {
|
|
214
|
+
min-width: 0;
|
|
215
|
+
max-width: 100%;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.ant-select-selection-item,
|
|
219
|
+
.ant-select-selection-item-content {
|
|
220
|
+
overflow: hidden;
|
|
221
|
+
text-overflow: ellipsis;
|
|
222
|
+
white-space: nowrap;
|
|
223
|
+
}
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
const recordSelectLabelClassName = css`
|
|
227
|
+
display: block;
|
|
228
|
+
min-width: 0;
|
|
229
|
+
max-width: 100%;
|
|
230
|
+
overflow: hidden;
|
|
231
|
+
text-overflow: ellipsis;
|
|
232
|
+
white-space: nowrap;
|
|
233
|
+
|
|
234
|
+
* {
|
|
235
|
+
min-width: 0;
|
|
236
|
+
max-width: 100%;
|
|
237
|
+
overflow: hidden;
|
|
238
|
+
text-overflow: ellipsis;
|
|
239
|
+
white-space: nowrap !important;
|
|
240
|
+
}
|
|
241
|
+
`;
|
|
242
|
+
|
|
201
243
|
const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
202
244
|
const {
|
|
203
245
|
fieldNames,
|
|
@@ -210,6 +252,7 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
210
252
|
onChange,
|
|
211
253
|
allowCreate = true,
|
|
212
254
|
allowEdit = true,
|
|
255
|
+
className,
|
|
213
256
|
...others
|
|
214
257
|
} = props;
|
|
215
258
|
const model: any = useFlowModel();
|
|
@@ -317,6 +360,7 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
317
360
|
<Select
|
|
318
361
|
style={{ width: '100%' }}
|
|
319
362
|
{...others}
|
|
363
|
+
className={[recordSelectClassName, className].filter(Boolean).join(' ')}
|
|
320
364
|
allowClear
|
|
321
365
|
showSearch
|
|
322
366
|
maxTagCount="responsive"
|
|
@@ -409,19 +453,7 @@ const LazySelect = (props: Readonly<LazySelectProps>) => {
|
|
|
409
453
|
}}
|
|
410
454
|
popupMatchSelectWidth
|
|
411
455
|
labelRender={(data) => {
|
|
412
|
-
return
|
|
413
|
-
<div
|
|
414
|
-
className={css`
|
|
415
|
-
div {
|
|
416
|
-
white-space: nowrap !important;
|
|
417
|
-
overflow: hidden;
|
|
418
|
-
text-overflow: ellipsis;
|
|
419
|
-
}
|
|
420
|
-
`}
|
|
421
|
-
>
|
|
422
|
-
{data.label}
|
|
423
|
-
</div>
|
|
424
|
-
);
|
|
456
|
+
return <div className={recordSelectLabelClassName}>{data.label}</div>;
|
|
425
457
|
}}
|
|
426
458
|
dropdownRender={(menu) => {
|
|
427
459
|
const isFullMatch = realOptions.some((v) => v[normalizedFieldNames.label] === others.searchText);
|
|
@@ -207,6 +207,48 @@ describe('dateTimeFormat', () => {
|
|
|
207
207
|
expect(save).toHaveBeenCalled();
|
|
208
208
|
});
|
|
209
209
|
|
|
210
|
+
it('syncs ordinary table column props when date time format settings are saved', async () => {
|
|
211
|
+
const setProps = vi.fn();
|
|
212
|
+
const save = vi.fn();
|
|
213
|
+
const setParentProps = vi.fn();
|
|
214
|
+
const model = {
|
|
215
|
+
context: {
|
|
216
|
+
collectionField: {
|
|
217
|
+
type: 'datetime',
|
|
218
|
+
interface: 'datetime',
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
setProps,
|
|
222
|
+
save,
|
|
223
|
+
parent: {
|
|
224
|
+
use: 'TableColumnModel',
|
|
225
|
+
setProps: setParentProps,
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
model.parent['subModels'] = {
|
|
229
|
+
field: model,
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
await dateTimeFormat.beforeParamsSave(
|
|
233
|
+
{ model },
|
|
234
|
+
{
|
|
235
|
+
picker: 'date',
|
|
236
|
+
dateFormat: 'YYYY-MM-DD',
|
|
237
|
+
showTime: true,
|
|
238
|
+
timeFormat: 'HH:mm:ss',
|
|
239
|
+
},
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
expect(setParentProps).toHaveBeenCalledWith({
|
|
243
|
+
picker: 'date',
|
|
244
|
+
dateFormat: 'YYYY-MM-DD',
|
|
245
|
+
showTime: true,
|
|
246
|
+
timeFormat: 'HH:mm:ss',
|
|
247
|
+
format: 'YYYY-MM-DD HH:mm:ss',
|
|
248
|
+
});
|
|
249
|
+
expect(save).toHaveBeenCalled();
|
|
250
|
+
});
|
|
251
|
+
|
|
210
252
|
it('hides time format for association title date-only fields', () => {
|
|
211
253
|
const ctx = {
|
|
212
254
|
model: {
|